Example #1
0
 /**
  * @test
  */
 public function mergeShouldMergeTwoResults()
 {
     $notice1 = $this->getMockMessage('Notice');
     $notice2 = $this->getMockMessage('Notice');
     $notice3 = $this->getMockMessage('Notice');
     $warning1 = $this->getMockMessage('Warning');
     $warning2 = $this->getMockMessage('Warning');
     $warning3 = $this->getMockMessage('Warning');
     $error1 = $this->getMockMessage('Error');
     $error2 = $this->getMockMessage('Error');
     $error3 = $this->getMockMessage('Error');
     $otherResult = new Result();
     $otherResult->addNotice($notice1);
     $otherResult->forProperty('foo.bar')->addNotice($notice2);
     $this->result->forProperty('foo')->addNotice($notice3);
     $otherResult->addWarning($warning1);
     $this->result->addWarning($warning2);
     $this->result->addWarning($warning3);
     $otherResult->forProperty('foo')->addError($error1);
     $otherResult->forProperty('foo')->addError($error2);
     $otherResult->addError($error3);
     $this->result->merge($otherResult);
     $this->assertSame([$notice1], $this->result->getNotices(), 'Notices are not merged correctly without recursion');
     $this->assertSame([$notice3], $this->result->forProperty('foo')->getNotices(), 'Original sub-notices are overridden.');
     $this->assertSame([$notice2], $this->result->forProperty('foo')->forProperty('bar')->getNotices(), 'Sub-notices are not copied.');
     $this->assertSame([$warning2, $warning3, $warning1], $this->result->getWarnings());
     $this->assertSame([$error3], $this->result->getErrors());
     $this->assertSame([$error1, $error2], $this->result->forProperty('foo')->getErrors());
 }
 /**
  * Checks if the given value is valid according to the property validators.
  *
  * @param mixed $object The value that should be validated
  * @return void
  * @api
  */
 protected function isValid($object)
 {
     $messages = new ErrorResult();
     foreach ($this->propertyValidators as $propertyName => $validators) {
         $propertyValue = $this->getPropertyValue($object, $propertyName);
         $result = $this->checkProperty($propertyValue, $validators);
         if ($result !== null) {
             $messages->forProperty($propertyName)->merge($result);
         }
     }
     $this->result = $messages;
 }
 /**
  * Internal function which actually does the property mapping.
  *
  * @param mixed $source the source data to map. MUST be a simple type, NO object allowed!
  * @param string $targetType The type of the target; can be either a class name or a simple type.
  * @param PropertyMappingConfigurationInterface $configuration Configuration for the property mapping.
  * @param array $currentPropertyPath The property path currently being mapped; used for knowing the context in case an exception is thrown.
  * @return mixed an instance of $targetType
  * @throws Exception\TypeConverterException
  * @throws Exception\InvalidPropertyMappingConfigurationException
  */
 protected function doMapping($source, $targetType, PropertyMappingConfigurationInterface $configuration, &$currentPropertyPath)
 {
     if (is_object($source)) {
         $targetClass = TypeHandling::truncateElementType($targetType);
         if ($source instanceof $targetClass) {
             return $source;
         }
     }
     if ($source === null) {
         $source = '';
     }
     $typeConverter = $this->findTypeConverter($source, $targetType, $configuration);
     $targetType = $typeConverter->getTargetTypeForSource($source, $targetType, $configuration);
     if (!is_object($typeConverter) || !$typeConverter instanceof TypeConverterInterface) {
         throw new Exception\TypeConverterException('Type converter for "' . $source . '" -> "' . $targetType . '" not found.');
     }
     $convertedChildProperties = [];
     foreach ($typeConverter->getSourceChildPropertiesToBeConverted($source) as $sourcePropertyName => $sourcePropertyValue) {
         $targetPropertyName = $configuration->getTargetPropertyName($sourcePropertyName);
         if ($configuration->shouldSkip($targetPropertyName)) {
             continue;
         }
         if (!$configuration->shouldMap($targetPropertyName)) {
             if ($configuration->shouldSkipUnknownProperties()) {
                 continue;
             }
             throw new Exception\InvalidPropertyMappingConfigurationException('It is not allowed to map property "' . $targetPropertyName . '". You need to use $propertyMappingConfiguration->allowProperties(\'' . $targetPropertyName . '\') to enable mapping of this property.', 1335969887);
         }
         $targetPropertyType = $typeConverter->getTypeOfChildProperty($targetType, $targetPropertyName, $configuration);
         $subConfiguration = $configuration->getConfigurationFor($targetPropertyName);
         $currentPropertyPath[] = $targetPropertyName;
         $targetPropertyValue = $this->doMapping($sourcePropertyValue, $targetPropertyType, $subConfiguration, $currentPropertyPath);
         array_pop($currentPropertyPath);
         if (!$targetPropertyValue instanceof Error) {
             $convertedChildProperties[$targetPropertyName] = $targetPropertyValue;
         }
     }
     $result = $typeConverter->convertFrom($source, $targetType, $convertedChildProperties, $configuration);
     if ($result instanceof Error) {
         $this->messages->forProperty(implode('.', $currentPropertyPath))->addError($result);
     }
     return $result;
 }
 /**
  * Get all property mapping / validation errors
  *
  * @return Result
  */
 public function getValidationResults()
 {
     $results = new Result();
     foreach ($this as $argument) {
         $argumentValidationResults = $argument->getValidationResults();
         if ($argumentValidationResults === null) {
             continue;
         }
         $results->forProperty($argument->getName())->merge($argumentValidationResults);
     }
     return $results;
 }
 /**
  * Validate a single configuration type
  *
  * @param string $configurationType the configuration typr to validate
  * @param string $path configuration path to validate, or NULL.
  * @param array $loadedSchemaFiles will be filled with a list of loaded schema files
  * @return \Neos\Error\Messages\Result
  * @throws Exception\SchemaValidationException
  */
 protected function validateSingleType($configurationType, $path, &$loadedSchemaFiles)
 {
     $availableConfigurationTypes = $this->configurationManager->getAvailableConfigurationTypes();
     if (in_array($configurationType, $availableConfigurationTypes) === false) {
         throw new Exception\SchemaValidationException('The configuration type "' . $configurationType . '" was not found. Only the following configuration types are supported: "' . implode('", "', $availableConfigurationTypes) . '"', 1364984886);
     }
     $configuration = $this->configurationManager->getConfiguration($configurationType);
     // find schema files for the given type and path
     $schemaFileInfos = [];
     $activePackages = $this->packageManager->getActivePackages();
     foreach ($activePackages as $package) {
         $packageKey = $package->getPackageKey();
         $packageSchemaPath = Files::concatenatePaths([$package->getResourcesPath(), 'Private/Schema']);
         if (is_dir($packageSchemaPath)) {
             foreach (Files::getRecursiveDirectoryGenerator($packageSchemaPath, '.schema.yaml') as $schemaFile) {
                 $schemaName = substr($schemaFile, strlen($packageSchemaPath) + 1, -strlen('.schema.yaml'));
                 $schemaNameParts = explode('.', str_replace('/', '.', $schemaName), 2);
                 $schemaType = $schemaNameParts[0];
                 $schemaPath = isset($schemaNameParts[1]) ? $schemaNameParts[1] : null;
                 if ($schemaType === $configurationType && ($path === null || strpos($schemaPath, $path) === 0)) {
                     $schemaFileInfos[] = ['file' => $schemaFile, 'name' => $schemaName, 'path' => $schemaPath, 'packageKey' => $packageKey];
                 }
             }
         }
     }
     if (count($schemaFileInfos) === 0) {
         throw new Exception\SchemaValidationException('No schema files found for configuration type "' . $configurationType . '"' . ($path !== null ? ' and path "' . $path . '".' : '.'), 1364985056);
     }
     $result = new Result();
     foreach ($schemaFileInfos as $schemaFileInfo) {
         $loadedSchemaFiles[] = $schemaFileInfo['file'];
         if ($schemaFileInfo['path'] !== null) {
             $data = Arrays::getValueByPath($configuration, $schemaFileInfo['path']);
         } else {
             $data = $configuration;
         }
         if (empty($data)) {
             $result->addNotice(new Notice('No configuration found, skipping schema "%s".', 1364985445, [substr($schemaFileInfo['file'], strlen(FLOW_PATH_ROOT))]));
         } else {
             $parsedSchema = Yaml::parse($schemaFileInfo['file']);
             $validationResultForSingleSchema = $this->schemaValidator->validate($data, $parsedSchema);
             if ($schemaFileInfo['path'] !== null) {
                 $result->forProperty($schemaFileInfo['path'])->merge($validationResultForSingleSchema);
             } else {
                 $result->merge($validationResultForSingleSchema);
             }
         }
     }
     return $result;
 }
