Seditio Source
Root |
./othercms/croogo-4.0.7/vendor/cakephp/cakephp/src/View/Form/ContextFactory.php
<?php
/**
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * For full copyright and license information, please see the LICENSE.txt
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         3.5.0
 * @license       https://opensource.org/licenses/mit-license.php MIT License
 */
namespace Cake\View\Form;

use
Cake\Collection\Collection;
use
Cake\Datasource\EntityInterface;
use
Cake\Form\Form;
use
Cake\Http\ServerRequest;
use
RuntimeException;
use
Traversable;

/**
 * Factory for getting form context instance based on provided data.
 */
class ContextFactory
{
   
/**
     * Context providers.
     *
     * @var array
     */
   
protected $providers = [];

   
/**
     * Constructor.
     *
     * @param array $providers Array of provider callables. Each element should
     *   be of form `['type' => 'a-string', 'callable' => ..]`
     */
   
public function __construct(array $providers = [])
    {
        foreach (
$providers as $provider) {
           
$this->addProvider($provider['type'], $provider['callable']);
        }
    }

   
/**
     * Create factory instance with providers "array", "form" and "orm".
     *
     * @param array $providers Array of provider callables. Each element should
     *   be of form `['type' => 'a-string', 'callable' => ..]`
     * @return \Cake\View\Form\ContextFactory
     */
   
public static function createWithDefaults(array $providers = [])
    {
       
$providers = [
            [
               
'type' => 'orm',
               
'callable' => function ($request, $data) {
                    if (
is_array($data['entity']) || $data['entity'] instanceof Traversable) {
                       
$pass = (new Collection($data['entity']))->first() !== null;
                        if (
$pass) {
                            return new
EntityContext($request, $data);
                        }
                    }
                    if (
$data['entity'] instanceof EntityInterface) {
                        return new
EntityContext($request, $data);
                    }
                    if (
is_array($data['entity']) && empty($data['entity']['schema'])) {
                        return new
EntityContext($request, $data);
                    }
                },
            ],
            [
               
'type' => 'array',
               
'callable' => function ($request, $data) {
                    if (
is_array($data['entity']) && isset($data['entity']['schema'])) {
                        return new
ArrayContext($request, $data['entity']);
                    }
                },
            ],
            [
               
'type' => 'form',
               
'callable' => function ($request, $data) {
                    if (
$data['entity'] instanceof Form) {
                        return new
FormContext($request, $data);
                    }
                },
            ],
        ] +
$providers;

        return new static(
$providers);
    }

   
/**
     * Add a new context type.
     *
     * Form context types allow FormHelper to interact with
     * data providers that come from outside CakePHP. For example
     * if you wanted to use an alternative ORM like Doctrine you could
     * create and connect a new context class to allow FormHelper to
     * read metadata from doctrine.
     *
     * @param string $type The type of context. This key
     *   can be used to overwrite existing providers.
     * @param callable $check A callable that returns an object
     *   when the form context is the correct type.
     * @return $this
     */
   
public function addProvider($type, callable $check)
    {
       
$this->providers = [$type => ['type' => $type, 'callable' => $check]]
            +
$this->providers;

        return
$this;
    }

   
/**
     * Find the matching context for the data.
     *
     * If no type can be matched a NullContext will be returned.
     *
     * @param \Cake\Http\ServerRequest $request Request instance.
     * @param array $data The data to get a context provider for.
     * @return \Cake\View\Form\ContextInterface Context provider.
     * @throws \RuntimeException when the context class does not implement the
     *   ContextInterface.
     */
   
public function get(ServerRequest $request, array $data = [])
    {
       
$data += ['entity' => null];

        foreach (
$this->providers as $provider) {
           
$check = $provider['callable'];
           
$context = $check($request, $data);
            if (
$context) {
                break;
            }
        }
        if (!isset(
$context)) {
           
$context = new NullContext($request, $data);
        }
        if (!(
$context instanceof ContextInterface)) {
            throw new
RuntimeException(sprintf(
               
'Context providers must return object implementing %s. Got "%s" instead.',
               
ContextInterface::class,
               
getTypeName($context)
            ));
        }

        return
$context;
    }
}