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

/**
 * Hook class.
 */
class Hook_content_meta_aware_catalogue_entry extends Hook_CMA
{
    /**
     * Get content type details.
     *
     * @param  ?ID_TEXT $zone The zone to link through to (null: autodetect)
     * @param  boolean $get_extended_data Populate additional data that is somewhat costly to compute (add_url, archive_url)
     * @param  ?ID_TEXT $catalogue_name Catalogue name for entry (null: unknown / N/A)
     * @return ?array Map of content-type info (null: disabled)
     */
    public function info(?string $zone = null, bool $get_extended_data = false, ?string $catalogue_name = null) : ?array
    {
        if (!addon_installed('catalogues')) {
            return null;
        }

        return [
            'support_custom_fields' => false,

            'content_type_label' => 'catalogues:CATALOGUE_ENTRY',
            'content_type_universal_label' => 'Catalogue entry',
            'content_type_label_override' => 'CALL: generate_catalogue_entry_content_type_label',
            'content_type_universal_label_override' => 'CALL: generate_catalogue_entry_content_type_universal_label',

            'db' => $GLOBALS['SITE_DB'],
            'extra_where_sql' => 'r.c_name NOT LIKE \'' . db_encode_like('\_%') . '\'',
            'table' => 'catalogue_entries',
            'id_field' => 'id',
            'id_field_numeric' => true,
            'parent_category_field' => 'cc_id',
            'parent_category_meta_aware_type' => 'catalogue_category',
            'is_category' => false,
            'is_entry' => true,
            'category_field' => (get_value('disable_cat_cat_perms') === '1') ? 'c_name' : ['c_name', 'cc_id'], // For category permissions
            'permission_module' => (get_value('disable_cat_cat_perms') === '1') ? 'catalogues_catalogue' : ['catalogues_catalogue', 'catalogues_category'], // For category permissions
            'parent_spec__table_name' => 'catalogue_categories',
            'parent_spec__parent_name' => 'cc_parent_id',
            'parent_spec__field_name' => 'id',
            'category_is_string' => (get_value('disable_cat_cat_perms') === '1') ? true : [true, false],

            'title_field' => ['id', 'c_name', 'CALL: generate_catalogue_entry_title'],
            'title_field_dereference' => false,
            'title_field_post' => 'field_0',
            'description_field' => null,
            'description_field_dereference' => null,
            'description_field_supports_comcode' => null,
            'image_field' => ['id', 'c_name', 'CALL: generate_catalogue_entry_image_url'],
            'image_field_is_theme_image' => false,
            'alternate_icon_theme_image' => null,

            'view_page_link_pattern' => '_SEARCH:catalogues:entry:_WILD',
            'edit_page_link_pattern' => '_SEARCH:cms_catalogues:_edit:_WILD',
            'view_category_page_link_pattern' => '_SEARCH:catalogues:category:_WILD',
            'add_url' => ($get_extended_data && has_submit_permission('mid', get_member(), get_ip_address(), 'cms_catalogues')) ? (get_module_zone('cms_catalogues') . ':cms_catalogues:add_entry' . (($catalogue_name === null) ? '' : (':catalogue_name=' . $catalogue_name))) : null,
            'archive_url' => $get_extended_data ? ((($zone !== null) ? $zone : get_module_zone('catalogues')) . ':catalogues') : null,

            'support_url_monikers' => true,

            'views_field' => 'ce_views',
            'order_field' => null,
            'submitter_field' => 'ce_submitter',
            'author_field' => null,
            'add_time_field' => 'ce_add_date',
            'edit_time_field' => 'ce_edit_date',
            'date_field' => 'ce_add_date',
            'validated_field' => 'ce_validated',
            'additional_sort_fields' => null,

            'seo_type_code' => 'catalogue_entry',

            'feedback_type_code' => 'catalogue_entry',

            'search_hook' => 'catalogue_entries',
            'rss_hook' => 'catalogues',
            'attachment_hook' => 'catalogue_entry',
            'notification_hook' => 'catalogue_entry',
            'sitemap_hook' => 'catalogue_entry',

            'addon_name' => 'catalogues',

            'cms_page' => 'cms_catalogues',
            'module' => 'catalogues',

            'filtercode' => 'catalogues::_catalogues_filtercode',
            'filtercode_protected_fields' => [], // These are ones even some staff should never know

            'commandr_filesystem_hook' => 'catalogues',
            'commandr_filesystem__is_folder' => false,

            'support_revisions' => false,

            'support_privacy' => true,

            'support_content_reviews' => true,

            'support_spam_heuristics' => null,

            'actionlog_regexp' => '\w+_CATALOGUE_ENTRY',

            'default_prominence_weight' => PROMINENCE_WEIGHT_NONE,
            'default_prominence_flags' => 0,
        ];
    }

