From e61d9aee511c56cf9c7942ed8f44d7a807b7846f Mon Sep 17 00:00:00 2001 From: JAC - Frederic Bauer Date: Thu, 17 Dec 2020 10:10:57 +0100 Subject: [PATCH] Commit regarding issues #3 , #5 and #6 (this commit is meant to improve the config path determination, the documentation and the adherence to Symfony's coding guidelines). Markdown: - CHANGELOG-3.x.md: Added the new improvement introduced by this commit. PHP: - ConfigPathUtility.php 1. Improved config path retrieval: This was done in order catch more configuration files especially of the bundles, this new way is now less reliant on the strict adherence to Symfony's recommended bundle structure. 2. Refactored the code to adhere more closely to Symfony's recommended coding style. - CustomContainerBuilder.php: 1. Added and refactored documentation for functions and methods within the Container Builder in order to improve readability of the class and its methods. - CustomDelegatingLoader.php: Also small refactorings to the documentation for improved readability. - CustomGlobLoader.php: Same as before, more small refactorings to the documentation for better readability. - CustomValueStorage.php: Refactorings of the code and the documentation to be more inline with the Symfony coding guidelines and also to improve readability. - LoadInitializer.php: Added and refactored documentation for more readability and clarity on the class. - LocationAwareParameterBag.php: Added documentation and refactored the existing code to be more inline with the aforementioned guidelines and for more clarity on the class and its methods. - LocationRetrievalCoordinator.php: Also added and refactored the existing documentation with the same thinking as before. - Utility.php: Added documentation on every function and the class and also refactored the functions a bit, for more information on the class and its methods. --- Resources/doc/changelogs/CHANGELOG-3.x.md | 4 + .../ConfigPathUtility.php | 41 ++++--- .../CustomContainerBuilder.php | 41 ++++++- .../CustomDelegatingLoader.php | 5 +- .../CustomGlobLoader.php | 2 + .../CustomValueStorage.php | 41 +++++-- .../LoadInitializer.php | 30 +++-- .../LocationAwareParameterBag.php | 17 ++- .../LocationRetrievalCoordinator.php | 84 ++++++++----- src/Utility/Utility.php | 112 ++++++++++++++---- 10 files changed, 274 insertions(+), 103 deletions(-) diff --git a/Resources/doc/changelogs/CHANGELOG-3.x.md b/Resources/doc/changelogs/CHANGELOG-3.x.md index 24541e8..1f4b12b 100644 --- a/Resources/doc/changelogs/CHANGELOG-3.x.md +++ b/Resources/doc/changelogs/CHANGELOG-3.x.md @@ -10,6 +10,10 @@ * Fixed an issue with synchronous scrolling, where when the first node of a list was unique to said list, the synchronous scrolling would throw an error and never complete +* Improved config path retrieval: Now the process is able to find configuration files more effectively + and easily and should be aware of every used file for configuration except for the custom bundle config + which is conducted by the bundles themselves. + ## 3.0 (11.12.2020) * This changelog has been created to ship with the first full version of the bundle diff --git a/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php b/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php index ab0944a..7b1dc94 100644 --- a/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php +++ b/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php @@ -71,9 +71,7 @@ public static function initializePathUtility(): void // Parse the manual path_config-file self::getUserDefinedPaths(); - } catch (InvalidArgumentException $e) { - self::$configPaths = []; - } catch (Exception $error) { + } catch (InvalidArgumentException | Exception $e) { self::$configPaths = []; } } @@ -90,25 +88,27 @@ public static function initializePathUtility(): void * @param string $extensionPath The path pointing to a bundle's ExtensionClass. * @return string|null Returns the converted string or null, if the path does not point to the DependencyInjection or a directory which does not exist. */ - public static function convertExtensionPathToConfigDirectory(string $extensionPath) { - // Get the index in the string where "DependencyInjection" is present - $diPosition = strpos($extensionPath,"DependencyInjection"); + public static function convertExtensionPathToConfigDirectory(string $extensionPath): ?string + { + $configDirPath = preg_match("/\.php$/",$extensionPath)? dirname($extensionPath) : $extensionPath; - if(!$diPosition) { - return null; + if (preg_match("/\/$/", $configDirPath)) { + $configDirPath = substr($configDirPath,0,strlen($configDirPath)-1); } - // Change it from DependencyInjection to the config directory - $configDirPath = substr($extensionPath,0,$diPosition)."Resources/config/"; + while (!preg_match("/.*\/vendor\/?$/", $configDirPath)) { + if (file_exists($configDirPath.DIRECTORY_SEPARATOR."Resources".DIRECTORY_SEPARATOR."config")) { + $configDirPath = $configDirPath.DIRECTORY_SEPARATOR."Resources".DIRECTORY_SEPARATOR."config".DIRECTORY_SEPARATOR; + break; + } else if (file_exists($configDirPath.DIRECTORY_SEPARATOR."config")) { + $configDirPath = $configDirPath.DIRECTORY_SEPARATOR."config".DIRECTORY_SEPARATOR; + break; + } - if (!file_exists($configDirPath)) { - return null; + $configDirPath = dirname($configDirPath); } - // Since the entire directory is added as a glob resource, the "*" signals that all files within the directory are - // to be looked at (only one level deep) and the extensions signal that only files which end on one of the config - // extensions are considered. - return $configDirPath."*".self::$configExtensions; + return preg_match("/\/$/", $configDirPath)? $configDirPath."*".self::$configExtensions : null; } /** @@ -118,7 +118,8 @@ public static function convertExtensionPathToConfigDirectory(string $extensionPa * @param string $configPath The path to be added to the list. * @param bool $isGlobPattern A boolean stating whether the path is a glob-resource / pattern which will have to be loaded differently from non-glob-pattern. */ - public static function addPathToPathlist(string $configPath, bool $isGlobPattern = true): void { + public static function addPathToPathlist(string $configPath, bool $isGlobPattern = true): void + { // If the cache has not been initialised, initialise it. if (!self::$cacheInitialized) { self::initializePathUtility(); @@ -137,7 +138,8 @@ public static function addPathToPathlist(string $configPath, bool $isGlobPattern * *
Also signals, that a restart of the load process is useful / necessary. */ - public static function storePaths(): void { + public static function storePaths(): void + { if (self::$cacheInitialized && self::$pathsChanged) { try { self::$configPathCache->delete("cjw_config_paths"); @@ -234,7 +236,8 @@ private static function getUserDefinedPaths(): void * @param array $path A path array (hopefully with 3 items under the keys of "path", "glob" and "addConfExt"). * @return bool Boolean which states whether the path at least passes the most basic checks regarding their structure. */ - private static function checkUserDefinedPath(array $path): bool { + private static function checkUserDefinedPath(array $path): bool + { if (is_array($path) && count($path) === 3) { if (!(key_exists("path",$path) && is_string($path["path"]) && !empty($path["path"]))) { return false; diff --git a/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php b/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php index ab4dc86..951aa3a 100644 --- a/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php +++ b/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php @@ -6,6 +6,7 @@ use Exception; use ReflectionClass; +use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; @@ -33,14 +34,22 @@ public function __construct() * * @param string $location The location to be set. */ - public function setCurrentLocation(string $location) { - + public function setCurrentLocation(string $location) + { /** The parameterBag is the custom one created to feature such a function */ $this->parameterBag->setCurrentLocation($location); } /** * @override + * In order to be able to actively influence the way locations are read for parameters during the bundle configuration + * process, the compilation of the container is caught through this function and then, after the measures for the + * bundle configuration are set in place, the normal compilation process of the container takes place. + * + *
This was done in order to prevent the bundles from constantly adding the same parameters unchanged back into + * the container, which led to dozens of useless entries into the location lists for every parameter. + * + * @param bool $resolveEnvPlaceholders */ public function compile(bool $resolveEnvPlaceholders = false) { @@ -61,6 +70,7 @@ public function compile(bool $resolveEnvPlaceholders = false) * config directories to be tracked. * * @param string $name The name of the bundle who's extension config to retrieve. + * * @return array Returns the found configuration. */ public function getExtensionConfig(string $name) @@ -90,6 +100,8 @@ public function getExtensionConfig(string $name) * @override * This override ensures, that no definition of a service will be added while loading the config files of the bundles * outside of the bundle configuration phase. + * + * @param array $definitions */ public function addDefinitions(array $definitions) { @@ -102,8 +114,13 @@ public function addDefinitions(array $definitions) * @override * This override ensures, that no service will be registered while loading the config files of the bundles * outside of the bundle configuration phase. + * + * @param string $id + * @param string|null $class + * + * @return Definition|null */ - public function register(string $id, string $class = null) + public function register(string $id, string $class = null): ?Definition { if (!$this->isBundleConfigMode) { return parent::register($id, $class); // TODO: Change the autogenerated stub @@ -116,8 +133,13 @@ public function register(string $id, string $class = null) * @override * This override ensures, that no service definition will be added while loading the config files of the bundles * outside of the bundle configuration phase. + * + * @param string $id + * @param Definition $definition + * + * @return Definition|null */ - public function setDefinition(string $id, Definition $definition) + public function setDefinition(string $id, Definition $definition): ?Definition { if (!$this->isBundleConfigMode) { return parent::setDefinition($id, $definition); // TODO: Change the autogenerated stub @@ -130,11 +152,16 @@ public function setDefinition(string $id, Definition $definition) * @override * This override ensures, that no service alias will be set while loading the config files of the bundles * outside of the bundle configuration phase. + * + * @param string $alias + * @param $id + * + * @return string|Alias|null */ public function setAlias(string $alias, $id) { if (!$this->isBundleConfigMode) { - return parent::setAlias($alias, $id); // TODO: Change the autogenerated stub + return parent::setAlias($alias, $id); } return null; @@ -144,11 +171,13 @@ public function setAlias(string $alias, $id) * @override * This override ensures, that no service definition will be registered while loading the config files of the bundles * outside of the bundle configuration phase. + * + * @param array $definitions */ public function setDefinitions(array $definitions) { if (!$this->isBundleConfigMode) { - parent::setDefinitions($definitions); // TODO: Change the autogenerated stub + parent::setDefinitions($definitions); } } diff --git a/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php b/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php index 4f1a945..27526ba 100644 --- a/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php +++ b/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php @@ -4,6 +4,7 @@ namespace CJW\CJWConfigProcessor\src\LocationAwareConfigLoadBundle; +use Exception; use Symfony\Component\Config\Loader\DelegatingLoader; use Symfony\Component\Config\Loader\LoaderResolverInterface; @@ -32,9 +33,11 @@ public function __construct(LoaderResolverInterface $resolver, CustomContainerBu * @override * This override ensures that everytime a resource is loaded (which is not a global pattern) the path to said resource is set * in and known by the container. + * * @param $resource * @param string|null $type - * @throws \Exception + * + * @throws Exception */ public function load($resource, string $type = null) { diff --git a/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php b/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php index ab7788e..bad28d9 100644 --- a/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php +++ b/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php @@ -38,8 +38,10 @@ public function __construct(CustomContainerBuilder $container, FileLocatorInterf * This override is basically a copy of the {@see GlobLoader} load function just with one key difference: * It tracks the paths gathered by GlobResources and always relays that path before the loading process * of the parameters and services begins. + * * @param $resource * @param string|null $type + * * @throws FileLoaderImportCircularReferenceException * @throws LoaderLoadException */ diff --git a/src/LocationAwareConfigLoadBundle/CustomValueStorage.php b/src/LocationAwareConfigLoadBundle/CustomValueStorage.php index 6ad1d43..faff2db 100644 --- a/src/LocationAwareConfigLoadBundle/CustomValueStorage.php +++ b/src/LocationAwareConfigLoadBundle/CustomValueStorage.php @@ -14,16 +14,24 @@ class CustomValueStorage { - /** @var array This is an array of all locations that have been encountered during the loading process. */ + /** + * @var array This is an array of all locations that have been encountered during the loading process. + */ private static $encounteredLocations = []; - /** @var array An array of all parameters being loaded by the config loading process and the values accompanied by the paths they stem from. */ + /** + * @var array An array of all parameters being loaded by the config loading process and the values accompanied by the paths they stem from. + */ private static $parameterAndTheirLocations = []; - /** @var bool States whether new parameter values or paths can be added to the internal arrays or not. */ + /** + * @var bool States whether new parameter values or paths can be added to the internal arrays or not. + */ private static $allowWrite = true; - /** @var bool States whether the bundle config loading process has begun. */ + /** + * @var bool States whether the bundle config loading process has begun. + */ private static $bundleConfig = false; /** @@ -41,7 +49,8 @@ class CustomValueStorage * @param mixed $value The value attached to both the parametername and then the given path as well. It is going to be added under path-key as an entry of the array. * @param string $path The path (the origin) of the parameter value that is being set. It serves as a key under the parameter-key of the array. */ - public static function addParameterOrLocation(string $parameterName, $value, string $path) { + public static function addParameterOrLocation(string $parameterName, $value, string $path): void + { // Only if it is currently allowed to write, will the process even begin if (self::$allowWrite) { if (!in_array($path, self::$encounteredLocations)) { @@ -66,7 +75,8 @@ public static function addParameterOrLocation(string $parameterName, $value, str * It simply sets an internal boolean which then prohibits any parameters or paths / values to be set. * In order to unlock the writing process, use {@see unlockParameters()}. */ - public static function lockParameters() { + public static function lockParameters(): void + { self::$allowWrite = false; } @@ -75,7 +85,8 @@ public static function lockParameters() { * to the internal parameter-and-path storage. It sets the internal boolean to a different value * than {@see lockParameters()}. */ - public static function unlockParameters() { + public static function unlockParameters(): void + { self::$allowWrite = true; } @@ -91,7 +102,8 @@ public static function unlockParameters() { * * @param bool $activate A boolean stating that the mode is either to be active (true) or not (false). */ - public static function activateBundleConfigMode(bool $activate) { + public static function activateBundleConfigMode(bool $activate): void + { self::$bundleConfig = $activate; } @@ -100,7 +112,8 @@ public static function activateBundleConfigMode(bool $activate) { * bundleConfigMode and the lock-status of the class internally. This serves to allow a "fresh" start with the internal * storage. */ - public static function reset(): void { + public static function reset(): void + { self::$parameterAndTheirLocations = []; self::$bundleConfig = false; self::$allowWrite = true; @@ -112,7 +125,8 @@ public static function reset(): void { * * @return array Returns an array of parameters as super-keys, the locations as sub-keys and the values found at the paths as entries. */ - public static function getParametersAndTheirLocations() { + public static function getParametersAndTheirLocations(): array + { ksort(self::$parameterAndTheirLocations,SORT_STRING); return self::$parameterAndTheirLocations; } @@ -123,7 +137,8 @@ public static function getParametersAndTheirLocations() { * * @return array Returns an array which is filled with all encountered locations during the configuration-loading-process. */ - public static function getEncounteredLocations() { + public static function getEncounteredLocations(): array + { return self::$encounteredLocations; } @@ -131,9 +146,11 @@ public static function getEncounteredLocations() { * Allows a specific parameter to be retrieved from the internal storage of the class. * * @param string $parameterName The name of the parameter as string. + * * @return array|null Returns the internal array with `$path => $value` pairs or null if the parameter is not present in the internal array. */ - public static function getLocationsForSpecificParameter(string $parameterName) { + public static function getLocationsForSpecificParameter(string $parameterName): ?array + { // Only if that parameter exists as a key in the array, will that parameters paths and values be returned, otherwise null return isset(self::$parameterAndTheirLocations[$parameterName]) ? self::$parameterAndTheirLocations[$parameterName] : null; diff --git a/src/LocationAwareConfigLoadBundle/LoadInitializer.php b/src/LocationAwareConfigLoadBundle/LoadInitializer.php index 9b18cdf..b4a1bc6 100644 --- a/src/LocationAwareConfigLoadBundle/LoadInitializer.php +++ b/src/LocationAwareConfigLoadBundle/LoadInitializer.php @@ -27,6 +27,9 @@ */ class LoadInitializer extends Kernel { + /** + * @var Kernel An instance of the actual Symfony kernel handling all the requests (to ensure the correct paths are used). + */ private $kernel; public function __construct(string $environment, bool $debug) @@ -64,7 +67,7 @@ public function __construct(string $environment, bool $debug) * * @return string Returns the determined cache directory. */ - public function getCacheDir() + public function getCacheDir(): string { if ($this->kernel) { return $this->kernel->getCacheDir(); @@ -93,7 +96,7 @@ public function getCacheDir() * * @return string Returns the determined project directory. */ - public function getProjectDir() + public function getProjectDir(): string { if ($this->kernel) { return $this->kernel->getProjectDir(); @@ -115,10 +118,12 @@ public function getProjectDir() * @override * Overrides the standard function of the kernel in order to ensure, that the right CustomContainerBuilder and CustomLoaders * are being used for the config loading process. + * * @param ContainerInterface $container + * * @return CustomDelegatingLoader */ - protected function getContainerLoader(ContainerInterface $container) + protected function getContainerLoader(ContainerInterface $container): CustomDelegatingLoader { $locator = new FileLocator($this); /** @var CustomContainerBuilder $container */ @@ -139,7 +144,7 @@ protected function getContainerLoader(ContainerInterface $container) * @override * Overrides the standard function of the kernel in order to ensure, that the kernel works with the CustomContainerBuilder. */ - protected function getContainerBuilder() + protected function getContainerBuilder(): CustomContainerBuilder { $originalContainerBuilder = parent::getContainerBuilder(); $customContainerBuilder = new CustomContainerBuilder(); @@ -147,10 +152,16 @@ protected function getContainerBuilder() return $customContainerBuilder; } - protected function configureContainer( - ContainerBuilder $container, - LoaderInterface $loader - ): void { + /** + * @override + * Overrides the standard kernel functionality to ensure that the paths retrieved in the previous boot attempt + * of this custom kernel are used too, to retrieve the desired parameter paths. + * + * @param ContainerBuilder $container + * @param LoaderInterface $loader + */ + protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void + { parent::configureContainer($container, $loader); // After the original Symfony-Loading of specific routes, the custom routes, added in the configuration, are being parsed through @@ -176,7 +187,8 @@ protected function configureContainer( *
* It is employed to allow a reboot to occur during the loading process (in order to take newly found config-paths into account). */ - private function cleanUpCache() { + private function cleanUpCache(): void + { $glob = glob($this->getCacheDir()."/*"); foreach ($glob as $file) { diff --git a/src/LocationAwareConfigLoadBundle/LocationAwareParameterBag.php b/src/LocationAwareConfigLoadBundle/LocationAwareParameterBag.php index b0f5f46..f532078 100644 --- a/src/LocationAwareConfigLoadBundle/LocationAwareParameterBag.php +++ b/src/LocationAwareConfigLoadBundle/LocationAwareParameterBag.php @@ -5,12 +5,20 @@ use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; -//use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +/** + * Class LocationAwareParameterBag is a custom parameter bag which is designed to keep track of the resources being + * loaded into the container and this bag. It is reliant on information it receives from other classes of the load + * process higher up in the chain to keep its path information up to date. + * + * @package CJW\CJWConfigProcessor\src\LocationAwareConfigLoadBundle + */ class LocationAwareParameterBag extends EnvPlaceholderParameterBag { - /** @var string Stores the current location that is being loaded */ + /** + * @var string Stores the current location that is being loaded. + */ private $currentLocation; public function __construct(array $parameters = []) @@ -29,7 +37,8 @@ public function __construct(array $parameters = []) * * @param string $location The path / file that is being loaded. */ - public function setCurrentLocation(string $location) { + public function setCurrentLocation(string $location): void + { $this->currentLocation = $location; } @@ -42,7 +51,7 @@ public function setCurrentLocation(string $location) { * @param string $name The name of the parameter. * @param mixed $value The value being set to the parameter. */ - public function set(string $name, $value) + public function set(string $name, $value): void { // Give the parameter, the value and the current location CustomValueStorage::addParameterOrLocation($name,$value,$this->currentLocation); diff --git a/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php b/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php index c941135..a7da293 100644 --- a/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php +++ b/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php @@ -9,26 +9,42 @@ use Symfony\Component\Cache\Exception\CacheException; use Symfony\Contracts\Cache\ItemInterface; +/** + * Class LocationRetrievalCoordinator is the instigator of the entire location retrieval process and responsible for + * creating and using both the custom kernel and helper classes to determine, keep track of and store the locations + * of and for every determined parameter. + * + * @package CJW\CJWConfigProcessor\src\LocationAwareConfigLoadBundle + */ class LocationRetrievalCoordinator { - /** @var LoadInitializer A custom kernel that initiates the entire custom loading process. */ + /** + * @var LoadInitializer A custom kernel that initiates the entire custom loading process. + */ private static $customConfigLoader; - /** @var array An array which not only stores the parameters, but also the paths they have been read from (including the values set there) */ + /** + * @var array An array which not only stores the parameters, but also the paths they have been read from (including the values set there) + */ public static $parametersAndLocations; - /** @var PhpFilesAdapter A cache which is supposed to store the parameters that have been parsed. */ + /** + * @var PhpFilesAdapter A cache which is supposed to store the parameters that have been parsed. + */ private static $cache; - /** @var bool */ + /** + * @var bool + */ private static $initialized = false; /** * "Initiates" the class and sets all missing and non-instantiated attributes of the class prior to the rest * of its functions being called. */ - public static function initializeCoordinator(): void { + public static function initializeCoordinator(): void + { if (!self::$customConfigLoader) { self::$customConfigLoader = new LoadInitializer($_SERVER["APP_ENV"], (bool)$_SERVER["APP_DEBUG"]); } @@ -51,10 +67,8 @@ public static function initializeCoordinator(): void { try { // If parameters are returned (meaning that the kernel has booted and thus new parameters could have entered), delete the parameters present // also delete the processed parameters based on the previous parameters - if ( - is_array(self::$parametersAndLocations) && - count(self::$parametersAndLocations) > 0 - ) { + if (is_array(self::$parametersAndLocations) && count(self::$parametersAndLocations) > 0) + { self::$cache->delete("cjw_parameters_and_locations"); self::$cache->delete("cjw_processed_param_objects"); self::$cache->delete("cjw_processed_params"); @@ -75,7 +89,9 @@ public static function initializeCoordinator(): void { } /** - * @return array + * Retrieves all parameters and the associated locations which have been retrieved by the class. + * + * @return array An associative array, which contains the parameters as first keys, then the different paths and the values that have been set in those files. */ public static function getParametersAndLocations(): array { @@ -86,11 +102,19 @@ public static function getParametersAndLocations(): array return self::$parametersAndLocations; } - public static function getParameterLocations ( - string $parameterName, - array $siteAccessGroups = null, - bool $withSiteAccess = false - ) { + /** + * This functionality allows to retrieve all locations specific to one parameter given to the function. This can + * be done in a site access context too, where all site access versions of the given parameter will be looked at + * as well. + * + * @param string $parameterName The name of the parameter who's locations should be retrieved. + * @param array|null $siteAccessGroups An array of the site access groups that exist in the current installation (required to determine site access groups versions of the parameter). + * @param bool $withSiteAccess A boolean which states whether the parameter should be viewed in a site access context. Set to true, all site access versions of the given parameter are looked at. + * + * @return array|null An array of locations for the parameter of null if nothing could be found. + */ + public static function getParameterLocations (string $parameterName, array $siteAccessGroups = null, bool $withSiteAccess = false): ?array + { if (!self::$initialized) { self::initializeCoordinator(); } @@ -102,16 +126,14 @@ public static function getParameterLocations ( * Returns the internal array which keeps track of all encountered locations without any connection to * the parameters, values or other information. It resembles a plain "stack" of locations. * - * @param string $parameterName - * @param array|null $siteAccessGroups - * @param bool $withSiteAccess + * @param string $parameterName The name of the parameter who's locations should be retrieved. + * @param array|null $siteAccessGroups An array of the site access groups that exist in the current installation (required to determine site access groups versions of the parameter). + * @param bool $withSiteAccess A boolean which states whether the parameter should be viewed in a site access context. Set to true, all site access versions of the given parameter are looked at. + * * @return array Returns an array which is filled with all encountered locations during the configuration-loading-process. */ - private static function getLocationsForSpecificParameter ( - string $parameterName, - array $siteAccessGroups = null, - bool $withSiteAccess = false - ) { + private static function getLocationsForSpecificParameter (string $parameterName, array $siteAccessGroups = null, bool $withSiteAccess = false): ?array + { $parameterKeySegments = explode(".", $parameterName); if (is_array($parameterKeySegments) && count($parameterKeySegments) > 1) { @@ -187,10 +209,18 @@ private static function getLocationsForSpecificParameter ( } } - private static function getLocationsFromRewrittenSiteAccessParameter( - string $newSiteAccess, - array $originalParameterKeySegments - ) { + /** + * This function takes the original parameter name which has been split up by the "." (dots) and a given site access + * by which to look at it and creates a new parameter name through the given parts. Afterwards it checks for whether + * locations exist for that specific parameter. + * + * @param string $newSiteAccess The site access with which to construct the parameter name. + * @param array $originalParameterKeySegments An array of all segments of the parameter key. + * + * @return array Returns an array which includes the found locations for the new parameter or an empty one if nothing could be found. + */ + private static function getLocationsFromRewrittenSiteAccessParameter(string $newSiteAccess, array $originalParameterKeySegments): array + { if ($originalParameterKeySegments[1] !== $newSiteAccess) { $originalParameterKeySegments[1] = $newSiteAccess; diff --git a/src/Utility/Utility.php b/src/Utility/Utility.php index 1ce3c6b..5733b00 100644 --- a/src/Utility/Utility.php +++ b/src/Utility/Utility.php @@ -6,14 +6,30 @@ use Exception; +/** + * Class Utility is, as the name implies, a class which is responsible for delivering utility functionality that can + * be employed (mostly without any conditions) in other classes. + * + * @package CJW\CJWConfigProcessor\src\Utility + */ class Utility { - public static function removeUncommonParameters ( - array $firstParameterList, - array $secondParameterList, - int $level = 0 - ) { + /** + * Responsible for removing uncommon parameters between two given hierarchical, associative arrays of parameters. + * It is designed to work with site access versions of the parameters, which means that the parameters typically + * don't go deeper then two levels. + * + * @param array $firstParameterList The first list of parameters to check against the second. + * @param array $secondParameterList The second list of parameters to check against the first. + * @param int $level The (optional) amount of levels the comparison has gone to in the two arrays. + * + * @return array[] A multi dimensional array, which contains the first and second parameter lists with only the common parameters. + * + * @see removeCommonParameters For a similar function which does the opposite. + */ + public static function removeUncommonParameters (array $firstParameterList, array $secondParameterList, int $level = 0): array + { $firstListKeys = array_keys($firstParameterList); $secondListKeys = array_keys($secondParameterList); @@ -48,11 +64,21 @@ public static function removeUncommonParameters ( return [$firstParameterList,$secondParameterList]; } - public static function removeCommonParameters ( - array $firstParameterList, - array $secondParameterList, - int $level = 0 - ) { + /** + * Responsible for removing common parameters between two given hierarchical, associative arrays of parameters. + * It is designed to work with site access versions of the parameters, which means that the parameters typically + * don't go deeper then two levels. + * + * @param array $firstParameterList The first list of parameters to check against the second. + * @param array $secondParameterList The second list of parameters to check against the first. + * @param int $level The (optional) amount of levels the comparison has gone to in the two arrays. + * + * @return array[] A multi dimensional array, which contains the first and second parameter lists with only the uncommon parameters. + * + * @see removeUncommonParameters For a similar function which does the opposite. + */ + public static function removeCommonParameters (array $firstParameterList, array $secondParameterList, int $level = 0): array + { $firstListKeys = array_keys($firstParameterList); $secondListKeys = array_keys($secondParameterList); @@ -87,12 +113,15 @@ public static function removeCommonParameters ( /** * Taken off StackOverflow from + * * @author Captain kurO * @url https://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential/4254008#4254008 + * * @param array $array + * * @return bool */ - public static function has_string_keys(array $array) + public static function has_string_keys(array $array): bool { return count( array_filter( @@ -102,9 +131,16 @@ public static function has_string_keys(array $array) ) > 0; } - public static function determinePureSiteAccesses( - array $processedParameterArray - ): array { + /** + * Determines and then returns the defined "pure" site accesses of your installation through a given list of the + * application configuration. Pure in this case means, that site access groups are not included in that list. + * + * @param array $processedParameterArray An associative, hierarchical array of parameters to search for the site accesses. + * + * @return string[] Returns an array of site accesses in the form of strings. + */ + public static function determinePureSiteAccesses(array $processedParameterArray): array + { try { $results = $processedParameterArray["ezpublish"]["siteaccess"]["list"]["parameter_value"]; @@ -116,9 +152,16 @@ public static function determinePureSiteAccesses( } } - public static function determinePureSiteAccessGroups ( - array $processedParameterArray - ): array { + /** + * Determines and then returns the defined site access groups of your installation through a given list of the + * application configuration. Pure in this case means, that the site accesses are not included in that list. + * + * @param array $processedParameterArray An associative, hierarchical array of parameters to search for the site accesses. + * + * @return array Returns an array of the found site access groups (empty if non are found). + */ + public static function determinePureSiteAccessGroups (array $processedParameterArray): array + { try { return $processedParameterArray["ezpublish"]["siteaccess"]["groups"]["parameter_value"]; } catch (Exception $error) { @@ -126,10 +169,20 @@ public static function determinePureSiteAccessGroups ( } } - public static function removeEntryThroughKeyList ( - array $parameters, - array $keyList - ): array { + /** + * Takes a given list of hierarchical key segments and also an associative array of parameters and aims to delete + * the key at the very bottom of the key list from the parameters array. + * + *
For example: Giving only one key segment / key in the list will remove that key from the very first level of + * the associative parameters array. + * + * @param array $parameters An associative array of parameters from which to delete the given key. + * @param array $keyList A list of keys that will be gone through to the very last given segment, which is then going to be deleted from the given parameters array. + * + * @return array Returns the remaining array of parameters, after the key segment has been deleted. + */ + public static function removeEntryThroughKeyList (array $parameters, array $keyList): array + { $key = reset($keyList); array_splice($keyList,0,1); @@ -150,10 +203,19 @@ public static function removeEntryThroughKeyList ( return $parameters; } - public static function removeSpecificKeySegment ( - string $keySegment, - array $parametersToRemoveFrom - ) { + /** + * Similar to {@see removeEntryThroughKeyList}, aims to remove a specific key from an associative array of parameters. + * In contrast to the above mentioned function, this one takes only one specific key and goes through the entire + * array until the key is found, while the other function goes through the given list of segments and only these + * segments and then deletes the key if it exists. + * + * @param string $keySegment The specific key to be removed from the given array. + * @param array $parametersToRemoveFrom An associative array of parameters from which to remove the given key, if it exists. + * + * @return array Returns the resulting array of parameters, after the key segment has been deleted (unchanged from the given array, if the key could not be found). + */ + public static function removeSpecificKeySegment (string $keySegment, array $parametersToRemoveFrom): array + { $result = $parametersToRemoveFrom; foreach ($parametersToRemoveFrom as $key => $value) {