aristath/kirki

View on GitHub
packages/kirki-framework/control-repeater/src/Field/Repeater.php

Summary

Maintainability
C
1 day
Test Coverage
<?php
/**
 * Override field methods
 *
 * @package   kirki-framework/control-repeater
 * @copyright Copyright (c) 2019, Ari Stathopoulos (@aristath)
 * @license   https://opensource.org/licenses/MIT
 * @since     1.0
 */

namespace Kirki\Field;

use Kirki\Compatibility\Field;

/**
 * Field overrides.
 *
 * @since 1.0
 */
class Repeater extends Field {

    /**
     * The field type.
     *
     * @access public
     * @since 1.0
     * @var string
     */
    public $type = 'kirki-repeater';

    /**
     * Used only on repeaters.
     * Contains an array of the fields.
     *
     * @access protected
     * @since 1.0
     * @var array
     */
    protected $fields = [];

    /**
     * Sets the control type.
     *
     * @access protected
     * @since 1.0
     * @return void
     */
    protected function set_type() {

        $this->type = 'repeater';

    }

    /**
     * Sets the $transport
     *
     * @access protected
     * @since 1.0
     * @return void
     */
    protected function set_transport() {

        // Force using refresh mode.
        // Currently the repeater control does not support postMessage.
        $this->transport = 'refresh';

    }


    /**
     * Sets the $sanitize_callback
     *
     * @access protected
     * @since 1.0
     * @return void
     */
    protected function set_sanitize_callback() {

        if ( empty( $this->sanitize_callback ) ) {
            $this->sanitize_callback = [ $this, 'sanitize' ];
        }

    }

    /**
     * The sanitize method that will be used as a falback
     *
     * @access public
     * @since 1.0
     * @param string|array $value The control's value.
     */
    public function sanitize( $value ) {

        // is the value formatted as a string?
        if ( is_string( $value ) ) {
            $value = rawurldecode( $value );
            $value = json_decode( $value, true );
        }

        // Nothing to sanitize if we don't have fields.
        if ( empty( $this->fields ) ) {
            return $value;
        }

        foreach ( $value as $row_id => $row_value ) {

            // Make sure the row is formatted as an array.
            if ( ! is_array( $row_value ) ) {
                $value[ $row_id ] = [];
                continue;
            }

            // Start parsing sub-fields in rows.
            foreach ( $row_value as $subfield_id => $subfield_value ) {

                // Make sure this is a valid subfield.
                // If it's not, then unset it.
                if ( ! isset( $this->fields[ $subfield_id ] ) ) {
                    unset( $value[ $row_id ][ $subfield_id ] );
                }

                // Get the subfield-type.
                if ( ! isset( $this->fields[ $subfield_id ]['type'] ) ) {
                    continue;
                }

                $subfield_type = $this->fields[ $subfield_id ]['type'];

                // Allow using a sanitize-callback on a per-field basis.
                if ( isset( $this->fields[ $subfield_id ]['sanitize_callback'] ) ) {
                    $subfield_value = call_user_func( $this->fields[ $subfield_id ]['sanitize_callback'], $subfield_value );
                } else {

                    switch ( $subfield_type ) {
                        case 'image':
                        case 'cropped_image':
                        case 'upload':
                            if ( ! is_numeric( $subfield_value ) && is_string( $subfield_value ) ) {
                                $subfield_value = esc_url_raw( $subfield_value );
                            }
                            break;
                        case 'dropdown-pages':
                            $subfield_value = (int) $subfield_value;
                            break;
                        case 'color':
                            if ( $subfield_value ) {
                                $subfield_value = \Kirki\Field\ReactColorful::sanitize( $subfield_value );
                            }
                            break;
                        case 'text':
                            $subfield_value = sanitize_text_field( $subfield_value );
                            break;
                        case 'url':
                        case 'link':
                            $subfield_value = esc_url_raw( $subfield_value );
                            break;
                        case 'email':
                            $subfield_value = filter_var( $subfield_value, FILTER_SANITIZE_EMAIL );
                            break;
                        case 'tel':
                            $subfield_value = sanitize_text_field( $subfield_value );
                            break;
                        case 'checkbox':
                            $subfield_value = (bool) $subfield_value;
                            break;
                        case 'select':
                            if ( isset( $this->fields[ $subfield_id ]['multiple'] ) ) {
                                if ( true === $this->fields[ $subfield_id ]['multiple'] ) {
                                    $multiple = 2;
                                }
                                $multiple = (int) $this->fields[ $subfield_id ]['multiple'];
                                if ( 1 < $multiple ) {
                                    $subfield_value = (array) $subfield_value;
                                    foreach ( $subfield_value as $sub_subfield_key => $sub_subfield_value ) {
                                        $subfield_value[ $sub_subfield_key ] = sanitize_text_field( $sub_subfield_value );
                                    }
                                } else {
                                    $subfield_value = sanitize_text_field( $subfield_value );
                                }
                            }
                            break;
                        case 'radio':
                        case 'radio-image':
                            $subfield_value = sanitize_text_field( $subfield_value );
                            break;
                        case 'textarea':
                            $subfield_value = html_entity_decode( wp_kses_post( $subfield_value ) );

                    }
                }

                $value[ $row_id ][ $subfield_id ] = $subfield_value;
            }
        }

        return $value;

    }

}