<?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_state
{
    // ==============
    // 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
     * @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) : ?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)
     * @param  ?string $default The given default value as a string (null: don't "lock in" a new default value)
     * @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 ['short_unescaped', $default, 'short'];
    }

    /**
     * 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)) {
            $ev = $ev->evaluate();
        }

        if ($ev == '') {
            return '';
        }

        if (get_option('business_country', true) === 'US') { // Some tax services may need exact states, and Americans are a bit pampered, so show an explicit list
            require_code('locations');

            global $USA_STATE_LIST;
            if (isset($USA_STATE_LIST[$ev])) {
                $ev = $USA_STATE_LIST[$ev];
            }
        }

        return escape_html($ev);
    }

    // ======================
    // 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'];
        $autocomplete = ($new && !empty($field['cf_autofill_type'])) ? (($field['cf_autofill_hint'] ? ($field['cf_autofill_hint'] . ' ') : '') . $field['cf_autofill_type']) : null;

        $definitely_usa = (get_option('cpf_enable_country') == '0') && (get_option('business_country', true) === 'US');
        if (get_option('business_country', true) === 'US') { // Some tax services need exact states, and Americans are a bit pampered, so show an explicit list
            require_code('locations');
            $state_list = new Tempcode();
            $state_list->attach(form_input_list_entry('', '' == $actual_value, do_lang_tempcode('NA_EM')));
            $state_list->attach(create_usa_state_selection_list([$actual_value]));
            return form_input_list($_cf_name, $_cf_description, $input_name, $state_list, null, false, $field['cf_required'] == 1, null, 5, $autocomplete);
        }

        return form_input_line($_cf_name, $_cf_description, $input_name, $actual_value, $field['cf_required'] == 1, null, null, 'text', null, null, null, null, $autocomplete);
    }

    /**
     * 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'];
        $tmp_name = 'field_' . strval($id);
        $value = post_param_string($tmp_name, $editing ? STRING_MAGIC_NULL : '');

        // Validation (when using a U.S. state)
        if (($value != '') && ($value != STRING_MAGIC_NULL) && (get_option('business_country', true) === 'US')) {
            require_code('locations');

            global $USA_STATE_LIST;

            if (!array_key_exists($value, $USA_STATE_LIST)) {
                warn_exit(do_lang_tempcode('locations:NOT_VALID_US_STATE', escape_html($value)));
            }
        }

        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 $val;
    }
}
