/** * @param IControlConfig $controlConfig * @return string */ public function getLabelFor(IControlConfig $controlConfig) { $label = $this->format; $fieldName = $controlConfig->getFieldName(); $className = $controlConfig->getParentClassName(); if (Nette\Utils\Strings::contains($fieldName, DotNotation\ClassMetadataWrapper::FIELD_SEPARATOR)) { $classMetadata = $this->classMetadataFactory->getMetadataFor($className); $parts = explode(DotNotation\ClassMetadataWrapper::FIELD_SEPARATOR, $fieldName); $fieldName = array_pop($parts); $association = implode(DotNotation\ClassMetadataWrapper::FIELD_SEPARATOR, $parts); $className = $classMetadata->getAssociationTargetClass($association); } $classParts = explode('\\', $className); $classParts = array_map(function ($value) { return lcfirst($value); }, $classParts); // Convert \NameSpace1\NameSpace2\ClassName to nameSpace1.nameSpace2.className $fullQualifiedClassName = trim(implode('.', $classParts), '.'); // Convert \NameSpace1\NameSpace2\ClassName to className $shortClassName = end($classParts); $label = str_replace(self::FIELD_NAME, $fieldName, $label); $label = str_replace(self::CLASS_NAME, $shortClassName, $label); $label = str_replace(self::FULL_QUALIFIED_CLASS_NAME, $fullQualifiedClassName, $label); return $label; }
/** * @param object $object * @param Container $container * @param array|NULL $controls * @param array|NULL $groups * @throws InvalidStateException */ public function validateContainer($object, Container $container, array $controls = NULL, array $groups = NULL) { if ($object === NULL) { return; } $metadata = $this->classMetadataFactory->getMetadataFor(get_class($object)); $parentContainer = $container; if ($groups === NULL) { while (TRUE) { if ($parentContainer instanceof IOptions) { $groups = $parentContainer->getOption(ContainerBuilder::VALIDATION_GROUPS_OPTION); break; } $parentContainer = $parentContainer->getParent(); if (!$parentContainer) { break; } } } $violations = $this->validator->validate($object, NULL, $groups); $this->mapViolationsToContainer($container, $violations, $controls); // Validate toOne subContainers foreach ($container->getComponents(FALSE, 'NForms\\ToOneContainer') as $subContainer) { /** @var ToOneContainer $subContainer */ $fieldPath = $subContainer->getOption(IObjectMapper::FIELD_NAME, $subContainer->getName()); if (!$metadata->hasAssociation($fieldPath)) { continue; } if (!$metadata->isSingleValuedAssociation($fieldPath)) { throw new InvalidStateException("ToMany association '{$metadata->getClass()}#{$fieldPath}' found but container is toOne."); } if ($metadata->hasField($fieldPath)) { $this->validateContainer($metadata->getFieldValue($object, $fieldPath), $subContainer, $controls); } elseif ($metadata->hasAssociation($fieldPath)) { $this->validateContainer($metadata->getAssociationValue($object, $fieldPath), $subContainer, $controls); } } // Validate toMany subContainers foreach ($container->getComponents(FALSE, 'NForms\\ToManyContainer') as $subContainer) { /** @var ToManyContainer $subContainer */ $fieldPath = $subContainer->getOption(IObjectMapper::FIELD_NAME, $subContainer->getName()); if (!$metadata->hasAssociation($fieldPath)) { continue; } if ($metadata->isSingleValuedAssociation($fieldPath)) { throw new InvalidStateException("ToOne association '{$metadata->getClass()}#{$fieldPath}' found but container is toMany."); } $collection = $metadata->getAssociationValue($object, $fieldPath); $containers = $subContainer->getComponents(FALSE, 'NForms\\ToOneContainer'); foreach ($containers as $key => $toOneContainer) { /** @var ToOneContainer $toOneContainer */ $this->validateContainer($collection[$key], $toOneContainer, $controls); } if ($metadata->hasField($fieldPath)) { $this->validateContainer($metadata->getFieldValue($object, $fieldPath), $subContainer, $controls); } } }
/** * @param string $name * @return array|object */ public function getConstraintsForField($name) { $constraintsMetadata = $this->constraintsMetadata; $className = $constraintsMetadata->getClass(); while (count($parts = explode('.', $name, 2)) > 1) { $classMetadata = $this->classMetadataFactory->getMetadataFor($className); $className = $classMetadata->getAssociationTargetClass($parts[0]); $constraintsMetadata = $this->constraintsMetadataFactory->getMetadataFor($className); $name = $parts[1]; } return $constraintsMetadata->getConstraintsForField($name); }
/** * @param ChoiceControl|MultiChoiceControl $control * @param IControlConfig $config * @param NULL|array $items * @return NULL|array * @throws \NForms\Exceptions\InvalidArgumentException * @throws \NForms\Exceptions\UnexpectedTypeException */ public function processItems($control, IControlConfig $config, $items = NULL) { // Check type if (!$control instanceof ChoiceControl && !$control instanceof MultiChoiceControl) { throw new UnexpectedTypeException("Control has to be ChoiceControl or MultiChoiceControl."); } // Get items if not set if ($items === NULL) { if (($callback = $config->getOption(IControlConfig::ITEMS_CALLBACK)) !== NULL) { if (!is_callable($callback)) { throw new InvalidArgumentException("Invalid items callback."); } $items = call_user_func($callback, $control); if (!is_array($items)) { throw new UnexpectedTypeException("Result of items callback has to be array."); } } elseif ($items = $config->getOption(IControlConfig::ITEMS)) { $items = $config->getOption(IControlConfig::ITEMS); } } if (($targetClass = $config->getTargetClass()) !== NULL) { $relatedMetadata = $this->classMetadataFactory->getMetadataFor($targetClass); $itemTitle = $config->getOption(IControlConfig::ITEM_TITLE); foreach ($items as $title => $item) { if (is_object($item)) { if (!is_a($item, $targetClass)) { throw new UnexpectedTypeException("Expected {$targetClass}, given " . get_class($item)); } unset($items[$title]); if ($itemTitle) { if (is_callable($itemTitle)) { $title = call_user_func($itemTitle, $item); } else { //$title = $relatedMetadata->getFieldValue($item, $itemTitle); $title = $item->{$itemTitle}; } } $items[$relatedMetadata->getId($item)] = $title; } } } if (is_array($items)) { foreach ($items as $key => $value) { if (is_int($key)) { unset($items[$key]); $items[$value] = $value; } } } return $items; }
/** * @param string $fieldName * @throws MetadataException * @return IClassMetadata */ public function getRelatedMetadata($fieldName) { if (!$this->hasAssociation($fieldName)) { throw new MetadataException("Association '{$fieldName}' not found in class '{$this->getClass()}'."); } $class = $this->getAssociationTargetClass($fieldName); return $this->classMetadataFactory->getMetadataFor($class); }
/** * @throws \NForms\Exceptions\InvalidStateException * @return IClassMetadata */ private function getClassMetadata() { if (!$this->_classMetadata) { if (!$this->targetClass) { throw new InvalidStateException("Please, set container className."); } $this->_classMetadata = $this->classMetadataFactory->getMetadataFor($this->targetClass); } return $this->_classMetadata; }
/** * Get sub metadata, field name and sub object from dot notated field name * @param object $object * @param string $originalFieldName * @return array * @throws \NForms\Exceptions\InvalidArgumentException */ private function getSubMetadataAndObject($object, $originalFieldName) { $fieldName = $originalFieldName; $metadata = $this->classMetadata; while (count($parts = explode(self::FIELD_SEPARATOR, $fieldName, 2)) > 1) { if (!$metadata->isSingleValuedAssociation($parts[0])) { throw new InvalidArgumentException("Dot notated field name '{$originalFieldName}' can't go through toMany '{$parts['0']}' association."); } $object = $metadata->getAssociationValue($object, $parts[0]); $association = $metadata->getAssociationTargetClass($parts[0]); $metadata = $this->classMetadataFactory->getMetadataFor($association); $fieldName = $parts[1]; } return array($object, $metadata, $fieldName); }
/** * @param \Nette\Forms\Container|\NForms\IContainer $container * @param $object * @throws \NForms\Exceptions\InvalidStateException * @throws \NForms\Exceptions\InvalidArgumentException * @throws \NForms\Exceptions\UnexpectedTypeException * @return \NForms\Metadata\IClassMetadata */ private function getMetadata(Container $container, $object) { if (!is_object($object)) { throw new InvalidArgumentException("Expected object, given '" . gettype($object) . "'"); } if ($container instanceof IContainer) { if ($container->getClassName() === NULL) { throw new InvalidStateException("Container '{$container->getName()}' has no class."); } if (!is_a($object, $container->getClassName())) { throw new UnexpectedTypeException("Class mismatch. Container is for '{$container->getClassName()}' class, but object is '" . get_class($object) . "'."); } $className = $container->getClassName(); } else { $className = get_class($object); } return $this->metadataFactory->getMetadataFor($className); }
/** * @param string $className * @return IClassMetadata */ public function getMetadataFor($className) { return new ClassMetadataWrapper($this->metadataFactory, $this->metadataFactory->getMetadataFor($className)); }