class-field.php
<?php
namespace HivePress\Fields;
use HivePress\Helpers as hp;
use HivePress\Traits;
defined( 'ABSPATH' ) || exit;
abstract class Field {
use Traits\Mutator;
use Traits\Context;
use Traits\Meta {
set_meta as _set_meta;
}
protected $args = [];
protected $display_type;
protected $display_template;
protected $name;
protected $label;
protected $description;
protected $statuses = [];
protected $value;
protected $parent_value;
protected $filter;
protected $disabled = false;
protected $required = false;
protected $errors = [];
protected $attributes = [];
public static function init( $meta = [] ) {
$meta = hp\merge_arrays(
[
'name' => hp\get_class_name( static::class ),
'type' => 'CHAR',
'editable' => true,
'filterable' => false,
'sortable' => false,
'settings' => [
'required' => [
'label' => esc_html_x( 'Required', 'field', 'hivepress' ),
'caption' => esc_html__( 'Make this field required', 'hivepress' ),
'type' => 'checkbox',
'_context' => 'edit',
'_order' => 10,
],
'description' => [
'label' => hivepress()->translator->get_string( 'description' ),
'type' => 'textarea',
'max_length' => 2048,
'html' => true,
'_context' => 'edit',
'_order' => 20,
],
],
],
$meta
);
foreach ( hp\get_class_parents( static::class ) as $class ) {
$meta = apply_filters( 'hivepress/v1/fields/' . hp\get_class_name( $class ) . '/meta', $meta );
}
static::set_meta( $meta );
}
public function __construct( $args = [] ) {
$args = hp\merge_arrays(
[
'display_type' => hp\get_class_name( static::class ),
'display_template' => '%value%',
],
$args
);
foreach ( hp\get_class_parents( static::class ) as $class ) {
$args = apply_filters( 'hivepress/v1/fields/' . hp\get_class_name( $class ), $args, $this );
}
$this->args = $args;
foreach ( $args as $name => $value ) {
$this->set_property( $name, $value );
}
$this->boot();
}
protected function boot() {
if ( isset( $this->args['default'] ) ) {
$this->set_value( $this->args['default'] );
}
if ( ! $this->required ) {
$this->statuses = array_merge( [ 'optional' => esc_html_x( 'optional', 'field', 'hivepress' ) ], $this->statuses );
}
$this->statuses = array_filter( $this->statuses );
if ( 'hidden' === $this->display_type ) {
$this->attributes = array_filter(
$this->attributes,
function( $name ) {
return strpos( $name, 'data-' ) === 0;
},
ARRAY_FILTER_USE_KEY
);
}
$this->attributes = hp\merge_arrays(
$this->attributes,
[
'class' => [ 'hp-field', 'hp-field--' . hp\sanitize_slug( $this->display_type ) ],
]
);
}
final protected static function set_meta( $meta ) {
$settings = array_filter( hp\get_array_value( $meta, 'settings', [] ) );
if ( $settings ) {
$meta['settings'] = [];
foreach ( $settings as $name => $args ) {
$field = hp\create_class_instance( '\HivePress\Fields\\' . $args['type'], [ array_merge( $args, [ 'name' => $name ] ) ] );
if ( $field ) {
$meta['settings'][ $name ] = $field;
}
}
}
static::_set_meta( $meta );
}
final public function get_args() {
return $this->args;
}
final public function get_arg( $name ) {
return hp\get_array_value( $this->args, $name );
}
final public function get_display_type() {
return $this->display_type;
}
protected function set_display_template( $display_template ) {
$this->display_template = $display_template;
}
final public function get_name() {
return $this->name;
}
final public function get_slug() {
return hp\sanitize_slug( $this->name );
}
final public function get_label( $default = null ) {
$label = $this->label;
if ( ! $label && $default ) {
$label = true === $default ? $this->name : $default;
}
return $label;
}
final public function get_description() {
return $this->description;
}
final public function get_statuses() {
return $this->statuses;
}
public function set_value( $value ) {
$this->value = $value;
$this->filter = null;
if ( ! is_null( $this->value ) ) {
$this->normalize();
if ( ! is_null( $this->value ) ) {
$this->sanitize();
$this->update_filter();
}
}
return $this;
}
final public function get_value() {
return $this->value;
}
public function get_display_value() {
return $this->value;
}
public function set_parent_value( $value ) {
$this->parent_value = $value;
return $this;
}
protected function add_filter() {
$this->filter = [
'name' => $this->name,
'type' => static::get_meta( 'type' ),
'value' => $this->value,
'operator' => '=',
];
}
final public function get_filter() {
return $this->filter;
}
final public function update_filter( $force = false ) {
if ( $force || ( ! is_null( $this->value ) && static::get_meta( 'filterable' ) ) ) {
$this->add_filter();
}
}
final public function is_disabled() {
return $this->disabled;
}
final public function is_required() {
return $this->required;
}
final protected function add_errors( $errors ) {
$this->errors = array_merge( $this->errors, (array) $errors );
}
final public function get_errors() {
return $this->errors;
}
protected function normalize() {
if ( '' === $this->value ) {
$this->value = null;
}
}
abstract protected function sanitize();
public function validate() {
$this->errors = [];
if ( $this->required && is_null( $this->value ) ) {
$this->errors['required'] = sprintf( esc_html__( '"%s" field is required.', 'hivepress' ), $this->get_label( true ) );
}
return empty( $this->errors );
}
abstract public function render();
public function display() {
$shortcode = hp\has_shortcode( $this->display_template );
$value = $this->get_display_value();
foreach ( hp\get_class_parents( static::class ) as $class ) {
$value = apply_filters( 'hivepress/v1/fields/' . hp\get_class_name( $class ) . '/display_value', $value, $this );
}
if ( $shortcode ) {
$value = strip_shortcodes( $value );
}
$output = hp\replace_tokens(
array_merge(
$this->context,
[
'label' => '<strong>' . $this->label . '</strong>',
'value' => $value,
]
),
$this->display_template,
true
);
if ( $shortcode ) {
$output = do_shortcode( $output );
}
return $output;
}
}