PrivacyErasePersonalData.php 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839
  1. <?php
  2. /**
  3. * Testing Ajax handler for erasing personal data.
  4. *
  5. * @package WordPress\UnitTests
  6. * @since 5.2.0
  7. */
  8. /**
  9. * Tests_Ajax_PrivacyExportPersonalData class.
  10. *
  11. * @since 5.2.0
  12. *
  13. * @group ajax
  14. * @group privacy
  15. *
  16. * @covers ::wp_ajax_wp_privacy_erase_personal_data
  17. */
  18. class Tests_Ajax_PrivacyErasePersonalData extends WP_Ajax_UnitTestCase {
  19. /**
  20. * User Request ID.
  21. *
  22. * @since 5.2.0
  23. *
  24. * @var int $request_id
  25. */
  26. protected static $request_id;
  27. /**
  28. * User Request Email.
  29. *
  30. * @since 5.2.0
  31. *
  32. * @var string $request_email
  33. */
  34. protected static $request_email;
  35. /**
  36. * Ajax Action.
  37. *
  38. * @since 5.2.0
  39. *
  40. * @var string $action
  41. */
  42. protected static $action;
  43. /**
  44. * Eraser Index.
  45. *
  46. * @since 5.2.0
  47. *
  48. * @var int $eraser
  49. */
  50. protected static $eraser;
  51. /**
  52. * Eraser Key.
  53. *
  54. * @since 5.2.0
  55. *
  56. * @var string $eraser_key
  57. */
  58. protected static $eraser_key;
  59. /**
  60. * Eraser Friendly Name.
  61. *
  62. * @since 5.2.0
  63. *
  64. * @var string $eraser_friendly_name
  65. */
  66. protected static $eraser_friendly_name;
  67. /**
  68. * Page Index.
  69. *
  70. * @since 5.2.0
  71. *
  72. * @var int $page
  73. */
  74. protected static $page;
  75. /**
  76. * Last response parsed.
  77. *
  78. * @since 5.2.0
  79. *
  80. * @var array $_last_response_parsed
  81. */
  82. protected $_last_response_parsed;
  83. /**
  84. * An array key in the test eraser to unset.
  85. *
  86. * @since 5.2.0
  87. *
  88. * @var string $key_to_unset
  89. */
  90. protected $key_to_unset;
  91. /**
  92. * A value to change the test eraser callback to.
  93. *
  94. * @since 5.2.0
  95. *
  96. * @var string $new_callback_value
  97. */
  98. protected $new_callback_value;
  99. /**
  100. * Create user erase request fixtures.
  101. *
  102. * @param WP_UnitTest_Factory $factory Factory.
  103. */
  104. public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
  105. self::$request_email = 'requester@example.com';
  106. self::$request_id = wp_create_user_request( self::$request_email, 'remove_personal_data' );
  107. self::$action = 'wp-privacy-erase-personal-data';
  108. self::$eraser = 1;
  109. self::$eraser_key = 'custom-eraser';
  110. self::$eraser_friendly_name = 'Custom Eraser';
  111. self::$page = 1;
  112. }
  113. /**
  114. * Register a custom personal data eraser.
  115. */
  116. public function setUp() {
  117. parent::setUp();
  118. $this->key_to_unset = '';
  119. // Make sure the erasers response is not modified and avoid sending emails.
  120. remove_all_filters( 'wp_privacy_personal_data_erasure_page' );
  121. remove_all_actions( 'wp_privacy_personal_data_erased' );
  122. // Only use our custom privacy personal data eraser.
  123. remove_all_filters( 'wp_privacy_personal_data_erasers' );
  124. add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_custom_personal_data_eraser' ) );
  125. $this->_setRole( 'administrator' );
  126. // `erase_others_personal_data` meta cap in Multisite installation is only granted to those with `manage_network` capability.
  127. if ( is_multisite() ) {
  128. grant_super_admin( get_current_user_id() );
  129. }
  130. }
  131. /**
  132. * Clean up after each test method.
  133. */
  134. public function tearDown() {
  135. remove_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_custom_personal_data_eraser' ) );
  136. $this->new_callback_value = '';
  137. if ( is_multisite() ) {
  138. revoke_super_admin( get_current_user_id() );
  139. }
  140. parent::tearDown();
  141. }
  142. /**
  143. * Helper method for changing the test eraser's callback function.
  144. *
  145. * @param string|array $callback New test eraser callback index value.
  146. */
  147. protected function _set_eraser_callback( $callback ) {
  148. $this->new_callback_value = $callback;
  149. add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'filter_eraser_callback_value' ), 20 );
  150. }
  151. /**
  152. * Change the test eraser callback to a specified value.
  153. *
  154. * @since 5.2.0
  155. *
  156. * @param array $erasers List of data erasers.
  157. *
  158. * @return array Array of data erasers.
  159. */
  160. public function filter_eraser_callback_value( $erasers ) {
  161. $erasers[ self::$eraser_key ]['callback'] = $this->new_callback_value;
  162. return $erasers;
  163. }
  164. /**
  165. * Helper method for unsetting an array index in the test eraser.
  166. *
  167. * @param string|bool $key Test eraser key to unset.
  168. */
  169. protected function _unset_eraser_key( $key ) {
  170. $this->key_to_unset = $key;
  171. add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'filter_unset_eraser_index' ), 20 );
  172. }
  173. /**
  174. * Unsets an array key in the test eraser.
  175. *
  176. * If the key is false, the eraser is set to false.
  177. *
  178. * @since 5.2.0
  179. *
  180. * @param array $erasers Erasers.
  181. *
  182. * @return array Erasers.
  183. */
  184. public function filter_unset_eraser_index( $erasers ) {
  185. if ( false === $this->key_to_unset ) {
  186. $erasers[ self::$eraser_key ] = false;
  187. } elseif ( ! empty( $this->key_to_unset ) ) {
  188. unset( $erasers[ self::$eraser_key ][ $this->key_to_unset ] );
  189. }
  190. return $erasers;
  191. }
  192. /**
  193. * Helper method for erasing a key from the eraser response.
  194. *
  195. * @since 5.2.0
  196. *
  197. * @param array $key Response key to unset.
  198. */
  199. protected function _unset_response_key( $key ) {
  200. $this->key_to_unset = $key;
  201. $this->_set_eraser_callback( array( $this, 'filter_unset_response_index' ) );
  202. }
  203. /**
  204. * Unsets an array index in a response.
  205. *
  206. * @since 5.2.0
  207. *
  208. * @param string $email_address The requester's email address.
  209. * @param int $page Page number.
  210. *
  211. * @return array Export data.
  212. */
  213. public function filter_unset_response_index( $email_address, $page = 1 ) {
  214. $response = $this->callback_personal_data_eraser( $email_address, $page );
  215. if ( ! empty( $this->key_to_unset ) ) {
  216. unset( $response[ $this->key_to_unset ] );
  217. }
  218. return $response;
  219. }
  220. /**
  221. * The function should send an error when the request ID is missing.
  222. *
  223. * @since 5.2.0
  224. *
  225. * @ticket 43438
  226. */
  227. public function test_error_when_missing_request_id() {
  228. $this->assertNotWPError( self::$request_id );
  229. // Set up a request.
  230. $this->_make_ajax_call(
  231. array(
  232. 'id' => null, // Missing request ID.
  233. )
  234. );
  235. $this->assertFalse( $this->_last_response_parsed['success'] );
  236. $this->assertSame( 'Missing request ID.', $this->_last_response_parsed['data'] );
  237. }
  238. /**
  239. * The function should send an error when the request ID is less than 1.
  240. *
  241. * @since 5.2.0
  242. *
  243. * @ticket 43438
  244. */
  245. public function test_error_when_request_id_invalid() {
  246. $this->assertNotWPError( self::$request_id );
  247. // Set up a request.
  248. $this->_make_ajax_call(
  249. array(
  250. 'id' => -1, // Invalid request ID.
  251. )
  252. );
  253. $this->assertFalse( $this->_last_response_parsed['success'] );
  254. $this->assertSame( 'Invalid request ID.', $this->_last_response_parsed['data'] );
  255. }
  256. /**
  257. * The function should send an error when the current user is missing required capabilities.
  258. *
  259. * @since 5.2.0
  260. *
  261. * @ticket 43438
  262. */
  263. public function test_error_when_current_user_missing_required_capabilities() {
  264. $this->_setRole( 'author' );
  265. $this->assertFalse( current_user_can( 'erase_others_personal_data' ) );
  266. $this->assertFalse( current_user_can( 'delete_users' ) );
  267. $this->_make_ajax_call();
  268. $this->assertFalse( $this->_last_response_parsed['success'] );
  269. $this->assertSame( 'Sorry, you are not allowed to perform this action.', $this->_last_response_parsed['data'] );
  270. }
  271. /**
  272. * Test requests do not succeed on multisite when the current user is not a network admin.
  273. *
  274. * @ticket 43438
  275. * @group multisite
  276. * @group ms-required
  277. */
  278. public function test_error_when_current_user_missing_required_capabilities_multisite() {
  279. revoke_super_admin( get_current_user_id() );
  280. $this->_make_ajax_call();
  281. $this->assertFalse( $this->_last_response_parsed['success'] );
  282. $this->assertSame( 'Sorry, you are not allowed to perform this action.', $this->_last_response_parsed['data'] );
  283. }
  284. /**
  285. * The function should send an error when the nonce does not validate.
  286. *
  287. * @since 5.2.0
  288. */
  289. public function test_failure_with_invalid_nonce() {
  290. $this->expectException( 'WPAjaxDieStopException' );
  291. $this->expectExceptionMessage( '-1' );
  292. $this->_make_ajax_call(
  293. array(
  294. 'security' => 'invalid-nonce',
  295. )
  296. );
  297. }
  298. /**
  299. * The function should send an error when the request type is incorrect.
  300. *
  301. * @since 5.2.0
  302. */
  303. public function test_error_when_incorrect_request_type() {
  304. $request_id = wp_create_user_request(
  305. 'export-request@example.com',
  306. 'export_personal_data' // Incorrect request type, expects 'remove_personal_data'.
  307. );
  308. $this->_make_ajax_call(
  309. array(
  310. 'security' => wp_create_nonce( 'wp-privacy-erase-personal-data-' . $request_id ),
  311. 'id' => $request_id,
  312. )
  313. );
  314. $this->assertFalse( $this->_last_response_parsed['success'] );
  315. $this->assertSame( 'Invalid request type.', $this->_last_response_parsed['data'] );
  316. }
  317. /**
  318. * The function should send an error when the request email is invalid.
  319. *
  320. * @since 5.2.0
  321. */
  322. public function test_error_when_invalid_email() {
  323. wp_update_post(
  324. array(
  325. 'ID' => self::$request_id,
  326. 'post_title' => '', // Invalid requester's email address.
  327. )
  328. );
  329. $this->_make_ajax_call();
  330. $this->assertFalse( $this->_last_response_parsed['success'] );
  331. $this->assertSame( 'Invalid email address in request.', $this->_last_response_parsed['data'] );
  332. }
  333. /**
  334. * The function should send an error when the eraser index is missing.
  335. *
  336. * @since 5.2.0
  337. */
  338. public function test_error_when_missing_eraser_index() {
  339. $this->_make_ajax_call(
  340. array(
  341. 'eraser' => null, // Missing eraser index.
  342. )
  343. );
  344. $this->assertFalse( $this->_last_response_parsed['success'] );
  345. $this->assertSame( 'Missing eraser index.', $this->_last_response_parsed['data'] );
  346. }
  347. /**
  348. * The function should send an error when the page index is missing.
  349. *
  350. * @since 5.2.0
  351. */
  352. public function test_error_when_missing_page_index() {
  353. $this->_make_ajax_call(
  354. array(
  355. 'page' => null, // Missing page index.
  356. )
  357. );
  358. $this->assertFalse( $this->_last_response_parsed['success'] );
  359. $this->assertSame( 'Missing page index.', $this->_last_response_parsed['data'] );
  360. }
  361. /**
  362. * The function should send an error when the eraser index is negative.
  363. *
  364. * @since 5.2.0
  365. */
  366. public function test_error_when_negative_eraser_index() {
  367. $this->_make_ajax_call(
  368. array(
  369. 'eraser' => -1, // Negative eraser index.
  370. )
  371. );
  372. $this->assertFalse( $this->_last_response_parsed['success'] );
  373. $this->assertSame( 'Eraser index cannot be less than one.', $this->_last_response_parsed['data'] );
  374. }
  375. /**
  376. * The function should send an error when the eraser index is out of range.
  377. *
  378. * @since 5.2.0
  379. */
  380. public function test_error_when_eraser_index_out_of_range() {
  381. $this->_make_ajax_call(
  382. array(
  383. 'eraser' => PHP_INT_MAX, // Out of range eraser index.
  384. )
  385. );
  386. $this->assertFalse( $this->_last_response_parsed['success'] );
  387. $this->assertSame( 'Eraser index is out of range.', $this->_last_response_parsed['data'] );
  388. }
  389. /**
  390. * The function should send an error when the page index is less than one.
  391. *
  392. * @since 5.2.0
  393. */
  394. public function test_error_when_page_index_less_than_one() {
  395. $this->_make_ajax_call(
  396. array(
  397. 'page' => 0, // Page index less than one.
  398. )
  399. );
  400. $this->assertFalse( $this->_last_response_parsed['success'] );
  401. $this->assertSame( 'Page index cannot be less than one.', $this->_last_response_parsed['data'] );
  402. }
  403. /**
  404. * The function should send an error when an eraser is not an array.
  405. *
  406. * @since 5.2.0
  407. */
  408. public function test_error_when_eraser_not_array() {
  409. $this->_unset_eraser_key( false );
  410. $this->_make_ajax_call();
  411. $this->assertFalse( $this->_last_response_parsed['success'] );
  412. $this->assertSame(
  413. sprintf(
  414. 'Expected an array describing the eraser at index %s.',
  415. self::$eraser
  416. ),
  417. $this->_last_response_parsed['data']
  418. );
  419. }
  420. /**
  421. * The function should send an error when an eraser is missing a friendly name.
  422. *
  423. * @since 5.2.0
  424. */
  425. public function test_error_when_eraser_missing_friendly_name() {
  426. $this->_unset_eraser_key( 'eraser_friendly_name' );
  427. $this->_make_ajax_call();
  428. $this->assertFalse( $this->_last_response_parsed['success'] );
  429. $this->assertSame(
  430. sprintf(
  431. 'Eraser array at index %s does not include a friendly name.',
  432. self::$eraser
  433. ),
  434. $this->_last_response_parsed['data']
  435. );
  436. }
  437. /**
  438. * The function should send an error when an eraser is missing a callback.
  439. *
  440. * @since 5.2.0
  441. */
  442. public function test_error_when_eraser_missing_callback() {
  443. $this->_unset_eraser_key( 'callback' );
  444. $this->_make_ajax_call();
  445. $this->assertFalse( $this->_last_response_parsed['success'] );
  446. $this->assertSame(
  447. sprintf(
  448. 'Eraser does not include a callback: %s.',
  449. self::$eraser_friendly_name
  450. ),
  451. $this->_last_response_parsed['data']
  452. );
  453. }
  454. /**
  455. * The function should send an error when an eraser, at a given index, has an invalid callback.
  456. *
  457. * @since 5.2.0
  458. */
  459. public function test_error_when_eraser_index_invalid_callback() {
  460. $this->_set_eraser_callback( false );
  461. $this->_make_ajax_call();
  462. $this->assertFalse( $this->_last_response_parsed['success'] );
  463. $this->assertSame(
  464. sprintf(
  465. 'Eraser callback is not valid: %s.',
  466. self::$eraser_friendly_name
  467. ),
  468. $this->_last_response_parsed['data']
  469. );
  470. }
  471. /**
  472. * The function should send an error when an eraser, at a given index, is missing an array response.
  473. *
  474. * @since 5.2.0
  475. */
  476. public function test_error_when_eraser_index_invalid_response() {
  477. $this->_set_eraser_callback( '__return_null' );
  478. $this->_make_ajax_call();
  479. $this->assertFalse( $this->_last_response_parsed['success'] );
  480. $this->assertSame(
  481. sprintf(
  482. 'Did not receive array from %1$s eraser (index %2$d).',
  483. self::$eraser_friendly_name,
  484. self::$eraser
  485. ),
  486. $this->_last_response_parsed['data']
  487. );
  488. }
  489. /**
  490. * The function should send an error when missing an items_removed index.
  491. *
  492. * @since 5.2.0
  493. */
  494. public function test_error_when_eraser_items_removed_missing() {
  495. $this->_unset_response_key( 'items_removed' );
  496. $this->_make_ajax_call();
  497. $this->assertFalse( $this->_last_response_parsed['success'] );
  498. $this->assertSame(
  499. sprintf(
  500. 'Expected items_removed key in response array from %1$s eraser (index %2$d).',
  501. self::$eraser_friendly_name,
  502. self::$eraser
  503. ),
  504. $this->_last_response_parsed['data']
  505. );
  506. }
  507. /**
  508. * The function should send an error when missing an items_retained index.
  509. *
  510. * @since 5.2.0
  511. */
  512. public function test_error_when_eraser_items_retained_missing() {
  513. $this->_unset_response_key( 'items_retained' );
  514. $this->_make_ajax_call();
  515. $this->assertFalse( $this->_last_response_parsed['success'] );
  516. $this->assertSame(
  517. sprintf(
  518. 'Expected items_retained key in response array from %1$s eraser (index %2$d).',
  519. self::$eraser_friendly_name,
  520. self::$eraser
  521. ),
  522. $this->_last_response_parsed['data']
  523. );
  524. }
  525. /**
  526. * The function should send an error when missing a messages index.
  527. *
  528. * @since 5.2.0
  529. */
  530. public function test_error_when_eraser_messages_missing() {
  531. $this->_unset_response_key( 'messages' );
  532. $this->_make_ajax_call();
  533. $this->assertFalse( $this->_last_response_parsed['success'] );
  534. $this->assertSame(
  535. sprintf(
  536. 'Expected messages key in response array from %1$s eraser (index %2$d).',
  537. self::$eraser_friendly_name,
  538. self::$eraser
  539. ),
  540. $this->_last_response_parsed['data']
  541. );
  542. }
  543. /**
  544. * The function should send an error when the messages index is not an array.
  545. *
  546. * @since 5.2.0
  547. */
  548. public function test_error_when_eraser_messages_not_array() {
  549. $this->_set_eraser_callback( array( $this, 'filter_response_messages_invalid' ) );
  550. $this->_make_ajax_call();
  551. $this->assertFalse( $this->_last_response_parsed['success'] );
  552. $this->assertSame(
  553. sprintf(
  554. 'Expected messages key to reference an array in response array from %1$s eraser (index %2$d).',
  555. self::$eraser_friendly_name,
  556. self::$eraser
  557. ),
  558. $this->_last_response_parsed['data']
  559. );
  560. }
  561. /**
  562. * Change the messages index to an invalid value (not an array).
  563. *
  564. * @since 5.2.0
  565. *
  566. * @param string $email_address The requester's email address.
  567. * @param int $page Page number.
  568. *
  569. * @return array Export data.
  570. */
  571. public function filter_response_messages_invalid( $email_address, $page = 1 ) {
  572. $response = $this->callback_personal_data_eraser( $email_address, $page );
  573. $response['messages'] = true;
  574. return $response;
  575. }
  576. /**
  577. * The function should send an error when an eraser is missing 'done' in array response.
  578. *
  579. * @since 5.2.0
  580. */
  581. public function test_error_when_eraser_missing_done_response() {
  582. $this->_unset_response_key( 'done' );
  583. $this->_make_ajax_call();
  584. $this->assertFalse( $this->_last_response_parsed['success'] );
  585. $this->assertSame(
  586. sprintf(
  587. 'Expected done flag in response array from %1$s eraser (index %2$d).',
  588. self::$eraser_friendly_name,
  589. self::$eraser
  590. ),
  591. $this->_last_response_parsed['data']
  592. );
  593. }
  594. /**
  595. * The function should successfully send erasers response data when the current user has the required
  596. * capabilities.
  597. *
  598. * @since 5.2.0
  599. *
  600. * @ticket 43438
  601. */
  602. public function test_success_when_current_user_has_required_capabilities() {
  603. $this->assertTrue( current_user_can( 'erase_others_personal_data' ) );
  604. $this->assertTrue( current_user_can( 'delete_users' ) );
  605. $this->_make_ajax_call();
  606. $this->assertSame(
  607. sprintf( 'A message regarding retained data for %s.', self::$request_email ),
  608. $this->_last_response_parsed['data']['messages'][0]
  609. );
  610. $this->assertTrue( $this->_last_response_parsed['success'] );
  611. $this->assertTrue( $this->_last_response_parsed['data']['items_removed'] );
  612. $this->assertTrue( $this->_last_response_parsed['data']['items_retained'] );
  613. $this->assertTrue( $this->_last_response_parsed['data']['done'] );
  614. }
  615. /**
  616. * The function should successfully send erasers response data when no items to erase.
  617. *
  618. * @since 5.2.0
  619. *
  620. * @ticket 43438
  621. */
  622. public function test_success_when_no_items_to_erase() {
  623. $this->_make_ajax_call( array( 'page' => 2 ) );
  624. $this->assertTrue( $this->_last_response_parsed['success'] );
  625. $this->assertFalse( $this->_last_response_parsed['data']['items_removed'] );
  626. $this->assertFalse( $this->_last_response_parsed['data']['items_retained'] );
  627. $this->assertEmpty( $this->_last_response_parsed['data']['messages'] );
  628. $this->assertTrue( $this->_last_response_parsed['data']['done'] );
  629. }
  630. /**
  631. * Test that the function's output should be filterable with the `wp_privacy_personal_data_erasure_page` filter.
  632. *
  633. * @since 5.2.0
  634. */
  635. public function test_output_should_be_filterable() {
  636. add_filter( 'wp_privacy_personal_data_erasure_page', array( $this, 'filter_eraser_data_response' ), 20, 6 );
  637. $this->_make_ajax_call();
  638. $expected_new_index = self::$request_email . '-' . self::$request_id . '-' . self::$eraser_key;
  639. $this->assertTrue( $this->_last_response_parsed['success'] );
  640. $this->assertSame( 'filtered removed', $this->_last_response_parsed['data']['items_removed'] );
  641. $this->assertSame( 'filtered retained', $this->_last_response_parsed['data']['items_retained'] );
  642. $this->assertSame( array( 'filtered messages' ), $this->_last_response_parsed['data']['messages'] );
  643. $this->assertSame( 'filtered done', $this->_last_response_parsed['data']['done'] );
  644. $this->assertSame( $expected_new_index, $this->_last_response_parsed['data']['new_index'] );
  645. }
  646. /**
  647. * Filters the eraser response.
  648. *
  649. * @since 5.2.0
  650. *
  651. * @param array $response The personal data for the given eraser and page.
  652. * @param int $eraser_index The index of the eraser that provided this data.
  653. * @param string $email_address The email address associated with this personal data.
  654. * @param int $page The page for this response.
  655. * @param int $request_id The privacy request post ID associated with this request.
  656. * @param string $eraser_key The key (slug) of the eraser that provided this data.
  657. *
  658. * @return array Filtered erase response.
  659. */
  660. public function filter_eraser_data_response( $response, $eraser_index, $email_address, $page, $request_id, $eraser_key ) {
  661. $response['items_removed'] = 'filtered removed';
  662. $response['items_retained'] = 'filtered retained';
  663. $response['messages'] = array( 'filtered messages' );
  664. $response['done'] = 'filtered done';
  665. $response['new_index'] = $email_address . '-' . $request_id . '-' . $eraser_key;
  666. return $response;
  667. }
  668. /**
  669. * Register handler for a custom personal data eraser.
  670. *
  671. * @since 5.2.0
  672. *
  673. * @param array $erasers An array of personal data erasers.
  674. *
  675. * @return array An array of personal data erasers.
  676. */
  677. public function register_custom_personal_data_eraser( $erasers ) {
  678. $erasers[ self::$eraser_key ] = array(
  679. 'eraser_friendly_name' => self::$eraser_friendly_name,
  680. 'callback' => array( $this, 'callback_personal_data_eraser' ),
  681. );
  682. return $erasers;
  683. }
  684. /**
  685. * Custom Personal Data Eraser.
  686. *
  687. * @since 5.2.0
  688. *
  689. * @param string $email_address The comment author email address.
  690. * @param int $page Page number.
  691. *
  692. * @return array Erase data.
  693. */
  694. public function callback_personal_data_eraser( $email_address, $page = 1 ) {
  695. if ( 1 === $page ) {
  696. return array(
  697. 'items_removed' => true,
  698. 'items_retained' => true,
  699. 'messages' => array( sprintf( 'A message regarding retained data for %s.', $email_address ) ),
  700. 'done' => true,
  701. );
  702. }
  703. return array(
  704. 'items_removed' => false,
  705. 'items_retained' => false,
  706. 'messages' => array(),
  707. 'done' => true,
  708. );
  709. }
  710. /**
  711. * Helper function for Ajax handler.
  712. *
  713. * @since 5.2.0
  714. *
  715. * @param array $args Ajax request arguments.
  716. */
  717. protected function _make_ajax_call( $args = array() ) {
  718. $this->_last_response_parsed = null;
  719. $this->_last_response = '';
  720. $defaults = array(
  721. 'action' => self::$action,
  722. 'security' => wp_create_nonce( self::$action . '-' . self::$request_id ),
  723. 'page' => self::$page,
  724. 'id' => self::$request_id,
  725. 'eraser' => self::$eraser,
  726. );
  727. $_POST = wp_parse_args( $args, $defaults );
  728. try {
  729. $this->_handleAjax( self::$action );
  730. } catch ( WPAjaxDieContinueException $e ) {
  731. unset( $e );
  732. }
  733. if ( $this->_last_response ) {
  734. $this->_last_response_parsed = json_decode( $this->_last_response, true );
  735. }
  736. }
  737. }