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

/**
 * Hook class.
 */
class Hook_fields_url_multi
{
    // ==============
    // Module: search
    // ==============

    /**
     * Get special Tempcode for inputting this field.
     *
     * @param  array $field The field details
     * @return ?array Specially encoded input detail rows (null: nothing special)
     */
    public function get_search_inputter(array $field) : ?array
    {
        return null;
    }

    /**
     * Get special SQL from POSTed parameters for this field.
     *
     * @param  array $field The field details
     * @param  integer $i We're processing for the ith row
     * @param  string $table_alias Table alias for catalogue entry table
     * @return ?array Tuple of SQL details (array: extra trans fields to search, array: extra plain fields to search, string: an extra table segment for a join, string: the name of the field to use as a title, if this is the title, extra WHERE clause stuff) (null: nothing special)
     */
    public function inputted_to_sql_for_search(array $field, int $i, string $table_alias = 'r') : ?array
    {
        return null;
    }

    // ===================
    // Backend: fields API
    // ===================

    /**
     * Get some info bits relating to our field type, that helps us look it up / set defaults.
     *
     * @param  ?array $field The field details (null: new field)
     * @param  ?boolean $required Whether a default value cannot be blank (null: don't "lock in" a new default value) (may be passed as false also if we want to avoid "lock in" of a new default value, but in this case possible cleanup of $default may still happen where appropriate)
     * @param  ?string $default The given default value as a string (null: don't "lock in" a new default value) (blank: only "lock in" a new default value if $required is true)
     * @return array Tuple of details (row-type,default-value-to-use,db row-type)
     */
    public function get_field_value_row_bits(?array $field, ?bool $required = null, ?string $default = null) : array
    {
        return ['long_unescaped', $default, 'long'];
    }

    /**
     * Convert a field value to something renderable.
     *
     * @param  array $field The field details
     * @param  mixed $ev The raw value
     * @param  integer $i Position in fieldset
     * @param  ?array $only_fields List of fields the output is being limited to (null: N/A)
     * @param  ?ID_TEXT $table The table we store in (null: N/A)
     * @param  ?AUTO_LINK $id The ID of the row in the table (null: N/A)
     * @param  ?ID_TEXT $id_field Name of the ID field in the table (null: N/A)
     * @param  ?ID_TEXT $field_id_field Name of the field ID field in the table (null: N/A)
     * @param  ?ID_TEXT $url_field Name of the URL field in the table (null: N/A)
     * @param  ?MEMBER $submitter Submitter (null: current member)
     * @param  ?mixed $ev_pure The 'pure' form of the raw value, meaning Comcode is not pre-parsed and string conversion has not been performed (null: unknown)
     * @return mixed Rendered field (string or Tempcode)
     */
    public function render_field_value(array &$field, $ev, int $i, ?array $only_fields, ?string $table = null, ?int $id = null, ?string $id_field = null, ?string $field_id_field = null, ?string $url_field = null, ?int $submitter = null, $ev_pure = null)
    {
        if (is_object($ev)) {
            return $ev;
        }

        if ($ev == '') {
            return '';
        }
        if ($ev == 'http://') {
            return '';
        }
        if ($ev == 'https://') {
            return '';
        }

        $out = [];
        $evs = explode("\n", $ev);
        foreach ($evs as $ev) {
            require_code('http');
            $meta_details = get_webpage_meta_details($ev);
            $link_captions_title = $meta_details['t_title'];

            if ($link_captions_title == '') {
                $link_captions_title = urldecode(basename($ev));
            }

            $out[$ev] = $link_captions_title;
        }

        $auto_sort = option_value_from_field_array($field, 'auto_sort', 'off');
        if ($auto_sort == 'on') {
            cms_mb_asort($out, SORT_NATURAL | SORT_FLAG_CASE);
        }

        $ret = new Tempcode();
        foreach ($out as $ev => $link_captions_title) {
            $ret->attach(paragraph(hyperlink((url_is_local($ev) ? (get_base_url() . '/') : '') . $ev, $link_captions_title, true, true), 'url_multi'));
        }
        return $ret;
    }

