__( 'AI House visitor details', 'aihouse' ), 'callback' => array( __CLASS__, 'export' ), ); return $exporters; } /** * Registers the eraser. * * @param array $erasers Existing erasers. * @return array */ public static function register_eraser( $erasers ) { $erasers[ self::KEY ] = array( 'eraser_friendly_name' => __( 'AI House visitor details', 'aihouse' ), 'callback' => array( __CLASS__, 'erase' ), ); return $erasers; } /** * What this plugin holds about one person, as the export screen wants it. * * @param string $email_address The address the request came from. * @param int $page Page number (1-based); this plugin answers everything on page 1, which is * what `done => true` below tells WordPress. The parameter is part of the * callback signature WordPress calls, so it stays even though it is unused. * @return array */ public static function export( $email_address, $page = 1 ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- WordPress' exporter signature. $email = MYBOT_Contacts::clean_email( $email_address ); $phone = MYBOT_Contacts::clean_phone( $email_address ); $items = array(); foreach ( MYBOT_Contacts::matching( $email, $phone ) as $card ) { $items[] = array( 'group_id' => 'mybot-contacts', 'group_label' => __( 'Details you left in the chat', 'aihouse' ), 'item_id' => 'mybot-contact-' . (int) $card['id'], 'data' => self::data_of( $card, 'contact' ), ); } foreach ( self::requests_of( $email, $phone ) as $request ) { $items[] = array( 'group_id' => 'mybot-requests', 'group_label' => __( 'Questions you left for our team', 'aihouse' ), 'item_id' => 'mybot-request-' . (int) $request['id'], 'data' => self::data_of( $request, 'request' ), ); } return array( 'data' => $items, 'done' => true, ); } /** * Deletes everything this plugin holds about one person. * * @param string $email_address The address the request came from. * @param int $page Page number (1-based); everything is erased in one pass, which is what * `done => true` tells WordPress. Part of the callback signature. * @return array */ public static function erase( $email_address, $page = 1 ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed -- WordPress' eraser signature. $email = MYBOT_Contacts::clean_email( $email_address ); $phone = MYBOT_Contacts::clean_phone( $email_address ); $removed = MYBOT_Contacts::erase( $email, $phone ); $items = false; foreach ( self::requests_of( $email, $phone ) as $request ) { if ( self::delete_request( (int) $request['id'] ) ) { ++$removed; $items = true; } } if ( $removed > 0 ) { $items = true; } return array( 'items_removed' => $items, 'items_retained' => false, 'messages' => array(), 'done' => true, ); } /** * Requests left by one person. * * Looked up by email or by phone, the same two things a person knows about themselves. * * @param string $email Email address. * @param string $phone Phone number. * @return array */ protected static function requests_of( $email, $phone ) { if ( ! class_exists( 'MYBOT_Requests' ) || ! MYBOT_Requests::table_exists() ) { return array(); } global $wpdb; $table = MYBOT_Requests::table(); $rows = array(); foreach ( array( 'email' => $email, 'phone' => $phone, ) as $column => $value ) { if ( '' === (string) $value ) { continue; } $sql = ( 'email' === $column ) ? 'SELECT * FROM %i WHERE email = %s' : 'SELECT * FROM %i WHERE phone = %s'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.NotPrepared $found = $wpdb->get_results( $wpdb->prepare( $sql, $table, $value ), ARRAY_A ); foreach ( (array) $found as $row ) { $rows[ (int) $row['id'] ] = $row; } } return array_values( $rows ); } /** * Deletes one request row. * * @param int $id Request id. * @return bool */ protected static function delete_request( $id ) { global $wpdb; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $deleted = $wpdb->delete( MYBOT_Requests::table(), array( 'id' => absint( $id ) ), array( '%d' ) ); return false !== $deleted && $deleted > 0; } /** * One row, as export items. * * @param array $row Database row. * @param string $kind 'contact' or 'request'. * @return array */ protected static function data_of( $row, $kind ) { $data = array(); $fields = array( 'name' => __( 'Name', 'aihouse' ), 'email' => __( 'Email address', 'aihouse' ), 'phone' => __( 'Phone number', 'aihouse' ), 'note' => __( 'Note', 'aihouse' ), 'lang' => __( 'Language', 'aihouse' ), 'created_at' => __( 'Date', 'aihouse' ), ); if ( 'request' === $kind ) { $fields = array_merge( array( 'question' => __( 'Your question', 'aihouse' ), 'answer' => __( 'What the bot answered', 'aihouse' ), ), $fields ); } if ( 'contact' === $kind ) { $fields['consent_text'] = __( 'What you agreed to', 'aihouse' ); $fields['consent_at'] = __( 'When you agreed', 'aihouse' ); } foreach ( $fields as $column => $label ) { $value = isset( $row[ $column ] ) ? (string) $row[ $column ] : ''; if ( '' === $value ) { continue; } $data[] = array( 'name' => $label, 'value' => $value, ); } return $data; } }