PATH:
home
/
letacommog
/
aacote
/
wp-content
/
plugins
/
wp-job-manager
/
lib
/
wpjm_rest
<?php /** * The Abstract Mixtape_Interfaces_Model Base Class * * @package Mixtape/Model */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Class WP_Job_Manager_REST_Model */ class WP_Job_Manager_REST_Model implements WP_Job_Manager_REST_Interfaces_Model, WP_Job_Manager_REST_Interfaces_Permissions_Provider { /** * Fields By Class Name * * @var array */ private static $fields_by_class_name = array(); /** * Data Stores By Class Name * * @var array */ private static $data_stores_by_class_name = array(); /** * The Environment the model exists in * * @var WP_Job_Manager_REST_Environment */ private static $environments_by_class_name = array(); /** * Permissions Providers by class Name * * @var array */ private static $permissions_providers_by_class_name = array(); /** * Our data * * @var array */ private $data; /** * Our raw data * * @var array */ private $raw_data; /** * Mixtape_Model constructor. * * @param array $data The data array. * @param array $args Args. * * @throws WP_Job_Manager_REST_Exception Throws when data is not an array. */ function __construct( $data = array(), $args = array() ) { WP_Job_Manager_REST_Expect::that( is_array( $data ), '$data should be an array' ); $this->data = array(); if ( isset( $args['deserialize'] ) && true === $args['deserialize'] ) { unset( $args['deserialize'] ); $data = $this->deserialize( $data ); } $this->raw_data = $data; $data_keys = array_keys( $data ); foreach ( $data_keys as $key ) { $this->set( $key, $this->raw_data[ $key ] ); } } /** * Gets the value of a previously defined field. * * @param string $field_name The field name. * @param array $args Any args. * * @return mixed * @throws WP_Job_Manager_REST_Exception Fails when field is unknown. */ public function get( $field_name, $args = array() ) { WP_Job_Manager_REST_Expect::that( $this->has( $field_name ), 'Field ' . $field_name . 'is not defined' ); $fields = $this->get_fields(); $field_declaration = $fields[ $field_name ]; $this->set_field_if_unset( $field_declaration ); return $this->prepare_value( $field_declaration ); } /** * Sets a field value. * * @param string $field The field name. * @param mixed $value The new field value. * * @return $this * @throws WP_Job_Manager_REST_Exception Throws when trying to set an unknown field. */ public function set( $field, $value ) { WP_Job_Manager_REST_Expect::that( $this->has( $field ), 'Field ' . $field . 'is not defined' ); $fields = self::get_fields(); /** * The declaration. * * @var WP_Job_Manager_REST_Field_Declaration $field_declaration The declaration. */ $field_declaration = $fields[ $field ]; if ( isset( $args['deserializing'] ) && $args['deserializing'] ) { $value = $this->deserialize_field( $field_declaration, $value ); } if ( null !== $field_declaration->before_set() ) { $val = $this->call( $field_declaration->before_set(), array( $value, $field_declaration->get_name() ) ); } else { $val = $field_declaration->cast_value( $value ); } $this->data[ $field_declaration->get_name() ] = $val; return $this; } /** * Check if this model has a field * * @param string $field The field name to check. * @return bool */ public function has( $field ) { $fields = $this->get_fields(); return isset( $fields[ $field ] ); } /** * Validate this Model's current state. * * @return bool|WP_Error Either true or WP_Error on failure. */ public function validate() { $validation_errors = array(); $fields = self::get_fields(); foreach ( $fields as $key => $field_declaration ) { $is_valid = $this->run_field_validations( $field_declaration ); if ( is_wp_error( $is_valid ) ) { $validation_errors[] = $is_valid->get_error_data(); } } if ( count( $validation_errors ) > 0 ) { return $this->validation_error( $validation_errors ); } return true; } /** * Sanitize this Model's current data. * * @return WP_Job_Manager_REST_Interfaces_Model $this */ public function sanitize() { $fields = self::get_fields(); foreach ( $fields as $key => $field_declaration ) { /** * Field Declaration. * * @var WP_Job_Manager_REST_Field_Declaration $field_declaration */ $field_name = $field_declaration->get_name(); $value = $this->get( $field_name ); $custom_sanitization = $field_declaration->get_sanitizer(); if ( ! empty( $custom_sanitization ) ) { $value = $this->call( $custom_sanitization, array( $this, $value ) ); } else { $value = $field_declaration->get_type()->sanitize( $value ); } $this->set( $field_name, $value ); } return $this; } /** * We got a Validation Error * * @param array $error_data The details. * @return WP_Error */ protected function validation_error( $error_data ) { return new WP_Error( 'validation-error', 'validation-error', $error_data ); } /** * Run Validations for this field. * * @param WP_Job_Manager_REST_Field_Declaration $field_declaration The field. * * @return bool|WP_Error */ protected function run_field_validations( $field_declaration ) { if ( $field_declaration->is_kind( WP_Job_Manager_REST_Field_Declaration::DERIVED ) ) { return true; } $value = $this->get( $field_declaration->get_name() ); if ( $field_declaration->is_required() && empty( $value ) ) { // translators: %s is usually a field name. $message = sprintf( __( '%s cannot be empty', 'mixtape' ), $field_declaration->get_name() ); return new WP_Error( 'required-field-empty', $message ); } elseif ( ! $field_declaration->is_required() && ! empty( $value ) ) { foreach ( $field_declaration->get_validations() as $validation ) { $result = $this->call( $validation, array( $value ) ); if ( is_wp_error( $result ) ) { $result->add_data(array( 'reason' => $result->get_error_messages(), 'field' => $field_declaration->get_data_transfer_name(), 'value' => $value, ) ); return $result; } } } return true; } /** * Prepare the value associated with this declaraton for output. * * @param WP_Job_Manager_REST_Field_Declaration $field_declaration The declaration to use. * @return mixed */ private function prepare_value( $field_declaration ) { $key = $field_declaration->get_name(); $value = $this->data[ $key ]; $before_return = $field_declaration->before_get(); if ( isset( $before_return ) && ! empty( $before_return ) ) { $value = $this->call( $before_return, array( $value, $key ) ); } return $value; } /** * Sets this field's value. Used for derived fields. * * @param WP_Job_Manager_REST_Field_Declaration $field_declaration The field declaration. */ private function set_field_if_unset( $field_declaration ) { $field_name = $field_declaration->get_name(); if ( ! isset( $this->data[ $field_name ] ) ) { if ( $field_declaration->is_kind( WP_Job_Manager_REST_Field_Declaration::DERIVED ) ) { $map_from = $field_declaration->get_map_from(); $value = $this->call( $map_from ); $this->set( $field_name, $value ); } else { $this->set( $field_name, $field_declaration->get_default_value() ); } } } /** * Get this model class fields * * @param null|string $filter_by_type Filter. * @return array */ public function get_fields( $filter_by_type = null ) { $class_name = get_class( $this ); /** * Out model * * @var WP_Job_Manager_REST_Interfaces_Model $instance */ $instance = new $class_name(); if ( ! isset( self::$fields_by_class_name[ $class_name ] ) ) { $fields = $instance->declare_fields(); self::$fields_by_class_name[ $class_name ] = self::initialize_field_map( $fields ); } if ( null === $filter_by_type ) { return self::$fields_by_class_name[ $class_name ]; } $filtered = array(); foreach ( self::$fields_by_class_name[ $class_name ] as $field_declaration ) { /** * The field declaration. * * @var WP_Job_Manager_REST_Field_Declaration $field_declaration */ if ( $field_declaration->get_kind() === $filter_by_type ) { $filtered[] = $field_declaration; } } return $filtered; } /** * Initialize_field_map * * @param array $declared_field_builders Array<Mixtape_Model_Field_Declaration_Builder>. * * @return array */ private static function initialize_field_map( $declared_field_builders ) { $fields = array(); foreach ( $declared_field_builders as $field_builder ) { /** * Builder * * @var WP_Job_Manager_REST_Field_Declaration $field Field Builder. */ $field = $field_builder->build(); $fields[ $field->get_name() ] = $field; } return $fields; } /** * Get this model's data store * * @return WP_Job_Manager_REST_Interfaces_Data_Store */ public function get_data_store() { $class_name = get_class( $this ); if ( ! isset( self::$data_stores_by_class_name[ $class_name ] ) ) { self::$data_stores_by_class_name[ $class_name ] = new WP_Job_Manager_REST_Data_Store_Nil(); } return self::$data_stores_by_class_name[ $class_name ]; } /** * Set this model's data store * * @param WP_Job_Manager_REST_Interfaces_Data_Store $data_store A builder or a Data store. * @throws WP_Job_Manager_REST_Exception Throws when Data Store Invalid. */ public function with_data_store( $data_store ) { $class_name = get_class( $this ); // at this point we should have a data store. WP_Job_Manager_REST_Expect::is_a( $data_store, 'WP_Job_Manager_REST_Interfaces_Data_Store' ); self::$data_stores_by_class_name[ $class_name ] = $data_store; } /** * Get this model's environment * * @return WP_Job_Manager_REST_Environment|null */ public function get_environment() { $class_name = get_class( $this ); if ( isset( self::$environments_by_class_name[ $class_name ] ) ) { return self::$environments_by_class_name[ $class_name ]; } return null; } /** * Set the model base class environment (change effective in all subclasses) * * @param WP_Job_Manager_REST_Environment $environment The Environment. * * @return WP_Job_Manager_REST_Interfaces_Model * * @throws WP_Job_Manager_REST_Exception If an WP_Job_Manager_REST_Environment is not provided. */ public function with_environment( $environment ) { WP_Job_Manager_REST_Expect::is_a( $environment, 'WP_Job_Manager_REST_Environment' ); $class_name = get_class( $this ); self::$environments_by_class_name[ $class_name ] = $environment; return $this; } /** * Create a new Model Instance * * @param array $data The data. * @param array $args Args. * * @return WP_Job_Manager_REST_Interfaces_Model * @throws WP_Job_Manager_REST_Exception Throws if data not an array. */ public function create( $data, $args = array() ) { WP_Job_Manager_REST_Expect::that( is_array( $data ), '$data should be an array' ); WP_Job_Manager_REST_Expect::that( is_array( $args ), '$args should be an array' ); $class_name = get_class( $this ); return new $class_name( $data, $args ); } /** * Merge values from array with current values. * Note: Values change in place. * * @param array $data The data (key-value assumed). * @param bool $updating Is this an update?. * * @return WP_Job_Manager_REST_Interfaces_Model|WP_Error * @throws WP_Job_Manager_REST_Exception Throws. */ function update_from_array( $data, $updating = false ) { $mapped_data = self::map_data( $data, $updating ); foreach ( $mapped_data as $name => $value ) { $this->set( $name, $value ); } return $this->sanitize(); } /** * Creates a new Model From a Data Array * * @param array $data The Data. * * @return WP_Job_Manager_REST_Model|WP_Error */ public function new_from_array( $data ) { $field_data = $this->map_data( $data, false ); return $this->create( $field_data )->sanitize(); } /** * Get field DTO Mappings * * @return array */ public function get_dto_field_mappings() { $mappings = array(); foreach ( $this->get_fields() as $field_declaration ) { /** * Declaration * * @var WP_Job_Manager_REST_Field_Declaration $field_declaration */ if ( ! $field_declaration->supports_output_type( 'json' ) ) { continue; } $mappings[ $field_declaration->get_data_transfer_name() ] = $field_declaration->get_name(); } return $mappings; } /** * Prepare the Model for Data Transfer * * @return array */ function to_dto() { $result = array(); foreach ( $this->get_dto_field_mappings() as $mapping_name => $field_name ) { $value = $this->get( $field_name ); $result[ $mapping_name ] = $value; } return $result; } /** * Map data names * * @param array $data The data to map. * @param bool $updating Are we Updating. * @return array */ private function map_data( $data, $updating = false ) { $request_data = array(); $fields = $this->get_fields(); foreach ( $fields as $field ) { /** * Field * * @var WP_Job_Manager_REST_Field_Declaration $field Field. */ if ( $field->is_kind( WP_Job_Manager_REST_Field_Declaration::DERIVED ) ) { continue; } $dto_name = $field->get_data_transfer_name(); $field_name = $field->get_name(); if ( isset( $data[ $dto_name ] ) && ! ( $updating && $field->is_primary() ) ) { $value = $data[ $dto_name ]; $request_data[ $field_name ] = $value; } } return $request_data; } /** * Call a method. * * @param string $method The method. * @param array $args The args. * * @return mixed * @throws WP_Job_Manager_REST_Exception Throw if method nonexistent. */ private function call( $method, $args = array() ) { if ( is_callable( $method ) ) { return call_user_func_array( $method, $args ); } WP_Job_Manager_REST_Expect::that( method_exists( $this, $method ), $method . ' does not exist' ); return call_user_func_array( array( $this, $method ), $args ); } /** * Get name * * @return string */ public function get_name() { return strtolower( get_class( $this ) ); } /** * Declare fields. * * @return array */ public function declare_fields() { WP_Job_Manager_REST_Expect::should_override( __METHOD__ ); return array(); } /** * Get the id * * @return mixed|null */ function get_id() { return $this->get( 'id' ); } /** * Set the id * * @param mixed $new_id The new id. * * @return mixed|null */ function set_id( $new_id ) { return $this->set( 'id', $new_id ); } /** * Create from Post. * * @param WP_Post $post Post. * @return WP_Job_Manager_REST_Model * @throws WP_Job_Manager_REST_Exception If something goes wrong. */ public static function from_raw_data( $post ) { $raw_post_data = $post->to_array(); $raw_meta_data = get_post_meta( $post->ID ); // assumes we are only ever adding one postmeta per key. $flattened_meta = array(); foreach ( $raw_meta_data as $key => $value_arr ) { $flattened_meta[ $key ] = $value_arr[0]; } $merged_data = array_merge( $raw_post_data, $flattened_meta ); return self::create( $merged_data, array( 'deserialize' => true, ) ); } /** * Transform raw data to model data * * @param array $data Data. * @return array */ public function deserialize( $data ) { $field_declarations = $this->get_fields(); $raw_data = array(); $post_array_keys = array_keys( $data ); foreach ( $field_declarations as $declaration ) { /** * Declaration * * @var WP_Job_Manager_REST_Field_Declaration $declaration */ $key = $declaration->get_name(); $mapping = $declaration->get_map_from(); $value = null; if ( in_array( $key, $post_array_keys, true ) ) { // simplest case: we got a $key for this, so just map it. $value = $this->deserialize_field( $declaration, $data[ $key ] ); } elseif ( in_array( $mapping, $post_array_keys, true ) ) { // other case: we got a mapping. $value = $this->deserialize_field( $declaration, $data[ $mapping ] ); } else { // just provide a default. $value = $declaration->get_default_value(); } $raw_data[ $key ] = $declaration->cast_value( $value ); } return $raw_data; } /** * Transform Model to raw data array * * @param null|string $field_type Type. * * @return array */ function serialize( $field_type = null ) { $field_values_to_insert = array(); foreach ( $this->get_fields( $field_type ) as $field_declaration ) { /** * Declaration * * @var WP_Job_Manager_REST_Field_Declaration $field_declaration */ $what_to_map_to = $field_declaration->get_map_from(); $value = $this->get( $field_declaration->get_name() ); $field_values_to_insert[ $what_to_map_to ] = $this->serialize_field( $field_declaration, $value ); } return $field_values_to_insert; } /** * Deserialize * * @param WP_Job_Manager_REST_Field_Declaration $field_declaration Declaration. * @param mixed $value Value. * @return mixed the deserialized value */ private function deserialize_field( $field_declaration, $value ) { $deserializer = $field_declaration->get_deserializer(); if ( isset( $deserializer ) && ! empty( $deserializer ) ) { return $this->call( $deserializer, array( $value ) ); } return $value; } /** * Serialize * * @param WP_Job_Manager_REST_Field_Declaration $field_declaration Declaration. * @param mixed $value Value. * @return mixed * @throws WP_Job_Manager_REST_Exception If call fails. */ private function serialize_field( $field_declaration, $value ) { $serializer = $field_declaration->get_serializer(); if ( isset( $serializer ) && ! empty( $serializer ) ) { return $this->call( $serializer, array( $value ) ); } return $value; } /** * Handle Permissions for a REST Controller Action * * @param WP_REST_Request $request The request. * @param string $action The action (e.g. index, create update etc). * @return bool */ public function permissions_check( $request, $action ) { $class_name = get_class( $this ); if ( isset( self::$permissions_providers_by_class_name[ $class_name ] ) ) { $permissions_provider = self::$permissions_providers_by_class_name[ $class_name ]; return call_user_func_array( array( $permissions_provider, 'permissions_check' ), array( $request, $action ) ); } return true; } /** * Set a Proxy Permission Provider for this class * * @param WP_Job_Manager_REST_Interfaces_Permissions_Provider $permissions_provider PP. * @return WP_Job_Manager_REST_Model $this */ public function with_permissions_provider( $permissions_provider ) { WP_Job_Manager_REST_Expect::is_a( $permissions_provider, 'WP_Job_Manager_REST_Interfaces_Permissions_Provider' ); $class_name = get_class( $this ); self::$permissions_providers_by_class_name[ $class_name ] = $permissions_provider; return $this; } }
[+]
..
[+]
data
[+]
field
[+]
permissions
[-] class-wp-job-manager-rest-model.php
[edit]
[-] class-wp-job-manager-rest-exception.php
[edit]
[-] class-wp-job-manager-rest-environment.php
[edit]
[-] class-wp-job-manager-rest-events.php
[edit]
[+]
type
[-] class-wp-job-manager-rest-classloader.php
[edit]
[-] class-wp-job-manager-rest-type.php
[edit]
[+]
controller
[+]
model
[-] class-wp-job-manager-rest-controller.php
[edit]
[-] class-wp-job-manager-rest-bootstrap.php
[edit]
[-] class-wp-job-manager-rest-expect.php
[edit]
[+]
interfaces