    /**
     * Get headings of special relevant data this content type supports.
     *
     * @return array A map of heading codenames to Tempcode labels
     */
    public function get_special_keymap_headings() : array
    {
        $headings = [];

        // TODO: Implement special keymap headings

        return $headings;
    }

    /**
     * Get special relevant data this content type supports.
     *
     * @param  array $row Database row
     * @return array A map of heading codenames to Tempcode values
     */
    public function get_special_keymap(array $row) : array
    {
        $keymap = [];

        /*TODO: Implement special keymap headings
        require_code('catalogues');
        return render_catalogue_category_entry_buildup(null, $c_names[0], null, 'CATEGORY', '', null, 0, null, null, C_DT_TABULAR, false, $rows);
        */

        return $keymap;
    }

    /**
     * Render a content box for a content row.
     *
     * @param  array $row The database row for the content
     * @param  ID_TEXT $zone The zone to display in
     * @param  boolean $give_context Whether to include context (i.e. say WHAT this is, not just show the actual content)
     * @param  boolean $include_breadcrumbs Whether to include breadcrumbs (if there are any)
     * @param  ?ID_TEXT $root Virtual root to use (null: none)
     * @param  boolean $attach_to_url_filter Whether to copy through any filter parameters in the URL, under the basis that they are associated with what this box is browsing
     * @param  ID_TEXT $guid Overridden GUID to send to templates (blank: none)
     * @return Tempcode Results
     */
    public function render_box(array $row, string $zone, bool $give_context = true, bool $include_breadcrumbs = true, ?string $root = null, bool $attach_to_url_filter = false, string $guid = '') : object
    {
        require_code('catalogues');

        return render_catalogue_entry_box($row, $zone, $give_context, $include_breadcrumbs, ($root === null) ? null : intval($root), $guid);
    }

    /**
     * Get the hook name of an AJAX tree selection list.
     *
     * @return ?string Hook name (null: none)
     */
    public function create_selection_tree_list() : ?string
    {
        return 'choose_catalogue_entry';
    }
}

/**
 * Find an entry title.
 *
 * @param  array $row Database row of entry
 * @param  integer $render_type A FIELD_RENDER_* constant
 * @param  boolean $resource_fs_style Whether to use the content API as resource-fs requires (may be slightly different)
 * @return ?mixed Content title (string or Tempcode, depending on $render_type) (null: could not generate)
 */
function generate_catalogue_entry_title(array $row, int $render_type = 1, bool $resource_fs_style = false)
{
    if (!addon_installed('catalogues')) {
        return null;
    }

    $catalogue_name = $row['c_name'];
    $fields = null;

    $unique_key_num = 0;
    if ($resource_fs_style) {
        $fields = $GLOBALS['SITE_DB']->query_select('catalogue_fields', ['*'], ['c_name' => $catalogue_name], 'ORDER BY cf_order,' . $GLOBALS['SITE_DB']->translate_field_ref('cf_name'));
        foreach ($fields as $i => $f) {
            if ($f['cf_type'] == 'codename') {
                $unique_key_num = $i;
                break;
            }
        }
    }

    require_code('catalogues');

    $field_values = get_catalogue_entry_field_values($catalogue_name, $row['id'], [$unique_key_num], $fields);
    if (!isset($field_values[$unique_key_num])) {
        return null;
    }
    $field = $field_values[$unique_key_num];

    $val = $field['cf_default'];
    $val_is_escaped = false;
    if (array_key_exists('effective_value_pure', $field)) {
        $val = $field['effective_value_pure'];
    } elseif (array_key_exists('effective_value', $field)) {
        $val = $field['effective_value'];
    }

    if (array_key_exists('effective_value', $field)) { // Implies Comcode was involved
        $val_is_escaped = true;
    }

    switch ($render_type) {
        case FIELD_RENDER_COMCODE:
            if ($val_is_escaped) {
                return $val;
            }
            return comcode_escape($val);

        case FIELD_RENDER_HTML:
            if (is_object($val)) {
                return $val;
            }
            return make_string_tempcode(escape_html($val));
    }

    // FIELD_RENDER_PLAIN:
    if (is_object($val)) {
        return strip_html($val->evaluate());
    }
    return $val;
}

