<?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    core_cns
 */

/**
 * Hook class.
 */
class Hook_privacy_core_cns extends Hook_privacy_base
{
    /**
     * Find privacy details.
     *
     * @return ?array A map of privacy details in a standardised format (null: disabled)
     */
    public function info() : ?array
    {
        if (get_forum_type() != 'cns') {
            return null;
        }

        return [
            'label' => 'cns:ACCOUNT_FORUMS',

            'description' => 'cns:DESCRIPTION_PRIVACY_ACCOUNT_FORUMS',

            'cookies' => [
            ],

            'positive' => [
                ((get_option('is_on_parental_consent') == '0') || (get_option('dobs') == '0')) ? null : [
                    'heading' => do_lang('CHILD_PROTECTION'),
                    'explanation' => do_lang_tempcode('PRIVACY_EXPLANATION_PARENTAL_CONSENT', escape_html(get_option('parental_consent_age'))),
                ],
                [
                    'heading' => do_lang('COOKIES'),
                    'explanation' => do_lang_tempcode('PRIVACY_EXPLANATION_COOKIES'),
                ],
                [
                    'heading' => do_lang('INFORMATION_DISCLOSURE'),
                    'explanation' => do_lang_tempcode('PRIVACY_EXPLANATION_NON_DISCLOSURE'),
                ],
            ],

            'general' => [
                [
                    'heading' => do_lang('INFORMATION_DISCLOSURE'),
                    'action' => do_lang_tempcode('PRIVACY_ACTION_PROFILE_DISCLOSURE'),
                    'reason' => do_lang_tempcode('PRIVACY_REASON_PROFILE_DISCLOSURE'),
                ],
                [
                    'heading' => do_lang('INFORMATION_DISCLOSURE'),
                    'action' => do_lang_tempcode('PRIVACY_ACTION_PRIVATE_TOPICS'),
                    'reason' => do_lang_tempcode('PRIVACY_REASON_PRIVATE_TOPICS'),
                ],
            ],

            'database_records' => [
                'f_moderator_logs' => [
                    'timestamp_field' => 'l_date_and_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'l_by_member',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_member_known_login_ips' => [
                    'timestamp_field' => 'i_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'i_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => ['i_ip_address'],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => ['i_val_code'],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_group_join_log' => [
                    'timestamp_field' => 'join_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_group_approvals' => [
                    'timestamp_field' => 'ga_date_and_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'ga_member_id',
                    'additional_member_id_fields' => ['ga_status_member_id'],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => ['ga_member_username'],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_invites' => [
                    'timestamp_field' => 'i_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'i_invite_member',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => ['i_email_address'],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_warnings' => [
                    'timestamp_field' => 'w_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'w_member_id',
                    'additional_member_id_fields' => ['w_issuing_member'],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => PRIVACY_METHOD__LEAVE, // Security
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE,
                ],
                'f_warnings_punitive' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'p_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => ['p_ip_address'],
                    'email_fields' => ['p_email_address'],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => PRIVACY_METHOD__LEAVE, // Security
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE,
                ],
                'f_members' => [
                    'timestamp_field' => 'm_join_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => ['m_ip_address'],
                    'email_fields' => ['m_email_address'],
                    'username_fields' => ['m_username'],
                    'file_fields' => ['m_avatar_url', 'm_photo_url'],
                    'additional_anonymise_fields' => ['m_pass_salt', 'm_pass_hash_salted', 'm_password_change_code', 'm_login_key_hash', 'm_validated_email_confirm_code'],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => PRIVACY_METHOD__LEAVE, // Prevent accidental lock-out
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_posts' => [
                    'timestamp_field' => 'p_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'p_posting_member',
                    'additional_member_id_fields' => ['p_whisper_to_member', 'p_last_edit_member'],
                    'ip_address_fields' => ['p_ip_address'],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => ['p_poster_name_if_guest'],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_password_history' => [
                    'timestamp_field' => 'p_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'p_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => ['p_hash_salted', 'p_salt'],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_member_custom_fields' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'mf_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_member_cpf_perms' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_group_members' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'gm_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_groups' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'g_group_lead_member',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_forums' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => null, // f_cache_last_member_id does not own the forum.
                    'additional_member_id_fields' => ['f_cache_last_member_id'],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => ['f_cache_last_username'],
                    'file_fields' => [],
                    'additional_anonymise_fields' => ['f_mail_password', 'f_mail_username'],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE,
                ],
                'f_topics' => [
                    'timestamp_field' => 't_cache_first_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 't_pt_from_member',
                    'additional_member_id_fields' => ['t_pt_to_member', 't_cache_first_member_id', 't_cache_last_member_id'],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => ['t_cache_first_username', 't_cache_last_username'],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_special_pt_access' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 's_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_poll_votes' => [
                    'timestamp_field' => 'pv_date_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'pv_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => ['pv_ip_address'],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_read_logs' => [
                    'timestamp_field' => 'l_time',
                    'retention_days' => addon_installed('cns_forum') ? intval(get_option('post_read_history_days')) : null,
                    'retention_handle_method' => PRIVACY_METHOD__DELETE,
                    'owner_id_field' => 'l_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_group_member_timeouts' => [
                    'timestamp_field' => 'timeout',
                    'retention_days' => intval(get_option('website_activity_store_time')),
                    'retention_handle_method' => PRIVACY_METHOD__DELETE,
                    'owner_id_field' => 'member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_forum_intro_ip' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => null,
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => ['i_ip_address'],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_forum_intro_member' => [
                    'timestamp_field' => null,
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'i_member_id',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
                'f_posts_fulltext_index' => [
                    'timestamp_field' => 'i_add_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'i_posting_member',
                    'additional_member_id_fields' => [],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__ANONYMISE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__ANONYMISE | PRIVACY_METHOD__DELETE,
                ],
                'f_pposts_fulltext_index' => [
                    'timestamp_field' => 'i_add_time',
                    'retention_days' => null,
                    'retention_handle_method' => PRIVACY_METHOD__LEAVE,
                    'owner_id_field' => 'i_posting_member',
                    'additional_member_id_fields' => ['i_for'],
                    'ip_address_fields' => [],
                    'email_fields' => [],
                    'username_fields' => [],
                    'file_fields' => [],
                    'additional_anonymise_fields' => [],
                    'extra_where' => null,
                    'removal_default_handle_method' => PRIVACY_METHOD__DELETE,
                    'removal_default_handle_method_member_override' => null,
                    'allowed_handle_methods' => PRIVACY_METHOD__DELETE,
                ],
            ],
        ];
    }

    /**
     * Serialise a row.
     *
     * @param  ID_TEXT $table_name Table name
     * @param  array $row Row raw from the database
     * @return array Row in a cleanly serialised format
     */
    public function serialise(string $table_name, array $row) : array
    {
        $ret = parent::serialise($table_name, $row);

        switch ($table_name) {
            case 'f_warnings_punitive':
                $hook = get_hook_ob('systems', 'cns_warnings', $row['p_hook'], 'Hook_cns_warnings_');
                if (($hook !== null) && method_exists($hook, 'generate_text') && ($hook->get_details() !== null)) {
                    $ret += [
                        'p_action__dereferenced' => $hook->generate_text($row),
                    ];
                }
                break;

            case 'f_posts':
                $ret += [
                    'p_topic_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_topics', 't_cache_first_title', ['id' => $row['p_topic_id']]),
                    'p_cache_forum_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_forums', 'f_name', ['id' => $row['p_cache_forum_id']]),
                ];
                break;

            case 'f_member_cpf_perms':
                $ret += [
                    'field_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_custom_fields', 'cf_name', ['id' => $row['field_id']]),
                ];
                break;

            case 'f_forums':
                break;

            case 'f_topics':
                $ret += [
                    'f_name__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_forums', 'f_name', ['id' => $row['t_forum_id']]),
                    't_poll_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_polls', 'po_question', ['id' => $row['t_poll_id']]),
                ];
                break;

            case 'f_special_pt_access':
                $ret += [
                    's_topic_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_topics', 't_cache_first_title', ['id' => $row['s_topic_id']]),
                ];
                break;

