| | 4338 | $email_address = sanitize_text_field( $_POST['email'] ); |
| | 4339 | $processor_index = (int) $_POST['exporter']; |
| | 4340 | $page = (int) $_POST['page']; |
| | 4341 | |
| | 4342 | wp_privacy_do_personal_data_callback( 'export', $processor_index, $email_address, $page ); |
| | 4343 | } |
| | 4344 | |
| | 4345 | /** |
| | 4346 | * Ajax handler for erasing a page of personal data. |
| | 4347 | * |
| | 4348 | * @since 4.9.5 |
| | 4349 | */ |
| | 4350 | function wp_ajax_wp_privacy_erase_personal_data() { |
| | 4351 | check_ajax_referer( 'wp-privacy-erase-personal-data', 'security' ); |
| | 4352 | |
| | 4353 | $email_address = sanitize_text_field( $_POST['email'] ); |
| | 4354 | $processor_index = (int) $_POST['eraser']; |
| | 4355 | $page = (int) $_POST['page']; |
| | 4356 | |
| | 4357 | wp_privacy_do_personal_data_callback( 'erase', $processor_index, $email_address, $page ); |
| | 4358 | } |
| | 4359 | |
| | 4360 | /** |
| | 4361 | * Handler for exporting or erasing a page of personal data. |
| | 4362 | * |
| | 4363 | * @since 4.9.5 |
| | 4364 | * |
| | 4365 | * @param string $type The type of processing requested: "export" or "erase" |
| | 4366 | * @param int $processor_index The index of the processor that should be called. |
| | 4367 | * @param string $email_address The email address for which processing is being performed. |
| | 4368 | * @param int $page The 1-based page of data to be processed. |
| | 4369 | */ |
| | 4370 | |
| | 4371 | function wp_privacy_do_personal_data_callback( $type, $processor_index, $email_address, $page ) { |
| 4341 | | /** |
| 4342 | | * Filters the array of exporter callbacks. |
| 4343 | | * |
| 4344 | | * @since 4.9.5. |
| 4345 | | * |
| 4346 | | * @param array $args { |
| 4347 | | * An array of callable exporters of personal data. Default empty array. |
| 4348 | | * [ |
| 4349 | | * callback string Callable exporter that accepts an email address and |
| 4350 | | * a page and returns an array of name => value |
| 4351 | | * pairs of personal data |
| 4352 | | * exporter_friendly_name string Translated user facing friendly name for the exporter |
| 4353 | | * ] |
| 4354 | | * } |
| 4355 | | */ |
| 4356 | | $exporters = apply_filters( 'wp_privacy_personal_data_exporters', array() ); |
| | 4378 | if ( ! in_array( $type, $allowed_types ) ) { |
| | 4379 | wp_send_json_error( 'invalid processor type' ); |
| | 4380 | } |
| 4358 | | if ( ! is_array( $exporters ) ) { |
| 4359 | | wp_send_json_error( 'An exporter has improperly used the registration filter.' ); |
| | 4382 | $processors = array(); |
| | 4383 | if ( 'export' === $type ) { |
| | 4384 | /** |
| | 4385 | * Filters the array of exporter callbacks. |
| | 4386 | * |
| | 4387 | * @since 4.9.5. |
| | 4388 | * |
| | 4389 | * @param array $args { |
| | 4390 | * An array of callable exporters of personal data. Default empty array. |
| | 4391 | * [ |
| | 4392 | * callback string Callable exporter that accepts an email address and |
| | 4393 | * a page and returns an array of personal data |
| | 4394 | * exporter_friendly_name string Translated user facing friendly name for the exporter |
| | 4395 | * ] |
| | 4396 | * } |
| | 4397 | */ |
| | 4398 | $processors = apply_filters( 'wp_privacy_personal_data_exporters', $processors ); |
| | 4399 | } else if ( 'erase' === $type ) { |
| | 4400 | /** |
| | 4401 | * Filters the array of eraser callbacks. |
| | 4402 | * |
| | 4403 | * @since 4.9.5. |
| | 4404 | * |
| | 4405 | * @param array $args { |
| | 4406 | * An array of callable erasers of personal data. Default empty array. |
| | 4407 | * [ |
| | 4408 | * callback string Callable eraser that accepts an email address and page |
| | 4409 | * eraser_friendly_name string Translated user facing friendly name for the eraser |
| | 4410 | * ] |
| | 4411 | * } |
| | 4412 | */ |
| | 4413 | $processors = apply_filters( 'wp_privacy_personal_data_erasers', $processors ); |
| 4385 | | $exporter = $exporters[ $index ]; |
| 4386 | | if ( ! is_array( $exporter ) ) { |
| 4387 | | wp_send_json_error( "Expected an array describing the exporter at index {$exporter_index}." ); |
| 4388 | | } |
| 4389 | | if ( ! array_key_exists( 'callback', $exporter ) ) { |
| 4390 | | wp_send_json_error( "Exporter array at index {$exporter_index} does not include a callback." ); |
| 4391 | | } |
| 4392 | | if ( ! is_callable( $exporter['callback'] ) ) { |
| 4393 | | wp_send_json_error( "Exporter callback at index {$exporter_index} is not a valid callback." ); |
| 4394 | | } |
| 4395 | | if ( ! array_key_exists( 'exporter_friendly_name', $exporter ) ) { |
| 4396 | | wp_send_json_error( "Exporter array at index {$exporter_index} does not include a friendly name." ); |
| 4397 | | } |
| | 4446 | if ( ! is_email( $email_address ) ) { |
| | 4447 | wp_send_json_error( 'A valid email address must be given.' ); |
| | 4448 | } |
| 4399 | | $callback = $exporters[ $index ]['callback']; |
| 4400 | | $exporter_friendly_name = $exporters[ $index ]['exporter_friendly_name']; |
| | 4450 | $processor = $processors[ $processor_index - 1 ]; |
| | 4451 | if ( ! is_array( $processor ) ) { |
| | 4452 | wp_send_json_error( "Expected an array describing the processor at index {$processor_index}." ); |
| | 4453 | } |
| | 4454 | if ( ! array_key_exists( 'callback', $processor ) ) { |
| | 4455 | wp_send_json_error( "Processor array at index {$processor_index} does not include a callback." ); |
| | 4456 | } |
| | 4457 | if ( ! is_callable( $processor['callback'] ) ) { |
| | 4458 | wp_send_json_error( "Processor callback at index {$processor_index} is not a valid callback." ); |
| | 4459 | } |
| 4407 | | if ( ! is_array( $response ) ) { |
| 4408 | | wp_send_json_error( "Expected response as an array from exporter: {$exporter_friendly_name}." ); |
| | 4466 | if ( 'export' === $type ) { |
| | 4467 | $processor_friendly_name = __( 'Unnamed exporter' ); |
| | 4468 | } else if ( 'erase' === $type ) { |
| | 4469 | $processor_friendly_name = __( 'Unnamed eraser' ); |
| | 4470 | } |
| | 4471 | |
| | 4472 | if ( array_key_exists( 'friendly_name', $processor ) ) { |
| | 4473 | if ( ! empty( $processor['friendly_name'] ) ) { |
| | 4474 | $processor_friendly_name = $processor['friendly_name']; |
| 4410 | | if ( ! array_key_exists( 'data', $response ) ) { |
| 4411 | | wp_send_json_error( "Expected data in response array from exporter: {$exporter_friendly_name}." ); |
| 4412 | | } |
| 4413 | | if ( ! is_array( $response['data'] ) ) { |
| 4414 | | wp_send_json_error( "Expected data array in response array from exporter: {$exporter_friendly_name}." ); |
| 4415 | | } |
| 4416 | | if ( ! array_key_exists( 'done', $response ) ) { |
| 4417 | | wp_send_json_error( "Expected done (boolean) in response array from exporter: {$exporter_friendly_name}." ); |
| 4418 | | } |
| 4419 | | } else { |
| 4420 | | // No exporters, so we're done |
| 4421 | | $response = array( |
| 4422 | | 'data' => array(), |
| 4423 | | 'done' => true, |
| 4424 | | ); |
| 4427 | | /** |
| 4428 | | * Filters a page of personal data exporter data. Used to build the export report. |
| 4429 | | * |
| 4430 | | * Allows the export response to be consumed by destinations in addition to Ajax. |
| 4431 | | * |
| 4432 | | * @since 4.9.5 |
| 4433 | | * |
| 4434 | | * @param array $response The personal data for the given exporter and page. |
| 4435 | | * @param int $exporter_index The index of the exporter that provided this data. |
| 4436 | | * @param string $email_address The email address associated with this personal data. |
| 4437 | | * @param int $page The zero-based page for this response. |
| 4438 | | */ |
| 4439 | | $response = apply_filters( 'wp_privacy_personal_data_export_page', $response, $exporter_index, $email_address, $page ); |
| | 4478 | if ( ! is_array( $response ) ) { |
| | 4479 | wp_send_json_error( "Expected response as an array from {$processor_friendly_name}." ); |
| | 4480 | } |
| | 4481 | if ( ! array_key_exists( 'data', $response ) ) { |
| | 4482 | wp_send_json_error( "Expected data in response array from {$processor_friendly_name}." ); |
| | 4483 | } |
| | 4484 | if ( ! is_array( $response['data'] ) ) { |
| | 4485 | wp_send_json_error( "Expected data array in response array from {$processor_friendly_name}." ); |
| | 4486 | } |
| | 4487 | if ( ! array_key_exists( 'done', $response ) ) { |
| | 4488 | wp_send_json_error( "Expected done (boolean) in response array from {$processor_friendly_name}." ); |
| | 4489 | } |
| | 4490 | |
| | 4491 | // If we're doing an export, run the export filter (for things like export file assembly) |
| | 4492 | if ( 'export' === $type ) { |
| | 4493 | /** |
| | 4494 | * Filters a page of personal data exporter data. Used to build the export report. |
| | 4495 | * |
| | 4496 | * Allows the export response to be consumed by destinations in addition to Ajax. |
| | 4497 | * |
| | 4498 | * @since 4.9.5 |
| | 4499 | * |
| | 4500 | * @param array $response The personal data for the given exporter and page. |
| | 4501 | * @param int $processor_index The index of the exporter that provided this data. |
| | 4502 | * @param string $email_address The email address associated with this personal data. |
| | 4503 | * @param int $page The 1-based page for this response. |
| | 4504 | */ |
| | 4505 | $response = apply_filters( 'wp_privacy_personal_data_export_page', $response, $processor_index, $email_address, $page ); |
| | 4506 | } |
| | 4507 | |
| | 4508 | // And lastly, send our response |