customers = $customers; $this->contacts = $contacts; $this->notes = $notes; $this->activity = $activity; $this->service = $service; } /** * {@inheritdoc} */ public function register(): void { add_filter( 'wp_privacy_personal_data_exporters', array( $this, 'register_exporter' ) ); add_filter( 'wp_privacy_personal_data_erasers', array( $this, 'register_eraser' ) ); } /** * Adds the exporter. * * @since 0.1.0 * * @param array $exporters Registered exporters. * @return array */ public function register_exporter( $exporters ) { $exporters['hostkhata-customer'] = array( 'exporter_friendly_name' => __( 'HostKhata customer data', 'hostkhata' ), 'callback' => array( $this, 'export' ), ); return $exporters; } /** * Adds the eraser. * * @since 0.1.0 * * @param array $erasers Registered erasers. * @return array */ public function register_eraser( $erasers ) { $erasers['hostkhata-customer'] = array( 'eraser_friendly_name' => __( 'HostKhata customer data', 'hostkhata' ), 'callback' => array( $this, 'erase' ), ); return $erasers; } /** * Exports the data held about the person with the given email address. * * @since 0.1.0 * * @param string $email Email address. * @return array{data: array>, done: bool} */ public function export( $email ): array { $customer = $this->customer_by_email( (string) $email ); if ( null === $customer ) { return array( 'data' => array(), 'done' => true, ); } $id = $customer['id']; $groups = array(); $profile = array( __( 'Name', 'hostkhata' ) => trim( $customer['first_name'] . ' ' . $customer['last_name'] ), __( 'Email', 'hostkhata' ) => $customer['user_email'], __( 'Company', 'hostkhata' ) => $customer['company'], __( 'Phone', 'hostkhata' ) => $customer['phone'], __( 'Address', 'hostkhata' ) => implode( ', ', array_filter( array( $customer['address_1'], $customer['address_2'], $customer['city'], $customer['state'], $customer['postcode'], $customer['country'] ) ) ), __( 'Status', 'hostkhata' ) => $customer['status'], __( 'Tags', 'hostkhata' ) => implode( ', ', $customer['tags'] ), __( 'Customer since', 'hostkhata' ) => $customer['created_at_gmt'] . ' UTC', ); $groups[] = $this->item( 'hostkhata-customer', __( 'Customer profile', 'hostkhata' ), 'customer-' . $id, $profile ); foreach ( $this->contacts->for_customer( $id ) as $contact ) { $groups[] = $this->item( 'hostkhata-contacts', __( 'Customer contacts', 'hostkhata' ), 'contact-' . $contact['id'], array( __( 'Name', 'hostkhata' ) => $contact['name'], __( 'Email', 'hostkhata' ) => $contact['email'], __( 'Phone', 'hostkhata' ) => $contact['phone'], __( 'Role', 'hostkhata' ) => $contact['job_role'], ) ); } foreach ( $this->notes->for_customer( $id, 500 ) as $note ) { $groups[] = $this->item( 'hostkhata-notes', __( 'Notes about the customer', 'hostkhata' ), 'note-' . $note['id'], array( __( 'Note', 'hostkhata' ) => $note['note'], __( 'Added', 'hostkhata' ) => $note['created_at_gmt'] . ' UTC', ) ); } foreach ( $this->activity->for_customer( $id, 500 ) as $entry ) { $groups[] = $this->item( 'hostkhata-activity', __( 'Account activity', 'hostkhata' ), 'activity-' . $entry['id'], array( __( 'Action', 'hostkhata' ) => $entry['action'], __( 'Date', 'hostkhata' ) => $entry['created_at_gmt'] . ' UTC', ) ); } return array( 'data' => $groups, 'done' => true, ); } /** * Erases the data held about the person with the given email address. * * @since 0.1.0 * * @param string $email Email address. * @return array{items_removed: bool, items_retained: bool, messages: string[], done: bool} */ public function erase( $email ): array { $result = array( 'items_removed' => false, 'items_retained' => false, 'messages' => array(), 'done' => true, ); $customer = $this->customer_by_email( (string) $email ); if ( null === $customer || CustomerStatus::ANONYMISED === $customer['status'] ) { return $result; } $counts = $this->customers->related_counts( $customer['id'] ); $outcome = $this->service->anonymise( $customer['id'] ); if ( $outcome instanceof WP_Error ) { $result['items_retained'] = true; $result['messages'][] = $outcome->get_error_message(); return $result; } $result['items_removed'] = true; if ( array_sum( $counts ) > 0 ) { $result['items_retained'] = true; $result['messages'][] = __( 'Orders, invoices and payments are kept for accounting. They no longer contain personal details.', 'hostkhata' ); } return $result; } /** * Finds the customer behind an email address. * * @param string $email Email address. * @return array|null */ private function customer_by_email( string $email ): ?array { $user = get_user_by( 'email', $email ); return $user ? $this->customers->find_by_user_id( (int) $user->ID ) : null; } /** * Builds one export item. * * @param string $group_id Group id. * @param string $group_label Group label. * @param string $item_id Item id. * @param array $values Name and value pairs. * @return array */ private function item( string $group_id, string $group_label, string $item_id, array $values ): array { $data = array(); foreach ( $values as $name => $value ) { if ( '' !== (string) $value ) { $data[] = array( 'name' => $name, 'value' => (string) $value, ); } } return array( 'group_id' => $group_id, 'group_label' => $group_label, 'item_id' => $item_id, 'data' => $data, ); } }