/var/www/vhosts/ihelp.ro/_OLD/vendor/cakephp/cakephp/src/View/Form
NameSizeModeActions
ArrayContext.php108600644editdlrm
ContextFactory.php54160644editdlrm
ContextInterface.php41560644editdlrm
EntityContext.php230950644editdlrm
FormContext.php52280644editdlrm
NullContext.php27700644editdlrm
Edit: /var/www/vhosts/ihelp.ro/_OLD/vendor/cakephp/cakephp/src/View/Form/EntityContext.php (23095B)
validators when * dealing with associated forms. */ class EntityContext implements ContextInterface { use LocatorAwareTrait; /** * Context data for this object. * * @var array */ protected $_context; /** * The name of the top level entity/table object. * * @var string */ protected $_rootName; /** * Boolean to track whether or not the entity is a * collection. * * @var bool */ protected $_isCollection = false; /** * A dictionary of tables * * @var \Cake\ORM\Table[] */ protected $_tables = []; /** * Dictionary of validators. * * @var \Cake\Validation\Validator[] */ protected $_validator = []; /** * Constructor. * * @param array $context Context info. */ public function __construct(array $context) { $context += [ 'entity' => null, 'table' => null, 'validator' => [], ]; $this->_context = $context; $this->_prepare(); } /** * Prepare some additional data from the context. * * If the table option was provided to the constructor and it * was a string, TableLocator will be used to get the correct table instance. * * If an object is provided as the table option, it will be used as is. * * If no table option is provided, the table name will be derived based on * naming conventions. This inference will work with a number of common objects * like arrays, Collection objects and ResultSets. * * @return void * @throws \RuntimeException When a table object cannot be located/inferred. */ protected function _prepare(): void { /** @var \Cake\ORM\Table|null $table */ $table = $this->_context['table']; /** @var \Cake\Datasource\EntityInterface|iterable $entity */ $entity = $this->_context['entity']; if (empty($table)) { if (is_iterable($entity)) { foreach ($entity as $e) { $entity = $e; break; } } $isEntity = $entity instanceof EntityInterface; if ($isEntity) { /** @psalm-suppress PossiblyInvalidMethodCall */ $table = $entity->getSource(); } if (!$table && $isEntity && get_class($entity) !== Entity::class) { [, $entityClass] = namespaceSplit(get_class($entity)); $table = Inflector::pluralize($entityClass); } } if (is_string($table) && strlen($table)) { $table = $this->getTableLocator()->get($table); } if (!($table instanceof Table)) { throw new RuntimeException( 'Unable to find table class for current entity.' ); } $this->_isCollection = ( is_array($entity) || $entity instanceof Traversable ); $alias = $this->_rootName = $table->getAlias(); $this->_tables[$alias] = $table; } /** * Get the primary key data for the context. * * Gets the primary key columns from the root entity's schema. * * @return string[] * @deprecated 4.0.0 Renamed to {@link getPrimaryKey()}. */ public function primaryKey(): array { deprecationWarning('`EntityContext::primaryKey()` is deprecated. Use `EntityContext::getPrimaryKey()`.'); return (array)$this->_tables[$this->_rootName]->getPrimaryKey(); } /** * Get the primary key data for the context. * * Gets the primary key columns from the root entity's schema. * * @return string[] */ public function getPrimaryKey(): array { return (array)$this->_tables[$this->_rootName]->getPrimaryKey(); } /** * @inheritDoc */ public function isPrimaryKey(string $field): bool { $parts = explode('.', $field); $table = $this->_getTable($parts); if (!$table) { return false; } $primaryKey = (array)$table->getPrimaryKey(); return in_array(array_pop($parts), $primaryKey, true); } /** * Check whether or not this form is a create or update. * * If the context is for a single entity, the entity's isNew() method will * be used. If isNew() returns null, a create operation will be assumed. * * If the context is for a collection or array the first object in the * collection will be used. * * @return bool */ public function isCreate(): bool { $entity = $this->_context['entity']; if (is_iterable($entity)) { foreach ($entity as $e) { $entity = $e; break; } } if ($entity instanceof EntityInterface) { return $entity->isNew() !== false; } return true; } /** * Get the value for a given path. * * Traverses the entity data and finds the value for $path. * * @param string $field The dot separated path to the value. * @param array $options Options: * * - `default`: Default value to return if no value found in data or * entity. * - `schemaDefault`: Boolean indicating whether default value from table * schema should be used if it's not explicitly provided. * @return mixed The value of the field or null on a miss. */ public function val(string $field, array $options = []) { $options += [ 'default' => null, 'schemaDefault' => true, ]; if (empty($this->_context['entity'])) { return $options['default']; } $parts = explode('.', $field); $entity = $this->entity($parts); if ($entity && end($parts) === '_ids') { return $this->_extractMultiple($entity, $parts); } if ($entity instanceof EntityInterface) { $part = end($parts); if ($entity instanceof InvalidPropertyInterface) { $val = $entity->getInvalidField($part); if ($val !== null) { return $val; } } $val = $entity->get($part); if ($val !== null) { return $val; } if ( $options['default'] !== null || !$options['schemaDefault'] || !$entity->isNew() ) { return $options['default']; } return $this->_schemaDefault($parts); } if (is_array($entity) || $entity instanceof ArrayAccess) { $key = array_pop($parts); return $entity[$key] ?? $options['default']; } return null; } /** * Get default value from table schema for given entity field. * * @param string[] $parts Each one of the parts in a path for a field name * @return mixed */ protected function _schemaDefault(array $parts) { $table = $this->_getTable($parts); if ($table === null) { return null; } $field = end($parts); $defaults = $table->getSchema()->defaultValues(); if (!array_key_exists($field, $defaults)) { return null; } return $defaults[$field]; } /** * Helper method used to extract all the primary key values out of an array, The * primary key column is guessed out of the provided $path array * * @param mixed $values The list from which to extract primary keys from * @param string[] $path Each one of the parts in a path for a field name * @return array|null */ protected function _extractMultiple($values, array $path): ?array { if (!is_iterable($values)) { return null; } $table = $this->_getTable($path, false); $primary = $table ? (array)$table->getPrimaryKey() : ['id']; return (new Collection($values))->extract($primary[0])->toArray(); } /** * Fetch the entity or data value for a given path * * This method will traverse the given path and find the entity * or array value for a given path. * * If you only want the terminal Entity for a path use `leafEntity` instead. * * @param array|null $path Each one of the parts in a path for a field name * or null to get the entity passed in constructor context. * @return \Cake\Datasource\EntityInterface|iterable|null * @throws \RuntimeException When properties cannot be read. */ public function entity(?array $path = null) { if ($path === null) { return $this->_context['entity']; } $oneElement = count($path) === 1; if ($oneElement && $this->_isCollection) { return null; } $entity = $this->_context['entity']; if ($oneElement) { return $entity; } if ($path[0] === $this->_rootName) { $path = array_slice($path, 1); } $len = count($path); $last = $len - 1; for ($i = 0; $i < $len; $i++) { $prop = $path[$i]; $next = $this->_getProp($entity, $prop); $isLast = ($i === $last); if (!$isLast && $next === null && $prop !== '_ids') { $table = $this->_getTable($path); if ($table) { return $table->newEmptyEntity(); } } $isTraversable = ( is_iterable($next) || $next instanceof EntityInterface ); if ($isLast || !$isTraversable) { return $entity; } $entity = $next; } throw new RuntimeException(sprintf( 'Unable to fetch property "%s"', implode('.', $path) )); } /** * Fetch the terminal or leaf entity for the given path. * * Traverse the path until an entity cannot be found. Lists containing * entities will be traversed if the first element contains an entity. * Otherwise the containing Entity will be assumed to be the terminal one. * * @param array|null $path Each one of the parts in a path for a field name * or null to get the entity passed in constructor context. * @return array Containing the found entity, and remaining un-matched path. * @throws \RuntimeException When properties cannot be read. */ protected function leafEntity($path = null) { if ($path === null) { return $this->_context['entity']; } $oneElement = count($path) === 1; if ($oneElement && $this->_isCollection) { throw new RuntimeException(sprintf( 'Unable to fetch property "%s"', implode('.', $path) )); } $entity = $this->_context['entity']; if ($oneElement) { return [$entity, $path]; } if ($path[0] === $this->_rootName) { $path = array_slice($path, 1); } $len = count($path); $leafEntity = $entity; for ($i = 0; $i < $len; $i++) { $prop = $path[$i]; $next = $this->_getProp($entity, $prop); // Did not dig into an entity, return the current one. if (is_array($entity) && !($next instanceof EntityInterface || $next instanceof Traversable)) { return [$leafEntity, array_slice($path, $i - 1)]; } if ($next instanceof EntityInterface) { $leafEntity = $next; } // If we are at the end of traversable elements // return the last entity found. $isTraversable = ( is_array($next) || $next instanceof Traversable || $next instanceof EntityInterface ); if (!$isTraversable) { return [$leafEntity, array_slice($path, $i)]; } $entity = $next; } throw new RuntimeException(sprintf( 'Unable to fetch property "%s"', implode('.', $path) )); } /** * Read property values or traverse arrays/iterators. * * @param mixed $target The entity/array/collection to fetch $field from. * @param string $field The next field to fetch. * @return mixed */ protected function _getProp($target, $field) { if (is_array($target) && isset($target[$field])) { return $target[$field]; } if ($target instanceof EntityInterface) { return $target->get($field); } if ($target instanceof Traversable) { foreach ($target as $i => $val) { if ((string)$i === $field) { return $val; } } return false; } } /** * Check if a field should be marked as required. * * @param string $field The dot separated path to the field you want to check. * @return bool|null */ public function isRequired(string $field): ?bool { $parts = explode('.', $field); $entity = $this->entity($parts); $isNew = true; if ($entity instanceof EntityInterface) { $isNew = $entity->isNew(); } $validator = $this->_getValidator($parts); $fieldName = array_pop($parts); if (!$validator->hasField($fieldName)) { return null; } if ($this->type($field) !== 'boolean') { return !$validator->isEmptyAllowed($fieldName, $isNew); } return false; } /** * @inheritDoc */ public function getRequiredMessage(string $field): ?string { $parts = explode('.', $field); $validator = $this->_getValidator($parts); $fieldName = array_pop($parts); if (!$validator->hasField($fieldName)) { return null; } $ruleset = $validator->field($fieldName); if (!$ruleset->isEmptyAllowed()) { return $validator->getNotEmptyMessage($fieldName); } return null; } /** * Get field length from validation * * @param string $field The dot separated path to the field you want to check. * @return int|null */ public function getMaxLength(string $field): ?int { $parts = explode('.', $field); $validator = $this->_getValidator($parts); $fieldName = array_pop($parts); if ($validator->hasField($fieldName)) { foreach ($validator->field($fieldName)->rules() as $rule) { if ($rule->get('rule') === 'maxLength') { return $rule->get('pass')[0]; } } } $attributes = $this->attributes($field); if (!empty($attributes['length'])) { return (int)$attributes['length']; } return null; } /** * Get the field names from the top level entity. * * If the context is for an array of entities, the 0th index will be used. * * @return string[] Array of field names in the table/entity. */ public function fieldNames(): array { $table = $this->_getTable('0'); if (!$table) { return []; } return $table->getSchema()->columns(); } /** * Get the validator associated to an entity based on naming * conventions. * * @param array $parts Each one of the parts in a path for a field name * @return \Cake\Validation\Validator * @throws \RuntimeException If validator cannot be retrieved based on the parts. */ protected function _getValidator(array $parts): Validator { $keyParts = array_filter(array_slice($parts, 0, -1), function ($part) { return !is_numeric($part); }); $key = implode('.', $keyParts); $entity = $this->entity($parts) ?: null; if (isset($this->_validator[$key])) { /** @psalm-suppress PossiblyInvalidArgument */ $this->_validator[$key]->setProvider('entity', $entity); return $this->_validator[$key]; } $table = $this->_getTable($parts); if (!$table) { throw new RuntimeException('Validator not found: ' . $key); } $alias = $table->getAlias(); $method = 'default'; if (is_string($this->_context['validator'])) { $method = $this->_context['validator']; } elseif (isset($this->_context['validator'][$alias])) { $method = $this->_context['validator'][$alias]; } $validator = $table->getValidator($method); /** @psalm-suppress PossiblyInvalidArgument */ $validator->setProvider('entity', $entity); return $this->_validator[$key] = $validator; } /** * Get the table instance from a property path * * @param string[]|string|\Cake\Datasource\EntityInterface $parts Each one of the parts in a path for a field name * @param bool $fallback Whether or not to fallback to the last found table * when a non-existent field/property is being encountered. * @return \Cake\ORM\Table|null Table instance or null */ protected function _getTable($parts, $fallback = true): ?Table { if (!is_array($parts) || count($parts) === 1) { return $this->_tables[$this->_rootName]; } $normalized = array_slice(array_filter($parts, function ($part) { return !is_numeric($part); }), 0, -1); $path = implode('.', $normalized); if (isset($this->_tables[$path])) { return $this->_tables[$path]; } if (current($normalized) === $this->_rootName) { $normalized = array_slice($normalized, 1); } $table = $this->_tables[$this->_rootName]; $assoc = null; foreach ($normalized as $part) { if ($part === '_joinData') { if ($assoc !== null) { $table = $assoc->junction(); $assoc = null; continue; } } else { $associationCollection = $table->associations(); $assoc = $associationCollection->getByProperty($part); } if ($assoc === null) { if ($fallback) { break; } return null; } $table = $assoc->getTarget(); } return $this->_tables[$path] = $table; } /** * Get the abstract field type for a given field name. * * @param string $field A dot separated path to get a schema type for. * @return string|null An abstract data type or null. * @see \Cake\Database\TypeFactory */ public function type(string $field): ?string { $parts = explode('.', $field); $table = $this->_getTable($parts); if (!$table) { return null; } return $table->getSchema()->baseColumnType(array_pop($parts)); } /** * Get an associative array of other attributes for a field name. * * @param string $field A dot separated path to get additional data on. * @return array An array of data describing the additional attributes on a field. */ public function attributes(string $field): array { $parts = explode('.', $field); $table = $this->_getTable($parts); if (!$table) { return []; } $column = (array)$table->getSchema()->getColumn(array_pop($parts)); $allowed = ['length' => null, 'precision' => null]; return array_intersect_key($column, $allowed); } /** * Check whether or not a field has an error attached to it * * @param string $field A dot separated path to check errors on. * @return bool Returns true if the errors for the field are not empty. */ public function hasError(string $field): bool { return $this->error($field) !== []; } /** * Get the errors for a given field * * @param string $field A dot separated path to check errors on. * @return array An array of errors. */ public function error(string $field): array { $parts = explode('.', $field); try { [$entity, $remainingParts] = $this->leafEntity($parts); } catch (RuntimeException $e) { return []; } if (count($remainingParts) === 0) { return $entity->getErrors(); } if ($entity instanceof EntityInterface) { $error = $entity->getError(implode('.', $remainingParts)); if ($error) { return $error; } return $entity->getError(array_pop($parts)); } return []; } }