    // ======================
    // Frontend: fields input
    // ======================

    /**
     * Get form inputter.
     *
     * @param  string $_cf_name The field name
     * @param  string $_cf_description The field description
     * @param  array $field The field details
     * @param  ?string $actual_value The actual current value of the field (null: none)
     * @param  boolean $new Whether this is for a new entry
     * @return ?Tempcode The Tempcode for the input field (null: skip the field - it's not input)
     */
    public function get_field_inputter(string $_cf_name, string $_cf_description, array $field, ?string $actual_value, bool $new) : ?object
    {
        if ($actual_value === null) {
            $actual_value = ''; // Plug anomaly due to unusual corruption
        }

        $input_name = @cms_empty_safe($field['cf_input_name']) ? ('field_' . strval($field['id'])) : $field['cf_input_name'];
        return form_input_line_multi($_cf_name, $_cf_description, $input_name, ($actual_value == '') ? [] : explode("\n", $actual_value), ($field['cf_required'] == 1) ? 1 : 0, null, 'url');
    }

    /**
     * Find the posted value from the get_field_inputter field.
     *
     * @param  boolean $editing Whether we were editing (because on edit, it could be a fractional edit)
     * @param  array $field The field details
     * @param  ?string $upload_dir Where the files will be uploaded to (null: do not store an upload, return null if we would need to do so)
     * @param  ?array $old_value Former value of field (null: none)
     * @return ?string The value (null: could not process)
     */
    public function inputted_to_field_value(bool $editing, array $field, ?string $upload_dir = 'uploads/catalogues', ?array $old_value = null) : ?string
    {
        $id = $field['id'];
        $i = 0;
        $value = '';
        do {
            $tmp_name = 'field_' . strval($id) . '_' . strval($i);
            $_value = post_param_string($tmp_name, null);
            if (($_value === null) && ($i == 0)) {
                return $editing ? STRING_MAGIC_NULL : '';
            }
            if (!cms_empty_safe($_value)) {
                if ($_value != STRING_MAGIC_NULL) {
                    $_value = fixup_protocolless_urls($_value);
                }
                if (($_value == 'http://') || ($_value == 'https://')) {
                    $_value = '';
                }

                // Check if the URL is broken
                if (addon_installed('health_check') && ($_value != '')) {
                    $message = '';
                    require_code('urls2');
                    require_lang('health_check');
                    $ok = check_url_exists($_value, 60 * 60 * 24 * 1, true, 3, $message);
                    if ($message === null) {
                        $message = 'UNKNOWN';
                    }
                    if (!$ok) {
                        $message_text = do_lang('BROKEN_LINK_PROBLEM__' . str_replace('-', '_', $message), $_value, $message, null, null, false); // Support custom messages for specific status codes
                        if ($message_text === null) {
                            $message_text = do_lang('BROKEN_LINK_PROBLEM', $_value, $message);
                        }
                        require_code('comcode');
                        attach_message(comcode_to_tempcode($message_text), 'warn');
                    }
                }

                if ($value != '') {
                    $value .= "\n";
                }
                $value .= $_value;
            }
            $i++;
        } while ($_value !== null);
        return $value;
    }

    /**
     * Determine what data should be used from this field in SEO.
     *
     * @param  string $val The value of the field
     * @param  integer $field_id The ID of the field
     * @param  ID_TEXT $content_type The content type using this field
     * @param  ?ID_TEXT $content_id The ID of the content using this field (null: not using a specific piece of content, such as adding a new entry)
     * @return mixed Either a string of the content to use in SEO, or a Tuple of [(string) content to use, (boolean) must use / high priority, (boolean) is a codename]
     */
    public function get_seo_source_map(string $val, int $field_id, string $content_type, ?string $content_id = null)
    {
        return '';
    }
}
