Newer
Older
tonitalia-pluginsoci / includes / class-gdpr.php
<?php
/**
 * GDPR export, anonymize, delete.
 *
 * @package TonItaliaRegistration
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class TON_Reg_Gdpr
 */
class TON_Reg_Gdpr {

	/**
	 * @param int $id Registration ID.
	 * @return array<string,mixed>|null
	 */
	public static function export( $id ) {
		$row = TON_Reg_Database::get( $id );
		if ( ! $row ) {
			return null;
		}

		$data = (array) $row;
		if ( $row->user_id ) {
			$user = get_userdata( (int) $row->user_id );
			if ( $user ) {
				$data['wp_user'] = array(
					'ID'           => $user->ID,
					'user_login'   => $user->user_login,
					'user_email'   => $user->user_email,
					'display_name' => $user->display_name,
				);
				$meta = array();
				foreach ( get_user_meta( (int) $row->user_id ) as $key => $values ) {
					if ( 0 === strpos( $key, 'ton_reg_' ) ) {
						$meta[ $key ] = $values[0] ?? '';
					}
				}
				$data['user_meta'] = $meta;
			}
		}

		return $data;
	}

	/**
	 * @param int    $id      Registration ID.
	 * @param string $admin_note Note.
	 * @return bool|WP_Error
	 */
	public static function anonymize( $id, $admin_note = '' ) {
		$row = TON_Reg_Database::get( $id );
		if ( ! $row ) {
			return new WP_Error( 'not_found', __( 'Registrazione non trovata.', 'ton-italia-registration' ) );
		}

		if ( $row->anonymized_at ) {
			return new WP_Error( 'already', __( 'GiĆ  anonimizzata.', 'ton-italia-registration' ) );
		}

		$placeholder = 'ANONIMIZZATO';
		$anon_email  = 'anon-' . $id . '@removed.local';

		TON_Reg_Database::update(
			$id,
			array(
				'cognome'              => $placeholder,
				'nome'                 => $placeholder,
				'luogo_nascita'        => $placeholder,
				'provincia_nascita'    => 'XX',
				'data_nascita'         => null,
				'codice_fiscale'       => str_repeat( 'X', 16 ),
				'comune_residenza'     => $placeholder,
				'provincia_residenza'  => 'XX',
				'indirizzo'            => $placeholder,
				'numero_civico'        => '0',
				'cap'                  => '00000',
				'telefono'             => '0000000000',
				'email'                => $anon_email,
				'luogo_dichiarazione'  => $placeholder,
				'data_dichiarazione'   => null,
				'registration_ip'      => '0.0.0.0',
				'user_agent'           => '',
				'anonymized_at'        => current_time( 'mysql', true ),
				'gdpr_log'             => self::append_log( $row->gdpr_log, 'anonymize', $admin_note ),
			)
		);

		TON_Reg_Documents::delete_all_for_registration( $id, true );

		if ( $row->user_id ) {
			$uid = (int) $row->user_id;
			wp_update_user(
				array(
					'ID'            => $uid,
					'user_email'    => $anon_email,
					'first_name'    => $placeholder,
					'last_name'     => $placeholder,
					'display_name'  => $placeholder,
				)
			);
			$meta_keys = array(
				'ton_reg_cognome',
				'ton_reg_nome',
				'ton_reg_luogo_nascita',
				'ton_reg_codice_fiscale',
				'ton_reg_telefono',
				'ton_reg_indirizzo',
			);
			foreach ( $meta_keys as $key ) {
				update_user_meta( $uid, $key, $placeholder );
			}
		}

		return true;
	}

	/**
	 * @param int    $id   Registration ID.
	 * @param string $note Admin note.
	 * @return bool|WP_Error
	 */
	public static function erase( $id, $note = '' ) {
		$row = TON_Reg_Database::get( $id );
		if ( ! $row ) {
			return new WP_Error( 'not_found', __( 'Registrazione non trovata.', 'ton-italia-registration' ) );
		}

		TON_Reg_Documents::delete_all_for_registration( $id, true );

		if ( $row->user_id ) {
			require_once ABSPATH . 'wp-admin/includes/user.php';
			wp_delete_user( (int) $row->user_id );
		}

		TON_Reg_Database::delete( $id );
		self::log_action( 'erase', $id, $note );

		return true;
	}

	/**
	 * @param string|null $existing Existing log JSON.
	 * @param string      $action   Action.
	 * @param string      $note     Note.
	 * @return string JSON.
	 */
	private static function append_log( $existing, $action, $note ) {
		$log = array();
		if ( $existing ) {
			$decoded = json_decode( $existing, true );
			if ( is_array( $decoded ) ) {
				$log = $decoded;
			}
		}
		$log[] = array(
			'action'    => $action,
			'time'      => current_time( 'mysql', true ),
			'admin'     => get_current_user_id(),
			'note'      => sanitize_text_field( $note ),
		);
		return wp_json_encode( $log );
	}

	/**
	 * @param string $action Action.
	 * @param int    $id     ID.
	 * @param string $note   Note.
	 */
	private static function log_action( $action, $id, $note ) {
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			error_log( sprintf( 'TON Reg GDPR %s #%d: %s', $action, $id, $note ) );
		}
	}
}