<?php /*

 Composr
 Copyright (c) Christopher Graham, 2004-2024

 See docs/LICENSE.md for full licensing information.


 NOTE TO PROGRAMMERS:
   Do not edit this file. If you need to make changes, save your changed file to the appropriate *_custom folder
   **** If you ignore this advice, then your website upgrades (e.g. for bug fixes) will likely kill your changes ****

*/

/**
 * @license    http://opensource.org/licenses/cpal_1.0 Common Public Attribution License
 * @copyright  Christopher Graham
 * @package    ecommerce
 */

/**
 * Hook class.
 */
class Hook_cron_credit_card_cleanup
{
    protected $threshold;
    protected $card_number_field_id;

    /**
     * Get info from this hook.
     *
     * @param  ?TIME $last_run Last time run (null: never)
     * @param  ?boolean $calculate_num_queued Calculate the number of items queued, if possible (null: the hook may decide / low priority)
     * @return ?array Return a map of info about the hook (null: disabled)
     */
    public function info(?int $last_run, ?bool $calculate_num_queued) : ?array
    {
        if (!addon_installed('ecommerce')) {
            return null;
        }

        if (get_forum_type() != 'cns') {
            return null;
        }

        $credit_card_cleanup_days = get_option('credit_card_cleanup_days');
        if ($credit_card_cleanup_days === null) {
            return null;
        }

        require_code('cns_members');
        $this->card_number_field_id = find_cms_cpf_field_id('cms_payment_card_number');
        if ($this->card_number_field_id === null) {
            return null;
        }

        // Calculate on low priority
        if ($calculate_num_queued === null) {
            $calculate_num_queued = true;
        }

        if ($calculate_num_queued) {
            $this->threshold = time() - 60 * 60 * 24 * intval($credit_card_cleanup_days);

            $where = 'm_last_visit_time<' . strval($this->threshold) . ' AND ' . db_string_not_equal_to('field_' . strval($this->card_number_field_id), '');
            $num_queued = $GLOBALS['FORUM_DB']->query_value_if_there(
                'SELECT COUNT(*) FROM ' .
                $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_members m JOIN ' . $GLOBALS['FORUM_DB']->get_table_prefix() . 'f_member_custom_fields f ON f.mf_member_id=m.id ' .
                'WHERE ' . $where
            );
        } else {
            $num_queued = null;
        }

        return [
            'label' => 'Credit card number scrubbing',
            'num_queued' => $num_queued,
            'minutes_between_runs' => 60 * 24,
            'enabled_by_default' => true,
        ];
    }

    /**
     * Run function for system scheduler hooks. Searches for things to do. ->info(..., true) must be called before this method.
     *
     * @param  ?TIME $last_run Last time run (null: never)
     */
    public function run(?int $last_run)
    {
        if (!isset($this->threshold)) { // Nothing to do
            return;
        }

        require_code('cns_members');
        require_code('cns_members_action2');

        $protected_field_changes = [];
        $protected_field_names = ['payment_cardholder_name', 'payment_card_type', 'payment_card_number', 'payment_card_start_date', 'payment_card_expiry_date', 'billing_street_address', 'billing_city', 'billing_post_code', 'billing_country', 'billing_mobile_phone_number', 'billing_county', 'billing_state'];
        foreach ($protected_field_names as $cpf) {
            $field_id = find_cms_cpf_field_id('cms_' . $cpf);
            if ($field_id !== null) {
                $protected_field_changes[$field_id] = (($cpf == 'payment_card_number') ? null : '');
            }
        }

        $start = 0;
        $max = 100;
        do {
            $rows = $GLOBALS['FORUM_DB']->query_select('f_members', ['id'], [], ' AND m_last_visit_time<' . strval($this->threshold), $max, $start);

            foreach ($rows as $row) {
                foreach ($protected_field_changes as $key => $value) {
                    $map = [];
                    $change_map = cns_set_custom_field($row['id'], $key, $value, null, true);
                    if ($change_map !== null) {
                        $map += $change_map;
                    }
                }

                if (count($map) > 0) {
                    $GLOBALS['FORUM_DB']->query_update('f_member_custom_fields', $map, ['mf_member_id' => $row['id']], '', 1);
                }
            }

            $start += $max;
        } while (count($rows) > 0);
    }
}