Example #6
0
 /**
  * Validate a dictionary value with the given schema
  *
  * The following properties are handled in given $schema:
  * - properties : array of keys and schemas that have to validate
  * - formatProperties : dictionary of schemas, the schemas are used to validate all keys that match the string-format
  * - patternProperties : dictionary of schemas, the schemas are used to validate all keys that match the string-pattern
  * - additionalProperties : if FALSE is given all additionalProperties are forbidden, if a schema is given all additional properties have to match the schema
  *
  * @param mixed $value
  * @param array $schema
  * @return ErrorResult
  */
 protected function validateDictionaryType($value, array $schema)
 {
     $result = new ErrorResult();
     if (is_array($value) === false || $this->isDictionary($value) === false) {
         $result->addError($this->createError('type=dictionary', 'type=' . gettype($value)));
         return $result;
     }
     $propertyKeysToHandle = array_keys($value);
     if (isset($schema['properties'])) {
         foreach ($schema['properties'] as $propertyName => $propertySchema) {
             if (array_key_exists($propertyName, $value)) {
                 $propertyValue = $value[$propertyName];
                 $subresult = $this->validate($propertyValue, $propertySchema);
                 if ($subresult->hasErrors()) {
                     $result->forProperty($propertyName)->merge($subresult);
                 }
                 $propertyKeysToHandle = array_diff($propertyKeysToHandle, [$propertyName]);
             } else {
                 // is subproperty required
                 if (is_array($propertySchema) && $this->isSchema($propertySchema) && isset($propertySchema['required']) && $propertySchema['required'] === true) {
                     $result->addError($this->createError('Property ' . $propertyName . ' is required'));
                 }
             }
         }
     }
     if (isset($schema['patternProperties']) && count($propertyKeysToHandle) > 0 && $this->isDictionary($schema['patternProperties'])) {
         foreach (array_values($propertyKeysToHandle) as $propertyKey) {
             foreach ($schema['patternProperties'] as $propertyPattern => $propertySchema) {
                 $keyResult = $this->validateStringType($propertyKey, ['pattern' => $propertyPattern]);
                 if ($keyResult->hasErrors() === false) {
                     $subresult = $this->validate($value[$propertyKey], $propertySchema);
                     if ($subresult->hasErrors()) {
                         $result->forProperty($propertyKey)->merge($subresult);
                     }
                     $propertyKeysToHandle = array_diff($propertyKeysToHandle, [$propertyKey]);
                 }
             }
         }
     }
     if (isset($schema['formatProperties']) && count($propertyKeysToHandle) > 0 && $this->isDictionary($schema['formatProperties'])) {
         foreach (array_values($propertyKeysToHandle) as $propertyKey) {
             foreach ($schema['formatProperties'] as $propertyPattern => $propertySchema) {
                 $keyResult = $this->validateStringType($propertyKey, ['format' => $propertyPattern]);
                 if ($keyResult->hasErrors() === false) {
                     $subresult = $this->validate($value[$propertyKey], $propertySchema);
                     if ($subresult->hasErrors()) {
                         $result->forProperty($propertyKey)->merge($subresult);
                     }
                     $propertyKeysToHandle = array_diff($propertyKeysToHandle, [$propertyKey]);
                 }
             }
         }
     }
     if (isset($schema['additionalProperties']) && $schema['additionalProperties'] !== true && count($propertyKeysToHandle) > 0) {
         if ($schema['additionalProperties'] === false) {
             foreach ($propertyKeysToHandle as $propertyKey) {
                 $result->forProperty($propertyKey)->addError($this->createError('This property is not allowed here, check the spelling if you think it belongs here.'));
             }
         } else {
             foreach ($propertyKeysToHandle as $propertyKey) {
                 $subresult = $this->validate($value[$propertyKey], $schema['additionalProperties']);
                 if ($subresult->hasErrors()) {
                     $result->forProperty($propertyKey)->merge($subresult);
                 }
             }
         }
     }
     return $result;
 }