            case 'f_poll_votes':
                $ret += [
                    'pv_poll_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_polls', 'po_question', ['id' => $row['pv_poll_id']]),
                ];
                break;

            case 'f_read_logs':
                $ret += [
                    'l_topic_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_topics', 't_cache_first_title', ['id' => $row['l_topic_id']]),
                ];
                break;

            case 'f_forum_intro_ip':
                $ret += [
                    'i_forum_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_forums', 'f_name', ['id' => $row['i_forum_id']]),
                ];
                break;

            case 'f_forum_intro_member':
                $ret += [
                    'i_forum_id__dereferenced' => $GLOBALS['FORUM_DB']->query_select_value_if_there('f_forums', 'f_name', ['id' => $row['i_forum_id']]),
                ];
                break;
        }

        return $ret;
    }

    /**
     * Delete a row.
     *
     * @param  ID_TEXT $table_name Table name
     * @param  array $table_details Details of the table from the info function
     * @param  array $row Row raw from the database
     */
    public function delete(string $table_name, array $table_details, array $row)
    {
        require_lang('cns');

        switch ($table_name) {
            case 'f_members':
                require_code('cns_members_action2');
                cns_delete_member($row['id']);
                break;

            case 'f_member_custom_fields':
                // It is possible we want to delete a member's CPFs but not the member itself. We must re-create the row with default values.
                parent::delete($table_name, $table_details, $row);

                require_code('cns_groups');
                require_code('cns_members_action');

                $groups = cns_get_members_groups($row['mf_member_id']);
                $all_fields = list_to_map('id', cns_get_all_custom_fields_match(array_keys($groups)));
                _cns_make_member_cpfs($row['mf_member_id'], [], $all_fields);
                break;

            case 'f_posts':
                require_code('cns_posts_action3');
                $topic_id = $GLOBALS['FORUM_DB']->query_select_value_if_there('f_posts', 'p_topic_id', ['id' => $row['id']]);
                cns_delete_posts_topic($topic_id, [$row['id']], '', false, true, false, false);
                break;

            case 'f_group_members':
                require_code('cns_groups_action2');
                cns_member_leave_secondary_group($row['gm_group_id'], $row['gm_member_id']);
                break;

            case 'f_groups':
                require_code('cns_groups_action2');
                cns_delete_group($row['id']);
                break;

            case 'f_poll_votes':
                if (!addon_installed('cns_forum')) {
                    parent::delete($table_name, $table_details, $row);
                    break;
                }

                require_code('cns_topicview');
                require_code('cns_polls_action2');

                $topic_id = $GLOBALS['FORUM_DB']->query_select_value_if_there('f_topic', 'id', ['t_poll_id' => $row['pv_poll_id']]);
                if ($topic_id === null) {
                    parent::delete($table_name, $table_details, $row);
                    break;
                }
                $topic_info = cns_read_in_topic($topic_id, 0, 0);
                cns_revoke_vote_in_poll($topic_info, $row['pv_member_id']);

                // cns_revoke_vote_in_poll does not actually delete the record, but was necessary to recalculate voting power
                parent::delete($table_name, $table_details, $row);
                break;

            case 'f_topics':
                require_code('cns_topics_action2');
                cns_delete_topic($row['id'], '', null, false);
                break;

            case 'f_group_member_timeouts':
                parent::delete($table_name, $table_details, $row);

                // Must also be removed from the group
                require_code('cns_groups_action2');
                cns_member_leave_secondary_group($row['group_id'], $row['member_id']);
                break;

            default:
                parent::delete($table_name, $table_details, $row);
                break;
        }
    }
}