/**
 * Find an entry image.
 *
 * @param  array $row Database row of entry
 * @return URLPATH The image URL (blank: none)
 */
function generate_catalogue_entry_image_url(array $row) : string
{
    if (!addon_installed('catalogues')) {
        return '';
    }

    require_code('catalogues');

    $unique_key_num = null;
    $field_type = null;

    $catalogue_name = $row['c_name'];

    global $CAT_FIELDS_CACHE;
    if (array_key_exists($catalogue_name, $CAT_FIELDS_CACHE)) {
        $fields = $CAT_FIELDS_CACHE[$catalogue_name];
    } else {
        $fields = $GLOBALS['SITE_DB']->query_select('catalogue_fields', ['*'], ['c_name' => $catalogue_name], 'ORDER BY cf_order,' . $GLOBALS['SITE_DB']->translate_field_ref('cf_name'));
        $CAT_FIELDS_CACHE[$catalogue_name] = $fields;
    }
    foreach ($fields as $i => $f) {
        if (in_array($f['cf_type'], ['picture', 'theme_image', 'picture_multi'])) {
            $unique_key_num = $i;
            $field_type = $f['cf_type'];
            break;
        }
    }

    if ($unique_key_num === null) {
        return '';
    }

    $field_values = get_catalogue_entry_field_values($catalogue_name, $row['id'], [$unique_key_num], $fields);
    $field = $field_values[$unique_key_num];
    if (empty($field)) {
        return '';
    }

    switch ($field_type) {
        case 'picture':
            $value = $field['effective_value_pure'];
            if (url_is_local($value)) {
                $value = get_custom_base_url() . '/' . $value;
            }
            break;

        case 'theme_image':
            $value = find_theme_image($field['effective_value_pure']);
            break;

        case 'picture_multi':
            $_value = explode("\n", $field['effective_value_pure']);
            $value = $_value[0];
            if (url_is_local($value)) {
                $value = get_custom_base_url() . '/' . $value;
            }
            break;
    }

    return $value;
}

/**
 * Find an entry content-type language string label.
 *
 * @param  array $row Database row of entry
 * @return Tempcode Label
 */
function generate_catalogue_entry_content_type_label(array $row) : object
{
    if (!addon_installed('catalogues')) {
        return new Tempcode();
    }

    if (!array_key_exists('c_name', $row)) {
        return do_lang_tempcode('catalogues:CATALOGUE_ENTRY');
    }

    require_code('catalogues');

    $catalogue = load_catalogue_row($row['c_name']);
    return do_lang_tempcode('catalogues:CATALOGUE_GENERIC', escape_html(get_translated_text($catalogue['c_title'])));
}

/**
 * Find an entry content-type universal label (doesn't depend on language pack).
 *
 * @param  array $row Database row of entry
 * @return string Label
 */
function generate_catalogue_entry_content_type_universal_label(array $row) : string
{
    if (!addon_installed('catalogues')) {
        return 'Catalogue entry';
    }

    if (!array_key_exists('c_name', $row)) {
        return 'Catalogue entry';
    }

    require_code('catalogues');

    $catalogue = load_catalogue_row($row['c_name']);
    return get_translated_text($catalogue['c_title']) . ' entry';
}
