PageRenderTime 50ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/Classes/TYPO3/FLOW3/Command/ConfigurationCommandController.php

https://github.com/christianjul/FLOW3-Composer
PHP | 239 lines | 142 code | 25 blank | 72 comment | 29 complexity | 0569a8cda8f11a5d0dc5b64e57e348e7 MD5 | raw file
Possible License(s): BSD-3-Clause, LGPL-3.0
  1. <?php
  2. namespace TYPO3\FLOW3\Command;
  3. /* *
  4. * This script belongs to the FLOW3 framework. *
  5. * *
  6. * It is free software; you can redistribute it and/or modify it under *
  7. * the terms of the GNU Lesser General Public License, either version 3 *
  8. * of the License, or (at your option) any later version. *
  9. * *
  10. * The TYPO3 project - inspiring people to share! *
  11. * */
  12. use TYPO3\FLOW3\Annotations as FLOW3;
  13. /**
  14. * Configuration command controller for the TYPO3.FLOW3 package
  15. *
  16. * @FLOW3\Scope("singleton")
  17. */
  18. class ConfigurationCommandController extends \TYPO3\FLOW3\Cli\CommandController {
  19. /**
  20. * @FLOW3\Inject
  21. * @var \TYPO3\FLOW3\Package\PackageManagerInterface
  22. */
  23. protected $packageManager;
  24. /**
  25. * @FLOW3\Inject
  26. * @var \TYPO3\FLOW3\Configuration\ConfigurationManager
  27. */
  28. protected $configurationManager;
  29. /**
  30. * @FLOW3\Inject
  31. * @var \TYPO3\FLOW3\Utility\SchemaValidator
  32. */
  33. protected $schemaValidator;
  34. /**
  35. * @FLOW3\Inject
  36. * @var \TYPO3\FLOW3\Utility\SchemaGenerator
  37. */
  38. protected $schemaGenerator;
  39. /**
  40. * Show the active configuration settings
  41. *
  42. * The command shows the configuration of the current context as it is used by FLOW3 itself.
  43. * You can specify the configuration type and path if you want to show parts of the configuration.
  44. *
  45. * ./flow3 configuration:show --type Settings --path TYPO3.FLOW3.persistence
  46. *
  47. * @param string $type Configuration type to show
  48. * @param string $path path to subconfiguration separated by "." like "TYPO3.FLOW3"
  49. * @return void
  50. */
  51. public function showCommand($type = NULL, $path = NULL) {
  52. $availableConfigurationTypes = $this->configurationManager->getAvailableConfigurationTypes();
  53. if (in_array($type, $availableConfigurationTypes)) {
  54. $configuration = $this->configurationManager->getConfiguration($type);
  55. if ($path !== NULL) {
  56. $configuration = \TYPO3\FLOW3\Utility\Arrays::getValueByPath($configuration, $path);
  57. }
  58. $typeAndPath = $type . ($path ? ': ' . $path : '');
  59. if ($configuration === NULL) {
  60. $this->outputLine('<b>Configuration "%s" was empty!</b>', array($typeAndPath));
  61. } else {
  62. $yaml = \Symfony\Component\Yaml\Yaml::dump($configuration, 99);
  63. $this->outputLine('<b>Configuration "%s":</b>', array($typeAndPath));
  64. $this->outputLine();
  65. $this->outputLine($yaml . chr(10));
  66. }
  67. } else {
  68. if ($type !== NULL) {
  69. $this->outputLine('<b>Configuration type "%s" was not found!</b>', array($type));
  70. }
  71. $this->outputLine('<b>Available configuration types:</b>');
  72. foreach ($availableConfigurationTypes as $availableConfigurationType) {
  73. $this->outputLine(' ' . $availableConfigurationType);
  74. }
  75. $this->outputLine();
  76. $this->outputLine('Hint: <b>%s configuration:show --type <configurationType></b>', array($this->getFlow3InvocationString()));
  77. $this->outputLine(' shows the configuration of the specified type.');
  78. }
  79. }
  80. /**
  81. * Validate the given configuration
  82. *
  83. * ./flow3 configuration:validate --type Settings --path TYPO3.FLOW3.persistence
  84. *
  85. * The schemas are searched in the path "Resources/Private/Schema" of all
  86. * active Packages. The schema-filenames must match the pattern
  87. * __type__.__path__.schema.yaml. The type and/or the path can also be
  88. * expressed as subdirectories of Resources/Private/Schema. So
  89. * Settings/TYPO3/FLOW3.persistence.schema.yaml will match the same pathes
  90. * like Settings.TYPO3.FLOW3.persistence.schema.yaml or
  91. * Settings/TYPO3.FLOW3/persistence.schema.yaml
  92. *
  93. * @param string $type Configuration type to validate
  94. * @param string $path path to the subconfiguration separated by "." like "TYPO3.FLOW3"
  95. * @return void
  96. */
  97. public function validateCommand($type = NULL, $path = NULL) {
  98. $availableConfigurationTypes = $this->configurationManager->getAvailableConfigurationTypes();
  99. if (in_array($type, $availableConfigurationTypes) === FALSE) {
  100. if ($type !== NULL) {
  101. $this->outputLine('<b>Configuration type "%s" was not found!</b>', array($type));
  102. $this->outputLine();
  103. }
  104. $this->outputLine('<b>Available configuration types:</b>');
  105. foreach ($availableConfigurationTypes as $availableConfigurationType) {
  106. $this->outputLine(' ' . $availableConfigurationType);
  107. }
  108. $this->outputLine();
  109. $this->outputLine('Hint: <b>%s configuration:validate --type <configurationType></b>', array($this->getFlow3InvocationString()));
  110. $this->outputLine(' validates the configuration of the specified type.');
  111. return;
  112. }
  113. $configuration = $this->configurationManager->getConfiguration($type);
  114. $this->outputLine('<b>Validating configuration for type: "' . $type . '"' . (($path !== NULL) ? ' and path: "' . $path . '"': '') . '</b>');
  115. // find schema files for the given type and path
  116. $schemaFileInfos = array();
  117. $activePackages = $this->packageManager->getActivePackages();
  118. foreach ($activePackages as $package) {
  119. $packageKey = $package->getPackageKey();
  120. $packageSchemaPath = \TYPO3\FLOW3\Utility\Files::concatenatePaths(array($package->getResourcesPath(), 'Private/Schema'));
  121. if (is_dir($packageSchemaPath)) {
  122. $packageSchemaFiles = \TYPO3\FLOW3\Utility\Files::readDirectoryRecursively($packageSchemaPath, '.schema.yaml');
  123. foreach ($packageSchemaFiles as $schemaFile) {
  124. $schemaName = substr($schemaFile, strlen($packageSchemaPath) + 1, -strlen('.schema.yaml'));
  125. $schemaNameParts = explode('.', str_replace('/', '.' ,$schemaName), 2);
  126. $schemaType = $schemaNameParts[0];
  127. $schemaPath = isset($schemaNameParts[1]) ? $schemaNameParts[1] : NULL;
  128. if ($schemaType === $type && ($path === NULL || strpos($schemaPath, $path) === 0)){
  129. $schemaFileInfos[] = array(
  130. 'file' => $schemaFile,
  131. 'name' => $schemaName,
  132. 'path' => $schemaPath,
  133. 'packageKey' => $packageKey
  134. );
  135. }
  136. }
  137. }
  138. }
  139. $this->outputLine();
  140. if (count($schemaFileInfos) > 0) {
  141. $this->outputLine('%s schema files were found:', array(count($schemaFileInfos)));
  142. $result = new \TYPO3\FLOW3\Error\Result();
  143. foreach ($schemaFileInfos as $schemaFileInfo) {
  144. if ($schemaFileInfo['path'] !== NULL) {
  145. $data = \TYPO3\FLOW3\Utility\Arrays::getValueByPath($configuration, $schemaFileInfo['path']);
  146. } else {
  147. $data = $configuration;
  148. }
  149. if (empty($data)){
  150. $result->forProperty($schemaFileInfo['path'])->addError(new \TYPO3\FLOW3\Error\Error('configuration in path ' . $schemaFileInfo['path'] . ' is empty'));
  151. $this->outputLine(' - package: "' . $schemaFileInfo['packageKey'] . '" schema: "' . $schemaFileInfo['name'] . '" -> <b>configuration is empty</b>');
  152. } else {
  153. $parsedSchema = \Symfony\Component\Yaml\Yaml::parse($schemaFileInfo['file']);
  154. $schemaResult = $this->schemaValidator->validate($data, $parsedSchema);
  155. if ($schemaResult->hasErrors()) {
  156. $this->outputLine(' - package:"' . $schemaFileInfo['packageKey'] . '" schema:"' . $schemaFileInfo['name'] . '" -> <b>' . count($schemaResult->getFlattenedErrors()) . ' errors</b>');
  157. } else {
  158. $this->outputLine(' - package:"' . $schemaFileInfo['packageKey'] . '" schema:"' . $schemaFileInfo['name'] . '" -> <b>is valid</b>');
  159. }
  160. if ($schemaFileInfo['path'] !== NULL) {
  161. $result->forProperty($schemaFileInfo['path'])->merge($schemaResult);
  162. } else {
  163. $result->merge($schemaResult);
  164. }
  165. }
  166. }
  167. } else {
  168. $this->outputLine('No matching schema-files were found!');
  169. return;
  170. }
  171. $this->outputLine();
  172. if ($result->hasErrors()) {
  173. $errors = $result->getFlattenedErrors();
  174. $this->outputLine('<b>%s errors were found:</b>', array(count($errors)));
  175. foreach ($errors as $path => $pathErrors){
  176. foreach ($pathErrors as $error){
  177. $this->outputLine(' - %s -> %s', array($path, $error->render()));
  178. }
  179. }
  180. } else {
  181. $this->outputLine('<b>The configuration is valid!</b>');
  182. }
  183. }
  184. /**
  185. * Generate a schema for the given configuration or YAML file.
  186. *
  187. * ./flow3 configuration:generateschema --type Settings --path TYPO3.FLOW3.persistence
  188. *
  189. * The schema will be output to standard output.
  190. *
  191. * @param string $type Configuration type to create a schema for
  192. * @param string $path path to the subconfiguration separated by "." like "TYPO3.FLOW3"
  193. * @param string $yaml YAML file to create a schema for
  194. * @return void
  195. */
  196. public function generateSchemaCommand($type = NULL, $path = NULL, $yaml = NULL) {
  197. $data = NULL;
  198. if ($yaml !== NULL && is_file($yaml) && is_readable($yaml)) {
  199. $data = \Symfony\Component\Yaml\Yaml::parse($yaml);
  200. } elseif ($type !== NULL) {
  201. $data = $this->configurationManager->getConfiguration($type);
  202. if ($path !== NULL){
  203. $data = \TYPO3\FLOW3\Utility\Arrays::getValueByPath($data, $path);
  204. }
  205. }
  206. if (empty($data)){
  207. $this->outputLine('Data was not found or is empty');
  208. return;
  209. }
  210. $yaml = \Symfony\Component\Yaml\Yaml::dump($this->schemaGenerator->generate($data), 99);
  211. $this->output($yaml . chr(10));
  212. }
  213. }
  214. ?>