diff --git a/Controller/ConfigProcessController.php b/Controller/ConfigProcessController.php index b3156c8..bd0dc14 100644 --- a/Controller/ConfigProcessController.php +++ b/Controller/ConfigProcessController.php @@ -21,15 +21,27 @@ use Symfony\Component\HttpFoundation\ResponseHeaderBag; use Symfony\Component\HttpKernel\Exception\HttpException; +/** + * Class ConfigProcessController is the main controller of the bundle and responsible for bringing the + * processed configuration into the frontend. + * + * @package CJW\CJWConfigProcessor\Controller + */ class ConfigProcessController extends AbstractController { + /** + * @var bool Not of much use at the moment. + */ private $showFavouritesOutsideDedicatedView; - public function __construct ( - ContainerInterface $symContainer, - ConfigResolverInterface $ezConfigResolver, - RequestStack $symRequestStack - ) + /** + * ConfigProcessController constructor. + * + * @param ContainerInterface $symContainer + * @param ConfigResolverInterface $ezConfigResolver + * @param RequestStack $symRequestStack + */ + public function __construct (ContainerInterface $symContainer, ConfigResolverInterface $ezConfigResolver, RequestStack $symRequestStack) { $this->container = $symContainer; ConfigProcessCoordinator::initializeCoordinator($symContainer,$ezConfigResolver,$symRequestStack); @@ -45,7 +57,14 @@ public function __construct ( $this->container->getParameter("cjw.favourite_parameters.display_everywhere"); } - public function getStartPage () { + /** + * Currently unused function to only render the base layout template without any + * processed configuration or additional functionality. + * + * @return Response|null Returns the baselayout template to be rendered or an exception if something went wrong. + */ + public function getStartPage () + { try { ConfigProcessCoordinator::startProcess(); } catch (Exception $e) { @@ -55,7 +74,14 @@ public function getStartPage () { return $this->render("@CJWConfigProcessor/pagelayout.html.twig"); } - public function getParameterList () { + /** + * Responsible for delivering the processed configuration for the frontend. + * Takes the processed configuration and renders it into a template. + * + * @return Response|null Returns a rendered template or delivers an error response in case of an error. + */ + public function getParameterList (): ?Response + { try { $parameters = ConfigProcessCoordinator::getProcessedParameters(); $favourites = $this->showFavouritesOutsideDedicatedView ? @@ -75,7 +101,17 @@ public function getParameterList () { } } - public function getSpecificSAParameters (Request $request, string $siteAccess = null) { + /** + * Responsible for bringing the single view of specific site access parameters into the frontend. + * If not site access context is given to the function, then simply the current site access of the request is used. + * + * @param Request $request The request made to the Symfony server. + * @param string|null $siteAccess The optional site access context, if non is given, then the current one of the request is used. + * + * @return Response|null Returns a rendered template with site access specific parameters. + */ + public function getSpecificSAParameters (Request $request, string $siteAccess = null): Response + { try { $specSAParameters = ConfigProcessCoordinator::getParametersForSiteAccess($siteAccess); $processedParameters = ConfigProcessCoordinator::getProcessedParameters(); @@ -110,17 +146,27 @@ public function getSpecificSAParameters (Request $request, string $siteAccess = ); } - public function compareSiteAccesses ( - string $firstSiteAccess, - string $secondSiteAccess, - string $limiter = null - ) { + /** + * Responsible for providing the site access comparison view to the bundle frontend. + * + * @param string $firstSiteAccess The first site access context for the first list of parameters in the comparison. + * @param string $secondSiteAccess The second site access context for the second list of parameters in the comparison. + * @param string|null $limiter An optional filter for the comparison (can be for common parameters only or uncommon, no filter if nothing is sent). + * + * @return Response|null Returns the rendered comparison template. + * + * @throws Exception Throws an exception if something went wrong during the process. + */ + public function compareSiteAccesses (string $firstSiteAccess, string $secondSiteAccess, string $limiter = null): ?Response + { + // Determine and retrieve the site access configuration for the two site accesses. $processedParameters = ConfigProcessCoordinator::getProcessedParameters(); $resultParameters = $this->retrieveParamsForSiteAccesses($firstSiteAccess,$secondSiteAccess); $resultFavourites = $this->retrieveFavouritesForSiteAccesses($processedParameters,$firstSiteAccess,$secondSiteAccess); $limiterString = "Default Comparison"; + // Filter the results if one is set. if ($limiter === "commons") { $resultParameters = Utility::removeUncommonParameters($resultParameters[0],$resultParameters[1]); $resultFavourites = Utility::removeUncommonParameters($resultFavourites[0],$resultFavourites[1]); @@ -131,6 +177,7 @@ public function compareSiteAccesses ( $limiterString = "Differences Comparison"; } + // Provide the different values to the templates. $firstSiteAccessParameters = $resultParameters[0]; $secondSiteAccessParameters = $resultParameters[1]; @@ -158,6 +205,13 @@ public function compareSiteAccesses ( ); } + /** + * Retrieve the favourite parameters for the dedicated favourites view. + * + * @param string|null $siteAccess The (optional) site access context in which to view the favourite parameters. + * + * @return Response Returns the rendered favourite view template. + */ public function getFavourites (string $siteAccess = null): Response { try { @@ -168,7 +222,7 @@ public function getFavourites (string $siteAccess = null): Response $siteAccesses = Utility::determinePureSiteAccesses($processedParameters); $groups = Utility::determinePureSiteAccessGroups($processedParameters); - $siteAccessesToScanFor = $siteAccess? + $siteAccessesToScanFor = $siteAccess ? ConfigProcessCoordinator::getSiteAccessListForController($siteAccess) : []; $favourites = @@ -185,7 +239,16 @@ public function getFavourites (string $siteAccess = null): Response ); } - public function getFavouriteKeyList (): Response { + /** + * Returns only a list of keys of the parameters that have been marked as favourites. It returns these + * in a json format for further processing in the frontend. + * + *
Example format for the keys: ["favourite.key.one", "favourite.key.second", "third.favourite.key"] + * + * @return Response Returns the list of favourite parameter keys as a flat json array. + */ + public function getFavouriteKeyList (): Response + { try { $processedParameters = ConfigProcessCoordinator::getProcessedParameters(); } catch (Exception $error) { @@ -198,7 +261,18 @@ public function getFavouriteKeyList (): Response { return $this->json($favourites); } - public function saveFavourites(Request $request): Response { + /** + * Allows saving a or multiple parameter keys as favourites in the application based on a sent + * json array of keys. + * + *
Example format for the keys: ["favourite.key.one", "favourite.key.second", "third.favourite.key"] + * + * @param Request $request The request which includes the favourite keys in a json array. + * + * @return Response Returns 200 if no error was encountered with the sent data. + */ + public function saveFavourites(Request $request): Response + { $requestData = $request->getContent(); try { @@ -212,7 +286,18 @@ public function saveFavourites(Request $request): Response { return new Response(null, 200); } - public function removeFavourites (Request $request): Response { + /** + * Allows removing a or multiple parameter keys from the favourites in the application based on a + * sent json array of keys. + * + *
Example format for the keys: ["favourite.key.one", "favourite.key.second", "third.favourite.key"] + * + * @param Request $request The request which includes the keys to be removed as a json array. + * + * @return Response Returns 200 if no error was encountered with the sent data. + */ + public function removeFavourites (Request $request): Response + { $requestData = $request->getContent(); try { @@ -226,26 +311,36 @@ public function removeFavourites (Request $request): Response { return new Response(null, 200); } - public function downloadParameterListAsTextFile(string $downloadDenominator): BinaryFileResponse { + /** + * Allows to determine a specific list of parameters to be brought into a file representation and + * made available for download by the user. + * + * @param string $downloadDescriptor A string which determines which parameters are supposed to be written to + * a file ("all_parameters" = all parameters, "favourites" = only favourites, + * "[site access]" all parameters for that site access). + * + * @return BinaryFileResponse Returns the file which has been created through the selected parameters. + */ + public function downloadParameterListAsTextFile(string $downloadDescriptor): BinaryFileResponse + { try { - if ($downloadDenominator === "all_parameters") { + if ($downloadDescriptor === "all_parameters") { $resultingFile = ParametersToFileWriter::writeParametersToFile( - ConfigProcessCoordinator::getProcessedParameters(), - $downloadDenominator + ConfigProcessCoordinator::getProcessedParameters() ); - } else if ($downloadDenominator === "favourites") { + } else if ($downloadDescriptor === "favourites") { $resultingFile = ParametersToFileWriter::writeParametersToFile( FavouritesParamCoordinator::getFavourites( ConfigProcessCoordinator::getProcessedParameters() ), - $downloadDenominator + $downloadDescriptor ); } else { $resultingFile = ParametersToFileWriter::writeParametersToFile( ConfigProcessCoordinator::getParametersForSiteAccess( - $downloadDenominator + $downloadDescriptor ), - $downloadDenominator + $downloadDescriptor ); } } catch (InvalidArgumentException | Exception $error) { @@ -266,10 +361,19 @@ public function downloadParameterListAsTextFile(string $downloadDenominator): Bi return $response; } - private function retrieveParamsForSiteAccesses ( - string $firstSiteAccess, - string $secondSiteAccess - ) { + /** + * Helper function to determine the specific parameters for both given site access contexts at the same time. + * It returns the found parameters in an array in which the first entry marks all the parameters for the first + * site access and the second every parameter for the second site access. + * + * @param string $firstSiteAccess The first site access for which to retrieve parameters. + * @param string $secondSiteAccess The second site access for which to retrieve parameters. + * + * @return array A two dimensional array of arrays in which the first entry includes the parameters for the first site access + * and the second entry contains the parameters for the second site access. + */ + private function retrieveParamsForSiteAccesses (string $firstSiteAccess, string $secondSiteAccess): array + { $firstSiteAccessParameters = []; $secondSiteAccessParameters = []; @@ -288,11 +392,20 @@ private function retrieveParamsForSiteAccesses ( return [$firstSiteAccessParameters,$secondSiteAccessParameters]; } - private function retrieveFavouritesForSiteAccesses( - array $processedParameters, - string $firstSiteAccess, - string $secondSiteAccess - ) { + /** + * Helper function to determine the favourite parameters for both given site access contexts at the same time. + * It returns the found parameters in an array in which the first entry marks all the parameters for the first + * site access and the second every parameter for the second site access. + * + * @param array $processedParameters The entire processed Symfony configuration to determine the favourite parameters if non had been set yet. + * @param string $firstSiteAccess The first site access for which to retrieve favourites. + * @param string $secondSiteAccess The second site access for which to retrieve favourites. + * + * @return array A two dimensional array of arrays in which the first entry includes the parameters for the first site access + * and the second entry contains the parameters for the second site access. + */ + private function retrieveFavouritesForSiteAccesses(array $processedParameters, string $firstSiteAccess, string $secondSiteAccess): array + { $firstFavourites = []; $secondFavourites = []; diff --git a/Controller/ConfigProcessLocationInfoController.php b/Controller/ConfigProcessLocationInfoController.php index c1ed155..b17d4ed 100644 --- a/Controller/ConfigProcessLocationInfoController.php +++ b/Controller/ConfigProcessLocationInfoController.php @@ -7,12 +7,28 @@ use CJW\CJWConfigProcessor\src\LocationAwareConfigLoadBundle\LocationRetrievalCoordinator; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\JsonResponse; +/** + * Class ConfigProcessLocationInfoController is a controller designed to enable frontend integration with the retrieving + * locations for specific parameters feature. + * + * @package CJW\CJWConfigProcessor\Controller + */ class ConfigProcessLocationInfoController extends AbstractController { + /** + * @var string The directory root of the project. + */ private $projectDir; + /** + * ConfigProcessLocationInfoController constructor. + * + * @param ContainerInterface $symContainer + * @param string $projectDir + */ public function __construct(ContainerInterface $symContainer, string $projectDir) { $this->projectDir = $projectDir; @@ -20,7 +36,18 @@ public function __construct(ContainerInterface $symContainer, string $projectDir LocationRetrievalCoordinator::initializeCoordinator(); } - public function retrieveLocationsForParameter (string $parameter, string $withSiteAccess) { + /** + * Responsible for determining the location info for a given parameter. + * + * @param string $parameter The key to the parameter to retrieve locations for. + * @param string $withSiteAccess String representation of a boolean to determine, whether to view the parameter key + * in a site access context. + * + * @return JsonResponse A json response which includes the paths where the parameter has been found and the values + * attached to these paths (also site access if set to true). + */ + public function retrieveLocationsForParameter (string $parameter, string $withSiteAccess): JsonResponse + { $saPresent = ($withSiteAccess && $withSiteAccess !== "false")?? false; $group = null; diff --git a/DependencyInjection/CJWConfigProcessorExtension.php b/DependencyInjection/CJWConfigProcessorExtension.php index 2523c64..3e8c9cc 100644 --- a/DependencyInjection/CJWConfigProcessorExtension.php +++ b/DependencyInjection/CJWConfigProcessorExtension.php @@ -4,6 +4,7 @@ namespace CJW\CJWConfigProcessor\DependencyInjection; +use Exception; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\DependencyInjection\Extension; use Symfony\Component\DependencyInjection\Loader; @@ -13,6 +14,15 @@ class CJWConfigProcessorExtension extends Extension { + /** + * @override + * Standard Symfony extension loading function. + * + * @param array $configs + * @param ContainerBuilder $container + * + * @throws Exception + */ public function load(array $configs, ContainerBuilder $container) { $loader = new Loader\YamlFileLoader( $container, new FileLocator(__DIR__ . '/../Resources/config') ); @@ -24,7 +34,14 @@ public function load(array $configs, ContainerBuilder $container) $this->handleFavouriteParamConfig($config, $container); } - private function handleCustomParamConfig (array $config, ContainerBuilder $container) { + /** + * Responsible for handling the configuration specifically for the custom parameters feature. + * + * @param array $config The configuration array to be parsed into actual container parameters. + * @param ContainerBuilder $container The container to add the parameters to. + */ + private function handleCustomParamConfig (array $config, ContainerBuilder $container) + { if (!isset($config["custom_site_access_parameters"])) { $allowParameters = false; $scanParameters = false; @@ -38,7 +55,14 @@ private function handleCustomParamConfig (array $config, ContainerBuilder $conta $container->setParameter("cjw.custom_site_access_parameters.scan_parameters", $scanParameters); } - private function handleFavouriteParamConfig (array $config, ContainerBuilder $container) { + /** + * Responsible for handling the configuration specifically for the favourite parameters feature. + * + * @param array $config The configuration array to be parsed into actual container parameters. + * @param ContainerBuilder $container The container to add the parameters to. + */ + private function handleFavouriteParamConfig (array $config, ContainerBuilder $container) + { if (!isset($config["favourite_parameters"])) { $allowParameters = false; $scanParameters = false; diff --git a/EventSubscriber/ConfigProcessingMenuSubscriber.php b/EventSubscriber/ConfigProcessingMenuSubscriber.php index ecdb0c7..77af060 100644 --- a/EventSubscriber/ConfigProcessingMenuSubscriber.php +++ b/EventSubscriber/ConfigProcessingMenuSubscriber.php @@ -7,17 +7,21 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** - * If the autoconfigure option is set to false in the service.yaml, then this Menu-Subscriber would have to be registered separately - * in the yaml as: (under services) (Path to my class): CJW\EventListener\: then tags: then - { name: kernel.event.subscriber } + * Class ConfigProcessingMenuSubscriber is responsible for adding the config processing view as a tab under the + * eZ / Ibexa Platform Backoffice main admin tab list. + * + * @package CJW\CJWConfigProcessor\EventSubscriber */ class ConfigProcessingMenuSubscriber implements EventSubscriberInterface { /** - * Through this function it is possible for me to get the main menu and perform an action as the menu is being build / as it - * has finished building. Thus I am able to inject other menu items. - * @return array|array[] + * @override + * Through this function it is possible to get the main menu and perform an action as the menu is being built / as it + * has finished building. + * + * @return array|array[] Returns an array that states on what event the the menu functionality should be triggered. */ - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ ConfigureMenuEvent::MAIN_MENU => ["onMenuConfigure",0], @@ -25,30 +29,15 @@ public static function getSubscribedEvents() } /** + * @override * This function is being called as soon as the ConfigureMenuEvent regarding the Main Menu has fired / the - * Subscriber has noticed it firing. In this function I am able to not only get the main menu as an object but also to - * influence and actively change the menu. + * Subscriber has noticed it firing. + * * @param ConfigureMenuEvent $event */ public function onMenuConfigure(ConfigureMenuEvent $event) { $menu = $event->getMenu(); -// $menu->addChild( -// "menu_item1", -// [ -// "label" => "CJWConfigProcessor-Bundle-Functions", "extras" => ["icon" => "file"] -// ] -// ); - -// $menu["menu_item1"]->addChild( -// "2nd_level_menu_item", -// [ -// "label" => "Config Processing View", -// "uri" => "/admin/cjw/config-processing", -// "extras" => ["icon" => "article"], -// ] -// ); - if (!isset($menu[MainMenuBuilder::ITEM_ADMIN])) { return; } @@ -61,18 +50,5 @@ public function onMenuConfigure(ConfigureMenuEvent $event) { "extras" => ["icon" => "list"], ] ); - -// $menu["menu_item1"]->addChild( -// "template_test_menu_item", -// [ -// "label" => "Template Test Item", -// "extras" => [ -// "template" => "admin_ui/menu_item_template.html.twig", -// "template_parameters" => [ -// "custom_parameter" => "value", -// ], -// ], -// ], -// ); } } diff --git a/EventSubscriber/LeftSideBarMenuBuilder.php b/EventSubscriber/LeftSideBarMenuBuilder.php index 1dfa80a..17f2974 100644 --- a/EventSubscriber/LeftSideBarMenuBuilder.php +++ b/EventSubscriber/LeftSideBarMenuBuilder.php @@ -12,6 +12,11 @@ use Knp\Menu\ItemInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +/** + * Class LeftSideBarMenuBuilder is used to build the left sidebar menu one can see in the bundle frontend. + * + * @package CJW\CJWConfigProcessor\EventSubscriber + */ class LeftSideBarMenuBuilder extends AbstractBuilder implements TranslationContainerInterface { @@ -20,19 +25,32 @@ class LeftSideBarMenuBuilder extends AbstractBuilder implements TranslationConta const ITEM__PARAMETER_LIST_SITE_ACCESS = 'Site Access Parameters'; const ITEM__PARAMETER_LIST_FAVOURITES = 'Favourite Parameters'; - public function __construct( - MenuItemFactory $factory, - EventDispatcherInterface $eventDispatcher - ) + /** + * LeftSideBarMenuBuilder constructor. + * + * @param MenuItemFactory $factory + * @param EventDispatcherInterface $eventDispatcher + */ + public function __construct(MenuItemFactory $factory, EventDispatcherInterface $eventDispatcher) { parent::__construct($factory, $eventDispatcher); } + /** + * @override + * @return string + */ protected function getConfigureEventName(): string { return ConfigureMenuEvent::CONTENT_SIDEBAR_LEFT; } + /** + * @override + * @param array $options + * + * @return ItemInterface + */ protected function createStructure(array $options): ItemInterface { $menu = $this->factory->createItem("root"); @@ -66,6 +84,10 @@ protected function createStructure(array $options): ItemInterface return $menu; } + /** + * @override + * @return array + */ public static function getTranslationMessages(): array { return [ diff --git a/EventSubscriber/RightSideBarSiteAccessComparisonMenuBuilder.php b/EventSubscriber/RightSideBarSiteAccessComparisonMenuBuilder.php index 62961e3..2f25988 100644 --- a/EventSubscriber/RightSideBarSiteAccessComparisonMenuBuilder.php +++ b/EventSubscriber/RightSideBarSiteAccessComparisonMenuBuilder.php @@ -10,9 +10,15 @@ use Knp\Menu\ItemInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; +/** + * Class RightSideBarSiteAccessComparisonMenuBuilder is responsible for building the right sidebar menu for the + * bundle frontend. + * + * @package CJW\CJWConfigProcessor\EventSubscriber + */ class RightSideBarSiteAccessComparisonMenuBuilder extends AbstractBuilder { - + /* Menu Item */ const ITEM__SINGLE_SITEACCESS_VIEW = 'Single Site Access View'; const ITEM__NORMAL_COMPARISON_VIEW = 'Default Comparison'; const ITEM__COMMON_PARAMETERS_VIEW = 'Commons Comparison'; @@ -20,16 +26,33 @@ class RightSideBarSiteAccessComparisonMenuBuilder extends AbstractBuilder const ITEM__HIGHLIGHT_DIFFERENCES = 'Highlight Differences'; const ITEM__SYNCHRONOUS_SCROLLING = 'Synchronous Scrolling'; + /** + * RightSideBarSiteAccessComparisonMenuBuilder constructor. + * + * @param MenuItemFactory $factory + * @param EventDispatcherInterface $eventDispatcher + */ public function __construct(MenuItemFactory $factory, EventDispatcherInterface $eventDispatcher) { parent::__construct($factory, $eventDispatcher); } + /** + * @override + * @return string + */ protected function getConfigureEventName(): string { return ConfigureMenuEvent::CONTENT_SIDEBAR_RIGHT; } + /** + * @override + * + * @param array $options + * + * @return ItemInterface + */ protected function createStructure(array $options): ItemInterface { $menu = $this->factory->createItem('root'); @@ -43,7 +66,7 @@ protected function createStructure(array $options): ItemInterface 'attributes' => [ 'class' => 'ez-btn--reveal', 'data-actions' => 'change view', - "cjw_id" => "cjw_single_sa_view" + "cjw_id" => "cjw_single_sa_view", ], ] ), @@ -54,7 +77,7 @@ protected function createStructure(array $options): ItemInterface 'attributes' => [ 'class' => 'ez-btn--reveal', 'data-actions' => 'change view', - "cjw_id" => "cjw_show_normal_comparison" + "cjw_id" => "cjw_show_normal_comparison", ], ] ), diff --git a/Resources/config/routing.yaml b/Resources/config/routing.yaml index ca64ea8..9e65b2f 100644 --- a/Resources/config/routing.yaml +++ b/Resources/config/routing.yaml @@ -39,7 +39,7 @@ cjw_config_processing.remove_favourites: methods: [POST] cjw_config_processing.download_parameters: - path: /cjw/config-processing/parameter_list/download/{downloadDenominator} + path: /cjw/config-processing/parameter_list/download/{downloadDescriptor} controller: cjw_config_processor.controller::downloadParameterListAsTextFile methods: [GET] diff --git a/Resources/doc/changelogs/CHANGELOG-3.x.md b/Resources/doc/changelogs/CHANGELOG-3.x.md index 1f4b12b..4edb391 100644 --- a/Resources/doc/changelogs/CHANGELOG-3.x.md +++ b/Resources/doc/changelogs/CHANGELOG-3.x.md @@ -2,24 +2,26 @@ ## 3.0.1 (xx.12.2020) -* Fixed an issue with difference highlighting: When the state was saved in the url, - the highlighting would trigger immediately before any other JS had loaded which caused +* Fixed an issue with difference highlighting: When the state was saved in the url, + the highlighting would trigger immediately before any other JS had loaded which caused some false markings as certain classes and attributes had not been set at that point (now it will trigger after the other JS has loaded properly) - -* Fixed an issue with synchronous scrolling, where when the first node of a list was unique + +* 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. +* More and more detailed documentation. + ## 3.0 (11.12.2020) * This changelog has been created to ship with the first full version of the bundle - + * Bug fixes and overall improvements heading up to the release - + * Addition of important documentation leading up to the release * Initial release diff --git a/Services/TwigConfigDisplayService.php b/Services/TwigConfigDisplayService.php index 567db55..b44e14a 100644 --- a/Services/TwigConfigDisplayService.php +++ b/Services/TwigConfigDisplayService.php @@ -6,6 +6,7 @@ use CJW\CJWConfigProcessor\src\ConfigProcessorBundle\ConfigProcessCoordinator; use Exception; +use Psr\Cache\InvalidArgumentException; use Symfony\Component\HttpFoundation\RequestStack; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; @@ -43,11 +44,17 @@ class TwigConfigDisplayService extends AbstractExtension implements GlobalsInter */ private $siteAccessParameters; - public function __construct( - ContainerInterface $symContainer, - ConfigResolverInterface $ezConfigResolver, - RequestStack $symRequestStack - ) { + /** + * TwigConfigDisplayService constructor. + * + * @param ContainerInterface $symContainer + * @param ConfigResolverInterface $ezConfigResolver + * @param RequestStack $symRequestStack + * + * @throws Exception If the ConfigProcessCoordinator could not be initialized. + */ + public function __construct(ContainerInterface $symContainer, ConfigResolverInterface $ezConfigResolver, RequestStack $symRequestStack) + { ConfigProcessCoordinator::initializeCoordinator($symContainer,$ezConfigResolver,$symRequestStack); ConfigProcessCoordinator::startProcess(); $this->processedParameters = ConfigProcessCoordinator::getProcessedParameters(); @@ -57,7 +64,7 @@ public function __construct( /** * @inheritDoc */ - public function getFunctions() + public function getFunctions(): array { return array( new TwigFunction( @@ -65,14 +72,9 @@ public function getFunctions() array($this, "getProcessedParameters"), array("is_safe" => array("html")), ), - new TwigFunction( - "cjw_process_for_current_siteaccess", - array($this, "getParametersForCurrentSiteAccess"), - array("is_safe" => array("html")), - ), new TwigFunction( "cjw_process_for_siteaccess", - array($this, "getParametersForSpecificSiteAccess"), + array($this, "getParametersForSiteAccess"), array("is_safe" => array("html")), ), new TwigFunction( @@ -106,7 +108,12 @@ public function getGlobals(): array ); } - public function getFilters() + /** + * @override + * + * @return TwigFilter[] + */ + public function getFilters(): array { return array( new TwigFilter("boolean", array($this, "booleanFilter")), @@ -118,29 +125,32 @@ public function getFilters() * * @return string The extensions name */ - public function getName() + public function getName(): string { return 'cjw_config_processor.twig.display'; } + /** + * @return array Returns the processed parameters (Symfony configuration) into a twig template. + */ public function getProcessedParameters(): array { try { return ConfigProcessCoordinator::getProcessedParameters(); } catch (Exception $e) { - echo("Something went wrong while trying to retrieve the processed parameters."); - return []; + return ["An unexpected error occurred: ".$e->getMessage()]; } } - public function getParametersForCurrentSiteAccess(): array { - try { - return ConfigProcessCoordinator::getSiteAccessParameters(); - } catch (Exception $error) { - return []; - } - } - - public function getParametersForSpecificSiteAccess(string $siteAccess): array { + /** + * @param string|null $siteAccess An optional parameter which determines what site access context to use for the + * retrieval (will use the current one of the request, when none is set). + * + * @return array Returns the site access parameters for the site access the current request uses to a twig template. + * + * @throws InvalidArgumentException + */ + public function getParametersForSiteAccess(string $siteAccess = null): array + { try { return ConfigProcessCoordinator::getParametersForSiteAccess($siteAccess); } catch (Exception $error) { @@ -150,7 +160,15 @@ public function getParametersForSpecificSiteAccess(string $siteAccess): array { //Helper functions in twig templates - public function isNumeric(...$value): bool { + /** + * Determines whether given values are all numeric or not. + * + * @param mixed ...$value The values being put into the function. + * + * @return bool Returns true if every value is numeric and false if there is at least one that isn't. + */ + public function isNumeric(...$value): bool + { if (count($value) === 1 && isset($value[0]) && is_array($value[0])) { $value = $value[0]; } @@ -164,11 +182,27 @@ public function isNumeric(...$value): bool { return true; } - public function isString($value): bool { + /** + * Determines whether a given value is of type string or not. + * + * @param mixed $value Value to be checked. + * + * @return bool Returns true is the value is of type string or false if it is not. + */ + public function isString($value): bool + { return is_string($value); } - public function isContentIterable(...$value) { + /** + * Determines whether the given values are of type array or not. + * + * @param mixed ...$value The values to be checked. + * + * @return bool Returns true if the values are all of type array and false if at least one is not. + */ + public function isContentIterable(...$value): bool + { if (count($value) === 1 && isset($value[0]) && is_array($value[0])) { $value = $value[0]; } @@ -182,7 +216,15 @@ public function isContentIterable(...$value) { return false; } - public function booleanFilter ($value) { + /** + * Turns a given boolean value into a string representation of its value. + * + * @param mixed $value The value to be filtered. + * + * @return mixed Returns a string representation of the boolean value if the value is a boolean, else returns the value itself. + */ + public function booleanFilter ($value) + { if (is_bool($value)) { return $value? "true" : "false"; } else { diff --git a/Services/TwigHelpParserService.php b/Services/TwigHelpParserService.php index 975e7dd..0ac1b80 100644 --- a/Services/TwigHelpParserService.php +++ b/Services/TwigHelpParserService.php @@ -5,18 +5,39 @@ use CJW\CJWConfigProcessor\src\Utility\Parsedown; +use Psr\Cache\InvalidArgumentException; use ReflectionClass; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Twig\Extension\AbstractExtension; use Twig\Extension\GlobalsInterface; use Twig\TwigFunction; +/** + * Class TwigHelpParserService is a twig helper class which adds a function to all twig templates to parse markdown + * files into html representations via Parsedown and return the html to the template. + * + *
The files must follow a certain naming scheme for this service to work: + * [feature-name].[language].[optionally more segments].md + * + * @package CJW\CJWConfigProcessor\Services + */ class TwigHelpParserService extends AbstractExtension implements GlobalsInterface { - + /** + * @var Parsedown Instance of the class Parsedown in order to enable parsing markdown files. + */ private $parsedown; + /** + * @var string If no other language is given or found, search files for this fallback language. + */ private $fallBackLanguage; + /** + * @var string The path to the directory in which the help files are stored. + */ private $helpTextDirectory; + /** + * @var PhpFilesAdapter A cache adapter to allow caching the parsed markdown blocks. + */ private $cache; public function __construct() @@ -30,11 +51,17 @@ public function __construct() $this->cache = new PhpFilesAdapter(); } + /** + * @override + */ public function getGlobals(): array { return []; } + /** + * @override + */ public function getFunctions(): array { return [ @@ -45,17 +72,26 @@ public function getFunctions(): array ]; } - public function getHelpText(string $currentContext, string $_locale): string + /** + * Parses a markdown file from the help text directory that has been set for the class through the given name + * and locale. + * + * @param string $fileName The name of the file / feature (**not a full path to it** and also not including any file extensions!!). + * @param string $_locale The locale / language for which to search the file (will use fallback language, if nothing is found for the given language). + * + * @return string Returns the parsed markdown file as a string containing html. + */ + public function getHelpText(string $fileName, string $_locale): string { $helpTextFiles = glob($this->helpTextDirectory."/*"); - $helpFileName = $currentContext; + $helpFileName = $fileName; foreach ($helpTextFiles as $helpTextFile) { $helpFileBasename = basename($helpTextFile); if ( preg_match( - "/^".$currentContext."\.".$_locale.".*\.md$/", + "/^".$fileName."\.".$_locale.".*\.md$/", $helpFileBasename ) ) { @@ -64,7 +100,7 @@ public function getHelpText(string $currentContext, string $_locale): string break; } else if ( preg_match( - "/^".$currentContext."\.".$this->fallBackLanguage.".*\.md$/", + "/^".$fileName."\.".$this->fallBackLanguage.".*\.md$/", $helpFileBasename ) ) { @@ -79,6 +115,15 @@ public function getHelpText(string $currentContext, string $_locale): string return "

No help file could be found for the current context.

"; } + /** + * Parses a given markdown file to html and returns the string containing the html. + * + * @param string $fileName The path to the file to parse. + * + * @return string The parsed output of the markdown file. + * + * @throws InvalidArgumentException Throws a cache exception if a problem arises when trying to cache the parsed text. + */ private function parseFileContents (string $fileName): string { return $this->cache->get($fileName, function() use ($fileName) { diff --git a/Services/TwigTestDisplayService.php b/Services/TwigTestDisplayService.php index 573617b..2408c32 100644 --- a/Services/TwigTestDisplayService.php +++ b/Services/TwigTestDisplayService.php @@ -9,14 +9,15 @@ use Twig\Extension\GlobalsInterface; /** - * TODO: Move the entire functionality and initialisation of the custom loading process out of the Twig-Service-Realm and into a controller + * Class TwigTestDisplayService is responsible for bringing the paths found for every parameter to twig templates. * - * Class TwigTestDisplayService * @package CJW\CJWLocationAwareConfigLoadBundle\Services */ class TwigTestDisplayService extends AbstractExtension implements GlobalsInterface { - /** @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 $parametersAndLocations; public function __construct() @@ -25,6 +26,7 @@ public function __construct() } /** + * @override * Function to return global variables to be used in twig templates */ public function getGlobals(): array @@ -33,14 +35,4 @@ public function getGlobals(): array "cjw_param_location" => $this->parametersAndLocations?? [], ]; } - -// /** -// * @inheritDoc -// */ -// public function getFunctions() -// { -// return [ -// new TwigFunction("getLocations",[LocationRetrievalCoordinator::class,"getParametersAndLocations"]), -// ]; -// } } diff --git a/src/ConfigProcessorBundle/ConfigProcessCoordinator.php b/src/ConfigProcessorBundle/ConfigProcessCoordinator.php index 589256b..24d4bf6 100644 --- a/src/ConfigProcessorBundle/ConfigProcessCoordinator.php +++ b/src/ConfigProcessorBundle/ConfigProcessCoordinator.php @@ -12,25 +12,45 @@ use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\RequestStack; +/** + * Class ConfigProcessCoordinator is responsible for initiating and "coordinating" the configuration processing process. + * This means that it is responsible for first calling the process and storing its result so that these may be retrieved + * and used throughout. It also serves as the interface through which outside classes and services may access the + * config processes. + * + * @package CJW\CJWConfigProcessor\src\ConfigProcessorBundle + */ class ConfigProcessCoordinator { - /** @var ContainerInterface */ + /** + * @var ContainerInterface The standard Symfony container, which is created by the kernel on boot. + */ private static $symContainer; - /** @var ConfigResolverInterface */ + /** + * @var ConfigResolverInterface + */ private static $ezConfigResolver; - /** @var ConfigProcessor */ + /** + * @var ConfigProcessor The processor with which the configuration is processed and parsed into an associative, hierarchical array. + */ private static $configProcessor; - /** @var SiteAccessParamProcessor */ + /** + * @var SiteAccessParamProcessor The processor responsible for determining site access specific parameters and parsing them as such. + */ private static $siteAccessParamProcessor; - /** @var RequestStack */ + /** + * @var RequestStack The request stack with the current, pending request. + */ private static $symRequestStack; - /** @var PhpFilesAdapter */ + /** + * @var PhpFilesAdapter The cache with which the results of all the processes are stored. + */ private static $cache; /** @@ -51,23 +71,26 @@ class ConfigProcessCoordinator */ private static $siteAccessParameters; - /** @var bool Simply describes whether the class and its various internal attributes have been initialized. */ + /** + * @var bool Simply describes whether the class and its various internal attributes have been initialized. + */ private static $initialized = false; - /** @var string The time the processed parameters have last been updated. */ + /** + * @var string The time the processed parameters have last been updated. + */ private static $lastUpdated; /** - * @param ContainerInterface $symContainer - * @param ConfigResolverInterface $ezConfigResolver - * @param RequestStack $symRequestStack + * Function to set up and first initiate the coordinator in order to allow for it to perform its processes + * without issue. This also sets up the variables and attributes of the class. + * + * @param ContainerInterface $symContainer The standard Symfony container, which has been created by the standard kernel. + * @param ConfigResolverInterface $ezConfigResolver A config resolver by ez to determine site access parameters. + * @param RequestStack $symRequestStack Contains the current, pending request. */ - public static function initializeCoordinator ( - ContainerInterface $symContainer, - ConfigResolverInterface $ezConfigResolver, - RequestStack $symRequestStack - ): void { - + public static function initializeCoordinator (ContainerInterface $symContainer, ConfigResolverInterface $ezConfigResolver, RequestStack $symRequestStack): void + { if (!self::$symContainer && $symContainer) { self::$symContainer = $symContainer; } @@ -98,14 +121,16 @@ public static function initializeCoordinator ( } self::$initialized = true; - } /** - * @throws Exception + * Responsible for starting the entire processing and parsing of the internal Symfony configuration and + * will create first versions of the processed parameters and the site access parameters. + * + * @throws Exception Throws an exception, when the coordinator has not been initialized before calling this function. */ - public static function startProcess () { - + public static function startProcess ():void + { if (!self::$initialized) { throw new Exception( "The 'ConfigProcessCoordinator' has not been initialized! " . @@ -123,21 +148,16 @@ public static function startProcess () { }); if ($request) { - self::$siteAccessParameters = self::$cache->get("cjw_site_access_parameters", function() { return self::getParametersForSiteAccess(); }); - } self::$lastUpdated = self::$cache->get("cjw_processing_timestamp", function() { $currentDate = new DateTime(); return $currentDate->format("Y-m-d H:i"); }); - } catch (Exception $error) { - print(`Something went wrong while trying to parse the parameters: ${$error}.`); - } catch (InvalidArgumentException $e) { - print(`An error occured while trying to access caching for the parameters: ${$e}.`); + } catch (InvalidArgumentException | Exception $error) { } } @@ -146,10 +166,13 @@ public static function startProcess () { * belong to the current or a given site access. * * @param string|null $siteAccess Optional argument which states which site access should be used for the parameter value retrieval. + * * @return array Returns an array which includes the site access parameters. + * * @throws InvalidArgumentException Throws an exception, when the Coordinator has not been initialized prior to calling this function. */ - public static function getParametersForSiteAccess(string $siteAccess = null): array { + public static function getParametersForSiteAccess(string $siteAccess = null): array + { if ($siteAccess) { $siteAccess = strtolower($siteAccess); } @@ -177,8 +200,9 @@ function() { /** * Gets the processed parameters array which contains the reformatted and sorted parameters. * - * @return array - * @throws Exception + * @return array The processed parameters as a hierarchical, associative array. + * + * @throws Exception Throws an exception, when the coordinator has not been intialized before calling this function. */ public static function getProcessedParameters(): array { @@ -192,8 +216,9 @@ public static function getProcessedParameters(): array /** * Retrieves the parameters for the current site access. * - * @return array - * @throws Exception + * @return array Returns the site access specific parameters in a hierarchical, associative array. + * + * @throws Exception Throws an exception, when the coordinator has not been intialized before calling this function. */ public static function getSiteAccessParameters(): array { @@ -204,11 +229,29 @@ public static function getSiteAccessParameters(): array return self::$siteAccessParameters?? []; } - public static function getSiteAccessListForController(string $specificSiteAccess = null): array { + /** + * Assembles and returns a list of all site accesses of the current installation. + * + * @param string|null $specificSiteAccess Can be filtered for a specific site access to get only the site accesses active, with the given one. + * + * @return string[] Returns an array of the found site accesses as strings. + * + * @throws Exception Throws an exception, when the coordinator has not been intialized before calling this function. + */ + public static function getSiteAccessListForController(string $specificSiteAccess = null): array + { return self::getSiteAccesses($specificSiteAccess); } - public static function getTimeOfLastUpdate (): string { + /** + * Does what the name states: Returns the timestamp for when the processed parameters have last been updated. + * + * @return string Return the timestamp as a string. + * + * @throws Exception Throws an exception, when the coordinator has not been initialized before calling this function. + */ + public static function getTimeOfLastUpdate (): string + { if (!self::$lastUpdated) { self::startProcess(); } @@ -227,9 +270,11 @@ public static function getTimeOfLastUpdate (): string { * as an array to the class. * * @return array Returns a hierarchical associative array that features every parameter sorted after their keys. + * * @throws Exception Throws an error if something went wrong while trying to parse the parameters. */ - private static function parseContainerParameters() { + private static function parseContainerParameters(): array + { $parameters = new ParameterAccessBag(self::$symContainer); $parameters = $parameters->getParameters(); @@ -250,10 +295,13 @@ private static function parseContainerParameters() { * parameter. * * @param string|null $desiredSiteAccess Optional parameter which dictates whether only the default SiteAccesses and the given one will be added or all available ones are added. + * * @return array Returns all found siteAccesses in an array. - * @throws Exception + * + * @throws Exception Throws an exception, when the coordinator has not been initialized before calling this function. */ - private static function getSiteAccesses(string $desiredSiteAccess = null): array { + private static function getSiteAccesses(string $desiredSiteAccess = null): array + { if (!self::$processedParameters) { self::startProcess(); } @@ -296,7 +344,16 @@ private static function getSiteAccesses(string $desiredSiteAccess = null): array return $siteAccesses; } - private static function getCustomParameters (array $siteAccessList) { + /** + * Responsible for returning the custom parameters which have been set by the user via the configuration + * (if the feature has been enabled). + * + * @param array $siteAccessList A list of site accesses for which the parameters are supposed to be looked at. + * + * @return array Returns an associative, hierarchical array of custom parameters. + */ + private static function getCustomParameters (array $siteAccessList): array + { if ( self::$symContainer->getParameter("cjw.custom_site_access_parameters.active") === true ) { @@ -345,11 +402,8 @@ private static function validateCachedItems() { self::$cache->delete("cjw_processed_param_objects"); self::$cache->delete("cjw_processing_timestamp"); } - } catch (InvalidArgumentException $e) { - print(`Accessing the cache components of the service has led to errors: ${$e}`); } - } } diff --git a/src/ConfigProcessorBundle/ConfigProcessor.php b/src/ConfigProcessorBundle/ConfigProcessor.php index 7511269..cd0a21c 100644 --- a/src/ConfigProcessorBundle/ConfigProcessor.php +++ b/src/ConfigProcessorBundle/ConfigProcessor.php @@ -13,8 +13,7 @@ class ConfigProcessor { /** - * Stores all the processed parameters with their namespaces as keys in the array. - * @var array + * @var array Stores all the processed parameters with their namespaces as keys in the array. */ private $processedParameters; @@ -24,7 +23,7 @@ public function __construct() } /** - * @return array Returns the internal Object-based Parameterlist + * @return array Returns the internal object-based Parameterlist */ public function getProcessedParameters(): array { @@ -36,10 +35,10 @@ public function getProcessedParameters(): array * readable structure. * * @param array $parameters A list of given parameters to be processed and reformatted. - * @returns array Returns an array of the processed and formatted parameters. + * * @return array Returns the processed parameters in the form of an associative array. */ - public function processParameters(array $parameters) + public function processParameters(array $parameters): array { if ($parameters && is_array($parameters)) { $keys = array_keys($parameters); @@ -63,12 +62,14 @@ public function processParameters(array $parameters) /** * Takes a given key and splits it into the different segments that are present in it - * (namespace, (with eZ) siteaccess, actual parameter etc). + * (namespace, (with eZ) siteaccess, actual parameter, etc). + * + * @param string $key The parameter key to be split into key segments. * - * @param string $key - * @return array | false + * @return array | false Returns an array of key segments or false, if it the given key could not be split. */ - private function parseIntoParts (string $key) { + private function parseIntoParts (string $key) + { if ($key && strlen($key) > 0) { $splitStringCarrier = explode(".",$key); @@ -86,16 +87,25 @@ private function parseIntoParts (string $key) { * Turns the array of ProcessedParamModel-Objects into an associative array with the keys and the values attached to them. * Also sorts the keys of the array alphabetically so they are more easily searchable. */ - private function reformatParametersForOutput() { + private function reformatParametersForOutput(): array + { $formattedOutput = []; foreach($this->processedParameters as $parameter) { $formattedOutput[$parameter->getKey()] = $parameter->reformatForOutput(); } -// ksort($formattedOutput,SORT_STRING); + return $this->sortParameterKeys($formattedOutput); } - private function sortParameterKeys (array $parameters) { + /** + * Function to sort the keys of a given, associative array alphabetically. + * + * @param array $parameters The associative array of parameters to be sorted. + * + * @return array Returns the sorted array. + */ + private function sortParameterKeys (array $parameters): array + { ksort($parameters, SORT_STRING); foreach ($parameters as $key => $value) { diff --git a/src/ConfigProcessorBundle/CustomParamProcessor.php b/src/ConfigProcessorBundle/CustomParamProcessor.php index bdf5740..08ba832 100644 --- a/src/ConfigProcessorBundle/CustomParamProcessor.php +++ b/src/ConfigProcessorBundle/CustomParamProcessor.php @@ -6,19 +6,30 @@ use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Class CustomParamProcessor is responsible for processing parameters and keys for parameters, which have been + * set directly by the user via the config and it provides various helper function to retrieve, parse, scan and edit + * the parameters (also when it comes to site accesses). + * + * @package CJW\CJWConfigProcessor\src\ConfigProcessorBundle + */ class CustomParamProcessor { - /** @var ContainerInterface */ + /** + * @var ContainerInterface The standard Symfony container, which has been created by the kernel during the boot process. + */ private $symContainer; - /** @var array */ + /** + * @var array A list of all site accesses for which to edit and scan the given parameters. + */ private $currentActiveSiteAccessList; - /** @var array */ + /** + * @var array A list of all site accesses available in the current installation. + */ private $allSiteAccesses; - public function __construct( - ContainerInterface $symContainer = null, - array $siteAccessList = [] - ) { + public function __construct(ContainerInterface $symContainer = null, array $siteAccessList = []) + { $this->symContainer = $symContainer; $this->currentActiveSiteAccessList = $siteAccessList; @@ -27,11 +38,17 @@ public function __construct( } } - - public function getCustomParameters ( - array $customParameterKeys, - array $processedParameters - ): array { + /** + * Build and returns a list of custom parameters (in the format the rest of the processed parameters is in) based + * on the given list of parameter keys. + * + * @param array $customParameterKeys A list of parameter keys as strings. + * @param array $processedParameters A list of the processed parameters of the entire Symfony configuration. + * + * @return array|null Returns an array of custom parameters and null if no parameters could be found via the given keys. + */ + public function getCustomParameters (array $customParameterKeys, array $processedParameters): array + { $customParameters = []; foreach ($customParameterKeys as $customKey) { @@ -55,7 +72,17 @@ public function getCustomParameters ( return $customParameters; } - public function replacePotentialSiteAccessParts (array $keysToBeProcessed): array { + /** + * Takes a list of parameter keys (as strings) and checks them for any potential site access segments within the + * keys. If such segments are found, then the parameter and that segment will be redone for every possible + * site access of the installation and added to the original list of keys. + * + * @param array $keysToBeProcessed Array of (string) keys of parameters. + * + * @return array Returns the new list of parameter keys (including the potential site access versions). + */ + public function replacePotentialSiteAccessParts (array $keysToBeProcessed): array + { $changedKeys = $keysToBeProcessed; foreach ($keysToBeProcessed as $parameterKey) { @@ -81,22 +108,49 @@ public function replacePotentialSiteAccessParts (array $keysToBeProcessed): arra return $changedKeys; } - - public function scanAndEditForSiteAccessDependency (array $parametersToBeProcessed): array { + /** + * Takes a list of already fully formed custom parameters (without values) and cuts all possibly site access + * dependent parameters out of that list in order to process them separately. + * + *
This separate processing comes in the form that it determines the values for those possibly site access + * dependent parameters by looking at the site access set for the parameter, but also "default", "global", etc. which + * are present in that site access hierarchy, to determine the value that is actually set under the circumstances + * of that site access for the parameter. + * + *
Example: When searching for test.admin.parameter, there might not be a value for site access admin, then it could + * be set under default, global, admin_group or any other site access from that hierarchy and so the value of + * the highest site access in that hierarchy is determined (global before any other, then the group and lasty default) + * + * @param array $parametersToBeProcessed Associative, hierarchical array of parameter keys for which to determine the values. + * + * @return array Returns the resulting parameter array after the separate site access processing operation. + */ + public function scanAndEditForSiteAccessDependency (array $parametersToBeProcessed): array + { + // First determine which of the given parameters might be site access dependent and store them in a separate array. $possiblySiteAccessDependentParameters = $this->getAllPossiblySiteAccessDependentParameters($parametersToBeProcessed); + // Take those parameters and add them back into the overall parameters array after the processing is done. $parametersToBeProcessed = $this->addSiteAccessParametersBackIntoStructure( $possiblySiteAccessDependentParameters, $parametersToBeProcessed ); + // Return the resulting full parameters array. return $parametersToBeProcessed; } - private function constructListOfAllSiteAccesses (): void { + /** + * Determines all site accesses and groups that have been set and are active in the installation and assembles a + * list of these accesses to be used in processing afterwards. This list also features the order in which the + * site accesses are looked at, with the first item being of the lowest relevance. + */ + private function constructListOfAllSiteAccesses (): void + { $this->allSiteAccesses[] = "default"; + // Get the site access groups. if ($this->symContainer->hasParameter("ezpublish.siteaccess.groups")) { $groups = $this->symContainer->getParameter("ezpublish.siteaccess.groups"); $groups = array_keys($groups); @@ -104,6 +158,7 @@ private function constructListOfAllSiteAccesses (): void { array_push($this->allSiteAccesses, ...$groups); } + // Get the site access parameters. if ($this->symContainer->hasParameter("ezpublish.siteaccess.list")) { array_push( $this->allSiteAccesses, @@ -114,11 +169,22 @@ private function constructListOfAllSiteAccesses (): void { $this->allSiteAccesses[] = "global"; } - private function getParameterThroughParts ( - array $keyParts, - array $processedParameters, - bool $withinCustomArray = false - ): array { + /** + * Gets a parameter out of a given array of parameters by looking at an array of hierarchical key segments, leading + * to the parameter that is supposed to be taken. But it incorporates checks along the way for whether the + * segments exist or are empty. + * + *
Example: [first,second,third] segment as keylist will be used for the given parameters, leading to + * parameters[first][second][third] to be returned. + * + * @param array $keyParts The list of key segments to go through. + * @param array $processedParameters An associative array of parameters to check with the list of keys. + * @param false $withinCustomArray An optional boolean, which is employed by the function, when it is recursively called. + * + * @return array Returns the found array after following the keylist. Returns an empty array, when the keys couldn't be found or the found parameter is empty. + */ + private function getParameterThroughParts (array $keyParts, array $processedParameters, bool $withinCustomArray = false): array + { $customParametersSoFar = []; if (count($keyParts) > 0) { @@ -128,7 +194,6 @@ private function getParameterThroughParts ( $customParametersSoFar[$key] = self::getParameterThroughParts($keyParts,$processedParameters[$key], true); - // in_array($key,$this->allSiteAccesses) && <-- maybe required to ensure only empty site access parameters are taken and nothing else if (count($customParametersSoFar[$key]) === 0) { unset($customParametersSoFar[$key]); } @@ -140,11 +205,23 @@ private function getParameterThroughParts ( return $customParametersSoFar; } - private function addSiteAccessParametersBackIntoStructure ( - array $parameters, - array $comparisonParameters - ): array { - $indexOfCurrentHightestAccess = 0; + /** + * Takes a list of site access parameters and parameters to add these to and determines both the site access + * version of the parameters that is valid for the current context (dismisses the rest) and adds these into + * the given "comparisonParameters". + * + *
Example: if 'test.admin.parameter = "test"' and 'test.global.parameter = "not test"' exist in the list of parameters + * to add, then 'test.admin.parameter' will be dismissed and 'test.global.parameter' will be added to the comparisonParameters, + * since global is positioned higher in the site access hierarchie. + * + * @param array $parameters The array of site access parameters to add to the given list. + * @param array $comparisonParameters The given list of parameters to add the given site access parameters to. + * + * @return array Returns an array which includes the added site access parameters and the previous, existing parameters. + */ + private function addSiteAccessParametersBackIntoStructure (array $parameters, array $comparisonParameters): array + { + $indexOfCurrentHighestAccess = 0; foreach ($parameters as $parameterKey => $parameterValue) { if ( !in_array($parameterKey, $this->allSiteAccesses) && @@ -169,13 +246,13 @@ private function addSiteAccessParametersBackIntoStructure ( continue; } - $indexOfCurrentHightestAccess = - ($currentAccessIndex < $indexOfCurrentHightestAccess)? $indexOfCurrentHightestAccess : $currentAccessIndex; + $indexOfCurrentHighestAccess = + ($currentAccessIndex < $indexOfCurrentHighestAccess)? $indexOfCurrentHighestAccess : $currentAccessIndex; $results = $this->buildFullParameterKeys($parameterValue); foreach ($results as $resultKey => $resultValue) { if ( - $currentAccessIndex < $indexOfCurrentHightestAccess && + $currentAccessIndex < $indexOfCurrentHighestAccess && key_exists($resultKey,$comparisonParameters) ) { continue; @@ -188,10 +265,17 @@ private function addSiteAccessParametersBackIntoStructure ( return $comparisonParameters; } - private function buildFullParameterKeys ( - array $parameters, - string $predecessorKeys = null - ): array { + /** + * Takes an associative, hierarchical array of parameters and assembles the keys of the different levels down + * to the actual value (of the parameter) to complete keys for every parameter. + * + * @param array $parameters Associative, hierarchical array of parameters. + * @param string|null $predecessorKeys An optional key which states what key came in the level above the current. + * + * @return array Returns an array of fully assembled parameter keys (if it was possible to do so), returns an empty array if no keys could be assembled. + */ + private function buildFullParameterKeys (array $parameters, string $predecessorKeys = null): array + { $result = []; foreach ($parameters as $parameterKey => $parameterValue) { @@ -221,9 +305,16 @@ private function buildFullParameterKeys ( return $result; } - private function getAllPossiblySiteAccessDependentParameters ( - array $parametersToBeProcessed - ): array { + /** + * Checks the given parameters array for any keys and by extension parameters which feature one a + * site access key segment and collects these parameters in a separate array. + * + * @param array $parametersToBeProcessed Associative, hierarchical array of parameters to search for site access dependencies. + * + * @return array Returns an array of site access dependent parameters, which have been found in the given ones or an empty array if non could be found. + */ + private function getAllPossiblySiteAccessDependentParameters (array $parametersToBeProcessed): array + { $result = []; foreach ($parametersToBeProcessed as $parameterKey => $parameterValue) { @@ -253,10 +344,20 @@ private function getAllPossiblySiteAccessDependentParameters ( return $result; } - private function addInKeysUnderSameSiteAccess ( - array $listToAddInto, - array $parametersToAdd - ): array { + /** + * Takes a list of parameters to add to an existing associative array and goes down the keys of both arrays to + * find a key of a parameter which is missing in the list to add to. If those keys are found, the content + * of the parameter will be added at that point in the list to add to. + * + *
Functions similarly to array_replace_recursive of php. + * + * @param array $listToAddInto An associative array to add the parameter to. + * @param array $parametersToAdd Associative array of parameters to add into the given list. + * + * @return array Returns the list to which the parameters have been added. + */ + private function addInKeysUnderSameSiteAccess(array $listToAddInto, array $parametersToAdd): array + { foreach($parametersToAdd as $parameterKey => $parameterValue) { if ( key_exists($parameterKey,$listToAddInto) && diff --git a/src/ConfigProcessorBundle/FavouritesParamCoordinator.php b/src/ConfigProcessorBundle/FavouritesParamCoordinator.php index 2f99838..4dcdb0c 100644 --- a/src/ConfigProcessorBundle/FavouritesParamCoordinator.php +++ b/src/ConfigProcessorBundle/FavouritesParamCoordinator.php @@ -6,19 +6,39 @@ use CJW\CJWConfigProcessor\src\Utility\Utility; use Exception; +use Psr\Cache\InvalidArgumentException; use Symfony\Component\Cache\Adapter\PhpFilesAdapter; use Symfony\Component\DependencyInjection\ContainerInterface; +/** + * Class FavouritesParamCoordinator is responsible for providing methods and functionalities to form, determine and + * retrieve parameters of the existing configuration as favourites. + * + * @package CJW\CJWConfigProcessor\src\ConfigProcessorBundle + */ class FavouritesParamCoordinator { - + /** + * @var bool Boolean which states whether the coordinator has been initialized yet. + */ private static $initialized = false; + /** + * @var ContainerInterface The standard Symfony container created during the boot process by the kernel. + */ private static $symContainer; + /** + * @var PhpFilesAdapter Cache adapter to allow the coordinator to store the favourite parameters. + */ private static $cache; - public static function initialize ( - ContainerInterface $symContainer - ) { + /** + * Initializes the coordinator and instantiates all important attributes of the class in order for + * it to function properly. + * + * @param ContainerInterface $symContainer The standard Symfony container created during the boot process by the kernel. + */ + public static function initialize (ContainerInterface $symContainer): void + { if ($symContainer) { self::$symContainer = $symContainer; } @@ -35,10 +55,18 @@ public static function initialize ( self::$initialized = true; } - public static function getFavourites ( - array $processedParameters, - array $siteAccesses = [] - ): array { + /** + * Retrieves a list of favourite parameters that have been set for the installation by the user. + * + * @param array $processedParameters An associative array of all processed parameters of the installation. + * @param array $siteAccesses A list of site accesses to take into account, when retrieving or determining the favourites. + * + * @return array Returns either an array containing the favourite parameters or an empty array if non have been set or found. + * + * @throws InvalidArgumentException Should an error occur with the caching mechanism behind the favourites. + */ + public static function getFavourites (array $processedParameters, array $siteAccesses = []): array + { if ( self::$symContainer->getParameter("cjw.favourite_parameters.allow") === true ) { @@ -68,11 +96,21 @@ function () use ($favouriteRetrievalProcessor, $processedParameters) { return []; } - public static function getFavouriteKeyList ( - array $processedParameters, - array $siteAccesses = [] - ): array { - + /** + * Takes the existing favourites that have been set by the user and constructs a list of key segments from these + * favourites (meaning only the keys of the favourite array and non of the values). + * + *
Example: ["favourite" => ["keys" => ["value" = "value"]]] will return ["favourite" => ["keys" => []]] + * + * @param array $processedParameters An associative array of all processed parameters of the installation. + * @param array $siteAccesses A list of site accesses to take into account, when retrieving or determining the favourites. + * + * @return array Returns an array of favourite keys. + * + * @throws InvalidArgumentException Should an error occur with the caching mechanism behind the favourites. + */ + public static function getFavouriteKeyList (array $processedParameters, array $siteAccesses = []): array + { $favouritesToProcess = self::getFavourites($processedParameters, $siteAccesses); @@ -82,10 +120,18 @@ public static function getFavouriteKeyList ( ); } - public static function setFavourite ( - array $favouriteParameterKeys, - array $processedParameters - ) + /** + * Allows setting specific parameters as favourites. The keys to be added must contain the entire + * parameter key to be set as favourites as every entry of the array will be viewed as a self contained unit. + * + *
Example: ["first.favourite.parameter","second.favourite.parameter","third","fourth.parameter"] + * + * @param array $favouriteParameterKeys A list of parameter keys to be set as favourites. + * @param array $processedParameters The processed Symfony configuration to search in with regards to the favourites. + * + * @throws InvalidArgumentException Should an error occur with the caching mechanism behind the favourites. + */ + public static function setFavourite(array $favouriteParameterKeys, array $processedParameters) { if ( self::$symContainer->getParameter("cjw.favourite_parameters.allow") === true @@ -129,11 +175,20 @@ function() use ($previousFavourites, $newFavourites) { } } - public static function removeFavourite( - array $favouritesToRemove, - array $processedParameters - ) { - + /** + * Allows removing specific parameters as a favourite. The keys to be removed must contain the entire + * parameter key to be removed as favourites as every entry of the array will be viewed as a selfcontained unit. + * When a given parameter is not part of the favourites, nothing will be done to the list. + * + *
Example: ["first.favourite.parameter","second.favourite.parameter","third","fourth.parameter"] + * + * @param array $favouritesToRemove An array of (string) parameter keys to be removed from the favourite parameters. + * @param array $processedParameters The processed Symfony configuration to search in with regards to the favourites. + * + * @throws InvalidArgumentException Should an error occur with the caching mechanism behind the favourites. + */ + public static function removeFavourite(array $favouritesToRemove, array $processedParameters) + { $favouriteRetrievalProcessor = new CustomParamProcessor(self::$symContainer); $previousFavourites = self::$cache->get( @@ -168,10 +223,17 @@ function () use ($currentFavourites) { } } - private static function getFavouritesThroughContainer ( - CustomParamProcessor $favouriteRetrievalProcessor, - array $processedParameters - ): array { + /** + * Supposed to retrieve the favourite parameters from cache, dictating the procedure in the case nothing has been + * cached in order to create the cache entry. + * + * @param CustomParamProcessor $favouriteRetrievalProcessor The processor used to determine and retrieve the parameters that have been deemed as favourites. + * @param array $processedParameters The processed Symfony configuration to search in with regards to the favourites. + * + * @return array|null Returns an array of favourites or null if none could be found. + */ + private static function getFavouritesThroughContainer(CustomParamProcessor $favouriteRetrievalProcessor, array $processedParameters): array + { $favouriteKeys = self::$symContainer->getParameter("cjw.favourite_parameters.parameters"); return $favouriteRetrievalProcessor->getCustomParameters( diff --git a/src/ConfigProcessorBundle/ParameterAccessBag.php b/src/ConfigProcessorBundle/ParameterAccessBag.php index 3544293..0d7086e 100644 --- a/src/ConfigProcessorBundle/ParameterAccessBag.php +++ b/src/ConfigProcessorBundle/ParameterAccessBag.php @@ -7,6 +7,12 @@ use Psr\Container\ContainerInterface; use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag; +/** + * Class ParameterAccessBag is a small class which is only used to get the entirety of all stored parameters from + * a FrozenParameterBag. + * + * @package CJW\CJWConfigProcessor\src\ConfigProcessorBundle + */ class ParameterAccessBag extends FrozenParameterBag { public function __construct(ContainerInterface $container) @@ -19,7 +25,8 @@ public function __construct(ContainerInterface $container) * * @return array Returns the array as it is stored in the original parameter bag. */ - public function getParameters() { + public function getParameters(): array + { // The "$this->parameters" attribute stems from the parent class. return $this->parameters; } diff --git a/src/ConfigProcessorBundle/ParametersToFileWriter.php b/src/ConfigProcessorBundle/ParametersToFileWriter.php index 0babcc6..0b71e94 100644 --- a/src/ConfigProcessorBundle/ParametersToFileWriter.php +++ b/src/ConfigProcessorBundle/ParametersToFileWriter.php @@ -7,15 +7,28 @@ use DateTime; use Symfony\Component\Filesystem\Filesystem; +/** + * Class ParametersToFileWriter is used to create a file representation of the parameter lists given to it. + * + * @package CJW\CJWConfigProcessor\src\ConfigProcessorBundle + */ class ParametersToFileWriter { - /** @var bool */ + /** + * @var bool Stating whether the Writer has been initialized already. + */ private static $initialized = false; - /** @var Filesystem */ + /** + * @var Filesystem Used to create the file itself and write the content to file. + */ private static $filesystem; - public static function initializeFileWriter () { + /** + * Function to initialize the writer and set up the most important class attributes to function properly. + */ + public static function initializeFileWriter(): void + { if (!self::$initialized) { if (!self::$filesystem) { @@ -24,26 +37,38 @@ public static function initializeFileWriter () { } } - public static function writeParametersToFile ( - array $parametersToWrite, - string $downloadDescriptor = null - ): string { - + /** + * Writes a given associative array of parameters to a file in a yaml format. + * + * @param array $parametersToWrite An associative, hierarchical array of parameters. + * @param string|null $downloadDescriptor A string which determines whether or not the file should be limited to + * or viewed in a specific context (favourites, site access, etc.). + * + * @return string Returns the name of / the path to the file that has been created. + */ + public static function writeParametersToFile(array $parametersToWrite, string $downloadDescriptor = null): string + { if (!self::$initialized) { self::initializeFileWriter(); } $temporaryFile = self::$filesystem->tempnam(sys_get_temp_dir(),"parameter_list_", ".yaml"); + // Assemble a new and more readable name for the temporary file that is offered to be downloaded. $tmpDir = pathinfo($temporaryFile,PATHINFO_DIRNAME); $currentDate = new DateTime(); $currentDate = $currentDate->format("Y-m-d_H.i"); $downloadDescriptor = $downloadDescriptor?? "all_parameters"; $targetName = $tmpDir."/parameter_list_".$downloadDescriptor."_".$currentDate.".yaml"; + // Start the file writing process only when the file does not already exist. if (!file_exists($targetName)) { if ($temporaryFile) { - $siteAccess = $downloadDescriptor === "favourites"? null : $downloadDescriptor; + $siteAccess = null; + if (!($downloadDescriptor === "favourites" || $downloadDescriptor === "all_parameters")) { + $siteAccess = $downloadDescriptor; + } + self::appendDataPerKey($temporaryFile,$parametersToWrite, $siteAccess); } @@ -53,14 +78,21 @@ public static function writeParametersToFile ( return $targetName; } - private static function appendDataPerKey ( - string $pathToFileToWriteTo, - array $parametersToWrite, - string $siteAccess = null - ) { + /** + * For every top level key of the given array, the data is collected and written out to the file. + * It will employ the top level key to write out the entirety of all sub-arrays / -keys. + * + * @param string $pathToFileToWriteTo The path to the file that is supposed to be written to. + * @param array $parametersToWrite An associative array of parameters to be written out. + * @param string|null $siteAccess The site access context in which to print out the parameter keys. + */ + private static function appendDataPerKey (string $pathToFileToWriteTo, array $parametersToWrite, string $siteAccess = null): void + { + // On the first line, make sure the "parameters"-key is written once. self::$filesystem->appendToFile($pathToFileToWriteTo,"parameters:\n"); foreach (array_keys($parametersToWrite) as $key) { + // Write out the top level key. self::$filesystem->appendToFile($pathToFileToWriteTo,"\n"); $keyDisplay = $key; @@ -68,17 +100,24 @@ private static function appendDataPerKey ( $keyDisplay .= ".".$siteAccess; } + // Write out the remaining keys under that top level. self::writeSubTree($pathToFileToWriteTo, $parametersToWrite[$key],$keyDisplay); } } - private static function writeSubTree ( - string $pathToFileToWriteTo, - array $subTreeToWrite, - string $previousKey, - bool $valueReached = false, - int $numberOfIndents = 0 - ) { + /** + * Handles the output to file for the entirety of a multi dimensional associative array structure. + * It determines the type of output based on whether the value of a parameter has started and + * whether those values include "yaml objects" or simply "yaml lists". + * + * @param string $pathToFileToWriteTo The path to the file to which to write the output. + * @param array $subTreeToWrite The array to be written into the file in a yaml format. + * @param string $previousKey The key of the array which came the level above the current. + * @param bool $valueReached Whether or not the value of the parameter has been reached. + * @param int $numberOfIndents The number of indents to add to the line before writing it out. + */ + private static function writeSubTree (string $pathToFileToWriteTo, array $subTreeToWrite, string $previousKey, bool $valueReached = false, int $numberOfIndents = 0): void + { foreach ($subTreeToWrite as $parameterKey => $parameterFollowUp) { $parameterFollowUpIsArray = is_array($parameterFollowUp); @@ -86,10 +125,22 @@ private static function writeSubTree ( if (is_bool($parameterFollowUp)) { $parameterFollowUp = $parameterFollowUp? "true" : "false"; } else { + if ($parameterFollowUp && str_contains($parameterFollowUp,"\"")) { + $parameterFollowUp = str_replace("\"","\\\"",$parameterFollowUp); + } + $parameterFollowUp = '"'.$parameterFollowUp.'"'; } } + if (preg_match('/^[\'"^£$%&*()}{@#~?><>,|=_+¬-]/', $parameterKey)) { + if (str_contains($parameterKey,"\"")) { + $parameterKey = str_replace("\"","\\\"",$parameterKey); + } + + $parameterKey = '"'.$parameterKey.'"'; + } + if (!$valueReached) { if ($parameterFollowUpIsArray) { self::writeMultiLineKeys ( @@ -130,21 +181,24 @@ private static function writeSubTree ( } } - private static function writeSingleLineKeys ( - string $parameterKey, - string $previousKey, - string $output, - string $pathToWriteTo - ): void + /** + * Writes a key with or without a value attached to it into a single line in a yaml format. + * + * @param string $parameterKey The key that is supposed to be added to the file. + * @param string $previousKey The key that came before it in the key hierarchy. + * @param string $paramValue The value attached to the key to be written out to the file. + * @param string $pathToWriteTo The path to the file to write to. + */ + private static function writeSingleLineKeys (string $parameterKey, string $previousKey, string $paramValue, string $pathToWriteTo): void { - $fileInput = $previousKey . ": " . $output . "\n"; + $fileInput = $previousKey . ": " . $paramValue . "\n"; if (!$parameterKey === "parameter_value") { $parameterKey = $previousKey . "." . $parameterKey; $fileInput = $parameterKey. ":\n"; } - if ($output) { + if ($paramValue) { self::$filesystem->appendToFile( $pathToWriteTo, self::buildOutputString( @@ -155,12 +209,16 @@ private static function writeSingleLineKeys ( } } - private static function writeMultiLineKeys ( - string $parameterKey, - string $previousKey, - array $output, - string $pathToWriteTo - ): void + /** + * Writes out a key structure in its entirety to a file. That key structure then does not contain + * a value as it rather is responsible for handling hierarchical key structures for the yaml. + * + * @param string $parameterKey The key that is supposed to be added to the file. + * @param string $previousKey The key that came before it in the key hierarchy. + * @param array $output The rest of the subtree structure beneath the parameter key. + * @param string $pathToWriteTo The path to the file to write to. + */ + private static function writeMultiLineKeys (string $parameterKey, string $previousKey, array $output, string $pathToWriteTo): void { $valueReached = false; $numberOfIndents = 0; @@ -190,12 +248,15 @@ private static function writeMultiLineKeys ( ); } - private static function writeInlineValues ( - string $parameterFollowUp, - string $pathToFile, - int $numberOfIndents, - string $parameterKey = "" - ): void + /** + * Write a value that spans only a single line out to the file. + * + * @param string $parameterFollowUp The parameter value to write out to the file. + * @param string $pathToFile The path leading to the file to write out to. + * @param int $numberOfIndents The number of indents to be added to the file before it is written out to the yaml file. + * @param string $parameterKey The key attached to the value (in the case it is a "yaml object"). + */ + private static function writeInlineValues (string $parameterFollowUp, string $pathToFile, int $numberOfIndents, string $parameterKey = ""): void { $outputString = "{ " . $parameterKey . ": " . $parameterFollowUp . " }\n"; @@ -209,12 +270,15 @@ private static function writeInlineValues ( ); } - private static function writeMultiLineValues( - array $parameterFollowUp, - string $pathToFile, - int $numberOfIndents, - string $parameterKey = "" - ): void + /** + * Write out values that span multiple lines to the file (lists or multiple objects). + * + * @param array $parameterFollowUp The value to be written out to the file. + * @param string $pathToFile The path to the file to be written to. + * @param int $numberOfIndents The number of indents to be added to every written line of the file. + * @param string $parameterKey The key attached to the value (is optional and can be empty, which signals a list). + */ + private static function writeMultiLineValues(array $parameterFollowUp, string $pathToFile, int $numberOfIndents, string $parameterKey = ""): void { if (strlen($parameterKey) > 0) { self::$filesystem->appendToFile( @@ -232,11 +296,17 @@ private static function writeMultiLineValues( ); } - private static function buildOutputString ( - string $input, - int $numberOfIndents, - bool $isKey = false - ): string { + /** + * Adds various markings and elements of a typical yaml string to the given input in order to create a valid yaml string. + * + * @param string $input The string to be edited. + * @param int $numberOfIndents The number of indents to be placed in front of the given line. + * @param bool $isKey An optional boolean stating whether the given string is a key (and only a key). + * + * @return string Returns the formatted string. + */ + private static function buildOutputString (string $input, int $numberOfIndents, bool $isKey = false): string + { if (!(strlen(trim($input)) > 0)) { return ""; } diff --git a/src/ConfigProcessorBundle/ProcessedParamModel.php b/src/ConfigProcessorBundle/ProcessedParamModel.php index 0f0b0f7..6bf7fea 100644 --- a/src/ConfigProcessorBundle/ProcessedParamModel.php +++ b/src/ConfigProcessorBundle/ProcessedParamModel.php @@ -16,14 +16,12 @@ class ProcessedParamModel implements Serializable { /** - * Stores the key (the namespace) the parameters belong to. - * @var string + * @var string Stores the key (the namespace) the parameters belong to. */ private $key; /** - * Stores the corresponding parameters of the namespace in an array. - * @var array + * @var array Stores the corresponding parameters of the namespace in an array. */ private $parameters; @@ -34,7 +32,7 @@ public function __construct(string $key) } /** - * @return string + * @return string Returns the key associated with the object. */ public function getKey(): string { @@ -42,7 +40,7 @@ public function getKey(): string } /** - * @return array + * @return array Returns the parameters associated with the object. */ public function getParameters(): array { @@ -50,7 +48,7 @@ public function getParameters(): array } /** - * @param string $key + * @param string $key Allows a key to be set for the object. */ public function setKey(string $key): void { @@ -58,7 +56,7 @@ public function setKey(string $key): void } /** - * @param array $parameters + * @param array $parameters Set the parameters of the object. */ public function setParameters(array $parameters): void { @@ -71,7 +69,8 @@ public function setParameters(array $parameters): void * @param array $keys A list of keys which describe the path through the data structure and to which node to add the values * @param array $valueArray A list of values the final node will be passed as parameters. */ - public function addParameter(array $keys, array $valueArray = []) { + public function addParameter(array $keys, array $valueArray = []): void + { $modelToAddTo = $this->constructByKeys($keys); // Is there anything to add? @@ -90,7 +89,8 @@ public function addParameter(array $keys, array $valueArray = []) { * * @return array Returns an array that contains all parameters and their values */ - public function reformatForOutput() { + public function reformatForOutput(): array + { $outputArray = []; $endOfBranch = $this->isFreeOfProcessedParamModels($this->parameters); @@ -123,17 +123,19 @@ public function reformatForOutput() { } /** - * Searches for a child who's key matches the siteaccess if one is found then it will be returned. In any + * Searches for a child who's key matches the site access if one is found then it will be returned. In any * other case false is given back. * - * @param string $siteaccess The access to search for in the key. + * @param string $siteAccess The access to search for in the key. + * * @return ProcessedParamModel|false Returns either the object that matches or false if nothing matches. */ - public function filterForSiteAccess(string $siteaccess) { + public function filterForSiteAccess(string $siteAccess) + { foreach ($this->parameters as $parameter) { if ( $parameter instanceof ProcessedParamModel && - $parameter->getKey() === $siteaccess + $parameter->getKey() === $siteAccess ) { return $parameter; } @@ -146,10 +148,11 @@ public function filterForSiteAccess(string $siteaccess) { * Recursively looks through the parameters of the model and tries to find the model with the given key. * When found, the model will be removed and returned. If not, false is returned. * - * @param string $key The key - * @return array | false; + * @param string $key The key of the object to be removed. + * @return array | false Returns the removed object or false if it could not be removed or wasn't found. */ - public function removeParamModel(string $key) { + public function removeParamModel(string $key) + { for ($i = 0; $i < count($this->parameters); ++$i) { if ($this->parameters[$i] instanceof ProcessedParamModel) { @@ -234,7 +237,8 @@ public function unserialize($serialized) * @param array $keys Given list of keys after which to construct the "key-list" tree-like structure in the parameters. * @return ProcessedParamModel Returns the model where the last key of the given list is stored. */ - private function constructByKeys(array $keys): ProcessedParamModel { + private function constructByKeys(array $keys): ProcessedParamModel + { $paramCarrier = $this->determineIfKeyIsPresent($keys); $foundOnLevel = array_search($paramCarrier->key,$keys); @@ -254,9 +258,10 @@ private function constructByKeys(array $keys): ProcessedParamModel { * * @param array $keys Given array of keys that will be searched for in the parameters of the object. * @param int $level Number that states what key to search for in the array in the next run of the function. + * * @return $this Returns the object the function has last been called unsuccessfully on. That means the object where the last key was found is returned. */ - private function determineIfKeyIsPresent(array $keys, int $level = 1) + private function determineIfKeyIsPresent(array $keys, int $level = 1): ProcessedParamModel { if ($level < count($keys)) { foreach ($this->parameters as $entry) { @@ -273,15 +278,25 @@ private function determineIfKeyIsPresent(array $keys, int $level = 1) * Private function of the model which adds an entire new ProcessedParamModel object into the parameter list. * * @param ProcessedParamModel $paramModel The model to add to the parameters (typically means there have been more keys in the given key list then are present in the existing parameters. + * * @return ProcessedParamModel Returns itself in order to allow further operations on itself. */ - private function addParamModel(ProcessedParamModel $paramModel): ProcessedParamModel { + private function addParamModel(ProcessedParamModel $paramModel): ProcessedParamModel + { array_push($this->parameters,$paramModel); return $paramModel; } - private function isFreeOfProcessedParamModels(array $childrenToSearchThrough): bool { + /** + * Determines whether a given array does not contain a single ProcessedParamModel. + * + * @param array $childrenToSearchThrough Array of elements to check. + * + * @return bool Returns true if no ProcessedParamModels could be found in the array or false if there was at least one positive result. + */ + private function isFreeOfProcessedParamModels(array $childrenToSearchThrough): bool + { foreach ($childrenToSearchThrough as $child) { if ($child instanceof ProcessedParamModel) { return false; diff --git a/src/ConfigProcessorBundle/SiteAccessParamProcessor.php b/src/ConfigProcessorBundle/SiteAccessParamProcessor.php index 110a35b..e924d8d 100644 --- a/src/ConfigProcessorBundle/SiteAccessParamProcessor.php +++ b/src/ConfigProcessorBundle/SiteAccessParamProcessor.php @@ -9,7 +9,7 @@ /** * Class SiteAccessParamProcessor serves to take the processed parameters and determine not only which parameters are - * active within that siteaccess, but also what value that parameter holds under these circumstances and reformat them + * active within that site access, but also what value that parameter holds under these circumstances and reformat them * for output. * * @package CJW\CJWConfigProcessor\ConfigProcessorBundle\src @@ -17,9 +17,7 @@ class SiteAccessParamProcessor { /** - * Holds the ezplatform / -systems config resolver with which to work out the values for the parameters. - * - * @var ConfigResolverInterface + * @var ConfigResolverInterface Holds the ezPlatform / -systems config resolver with which to work out the values for the parameters. */ private $ezConfigResolver; @@ -29,7 +27,7 @@ public function __construct(ConfigResolverInterface $resolver) } /** - * @param ConfigResolverInterface $ezConfigResolver + * @param ConfigResolverInterface $ezConfigResolver Set the config resolver to be used by the class. */ public function setEzConfigResolver(ConfigResolverInterface $ezConfigResolver): void { @@ -37,16 +35,18 @@ public function setEzConfigResolver(ConfigResolverInterface $ezConfigResolver): } /** - * Function to filter and resolve all parameters given to the function via a list of siteaccesses. - * That means that only values belonging to siteaccesses will be kept in the array and processed + * Function to filter and resolve all parameters given to the function via a list of site accesses. + * That means that only values belonging to site accesses will be kept in the array and processed * further and their values will be resolved. * - * @param array $siteAccesses The list of siteaccesses to filter for in the parameters. + * @param array $siteAccesses The list of site accesses to filter for in the parameters. * @param array $parameters The parameters to be filtered and processed. - * @param string|null $scope Optional parameter which determines whether a specific scope should be used for determining the parameter values or simply the current one. + * @param string|null $scope Optional parameter which determines whether a specific scope should be used for + * determining the parameter values or simply the current one. + * * @return array Returns an array that possesses only unique parameters and their current value. */ - public function processSiteAccessBased(array $siteAccesses, array $parameters, string $scope = null) + public function processSiteAccessBased(array $siteAccesses, array $parameters, string $scope = null): array { $siteAccessParameters = $this->filterForSiteAccess($siteAccesses, $parameters); $uniqueSiteAccessParameters = $this->provideUniqueParameters($siteAccessParameters); @@ -66,15 +66,16 @@ public function processSiteAccessBased(array $siteAccesses, array $parameters, s } /** - * Takes a given list of siteaccesses and searches in the given parameters array for every + * Takes a given list of site accesses and searches in the given parameters array for every * parameter that features at least one of the accesses. If one or more are found, than these * parts of the parameter are being pushed onto the result. * - * @param array $siteAccesses The list of siteaccesses to search for. + * @param array $siteAccesses The list of site accesses to search for. * @param array $parameters The array of parameters in which to search. + * * @return array Returns the resulting array which consists of all found parameter parts. */ - private function filterForSiteAccess(array $siteAccesses, array $parameters) + private function filterForSiteAccess(array $siteAccesses, array $parameters): array { $resultArray = []; @@ -97,9 +98,10 @@ private function filterForSiteAccess(array $siteAccesses, array $parameters) * access. As a result, the array only contains unique parameters for further processing. * * @param array $siteAccessParameters The parameters to be processed. + * * @return array Returns an array that includes only unique parameters. */ - private function provideUniqueParameters(array $siteAccessParameters) + private function provideUniqueParameters(array $siteAccessParameters): array { $uniqueParameters = $siteAccessParameters; $encounteredParamNames = []; @@ -137,7 +139,7 @@ private function provideUniqueParameters(array $siteAccessParameters) * * @throws Exception Throws an exception if there hasn't been a valid configResolver set for the object. */ - private function resolveParameters(array $filteredParameters) + private function resolveParameters(array $filteredParameters): array { if (!$this->ezConfigResolver) { throw new Exception("No configResolver has been set for this object."); @@ -168,12 +170,14 @@ private function resolveParameters(array $filteredParameters) * * might be reworked to better fit the bundle's coding standard. * - * @param array $filteredParameters - * @param string $scope - * @return array - * @throws Exception + * @param array $filteredParameters The filtered parameter list which is being resolved to the actual currently set parameters. + * @param string $scope The specific site access for which to retrieve the parameter value. + * + * @return array Returns the resolved Parameters. + * + * @throws Exception Throws an exception if there hasn't been a valid configResolver set for the object. */ - private function resolveParametersWithScope(array $filteredParameters, string $scope) + private function resolveParametersWithScope(array $filteredParameters, string $scope): array { if (!$this->ezConfigResolver) { throw new Exception("No configResolver has been set for this object."); @@ -196,9 +200,10 @@ private function resolveParametersWithScope(array $filteredParameters, string $s * Rearranges the array's keys in alphabetical order for easier navigation. * * @param array $processedSiteAccessParameters Parameters to be sorted. + * * @return array Returns the reformatted array. */ - private function reformatForOutput(array $processedSiteAccessParameters) + private function reformatForOutput(array $processedSiteAccessParameters): array { ksort($processedSiteAccessParameters, SORT_STRING); diff --git a/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php b/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php index 7b1dc94..24a248b 100644 --- a/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php +++ b/src/LocationAwareConfigLoadBundle/ConfigPathUtility.php @@ -20,25 +20,40 @@ class ConfigPathUtility { - /** @var string The assortment of file extensions which can be used to configure symfony. */ + /** + * @var string The assortment of file extensions which can be used to configure symfony. + */ private static $configExtensions = ""; - /** @var array Stores all added configuration paths */ + /** + * @var array Stores all added configuration paths + */ private static $configPaths = []; - /** @var PhpFilesAdapter A cache for the routes that have been determined throughout the previous loading processes. */ + /** + * @var PhpFilesAdapter A cache for the routes that have been determined throughout the previous loading processes. + */ private static $configPathCache; - /** @var bool States whether it has been tried to retrieve the existing paths from the cache already / the cache has been initialised. */ + /** + * @var bool States whether it has been tried to retrieve the existing paths from the cache already / the cache has been initialised. + */ private static $cacheInitialized = false; - /** @var bool States whether there has been a change in paths (this only occurs through adding a path (for now)). */ + /** + * @var bool States whether there has been a change in paths (this only occurs through adding a path (for now)). + */ private static $pathsChanged = false; - /** @var bool This boolean states whether there has been a change to the paths that warrants the kernel and thereby load process to be restarted to include the newly found paths. */ + /** + * @var bool This boolean states whether there has been a change to the paths that warrants the kernel and + * thereby load process to be restarted to include the newly found paths. + */ private static $restartLoadProcess = false; - /** @var string The directory in which to cache all the routes (in order to prevent the cache from being stored only temporarily) */ + /** + * @var string The directory in which to cache all the routes (in order to prevent the cache from being stored only temporarily) + */ private static $cacheDir = null; /** @@ -86,6 +101,7 @@ public static function initializePathUtility(): void *
But, paths which point to a file / directory which does not exist, are not added to the paths list. * * @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): ?string @@ -116,7 +132,7 @@ public static function convertExtensionPathToConfigDirectory(string $extensionPa * that the path list has been changed. * * @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. + * @param bool $isGlobPattern An (optional) 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 { @@ -195,7 +211,9 @@ public static function setConfigExtensions(string $configExtensions): void } /** - * @param string $cacheDir + * Sets the cache directory for this class of the bundle, based on the general cache path of the installation. + * + * @param string $cacheDir The blank, standard cache path of the project. */ public static function setCacheDir(string $cacheDir): void { @@ -217,7 +235,9 @@ private static function getUserDefinedPaths(): void $userDefinedConfigPaths = $parser->parseFile($pathToConfigRoutes); // Are there even parameters set in the file? If not, then just initiate the variable as an empty array - $configPaths = (is_array($userDefinedConfigPaths) && key_exists("parameters",$userDefinedConfigPaths))? $userDefinedConfigPaths["parameters"] : []; + $configPaths = + (is_array($userDefinedConfigPaths) && key_exists("parameters",$userDefinedConfigPaths)) ? + $userDefinedConfigPaths["parameters"] : []; foreach ($configPaths as $pathName => $pathInfo) { // First check, whether some basic information is set for the defined routes (to see whether they can be worked with) @@ -234,6 +254,7 @@ private static function getUserDefinedPaths(): void * Checks the user defined paths for any kind of errors with regards to the definition of said paths. * * @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 diff --git a/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php b/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php index 951aa3a..b3796bf 100644 --- a/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php +++ b/src/LocationAwareConfigLoadBundle/CustomContainerBuilder.php @@ -20,6 +20,9 @@ */ class CustomContainerBuilder extends ContainerBuilder { + /** + * @var bool Boolean which determines whether the bundle configuration mode is active or not. + */ private $isBundleConfigMode; public function __construct() @@ -73,7 +76,7 @@ public function compile(bool $resolveEnvPlaceholders = false) * * @return array Returns the found configuration. */ - public function getExtensionConfig(string $name) + public function getExtensionConfig(string $name): array { try { // Get the class of the extension, then generate a Reflection class out of that, which allows finding the path to the file, then set that path @@ -103,10 +106,10 @@ public function getExtensionConfig(string $name) * * @param array $definitions */ - public function addDefinitions(array $definitions) + public function addDefinitions(array $definitions): void { if (!$this->isBundleConfigMode) { - parent::addDefinitions($definitions); // TODO: Change the autogenerated stub + parent::addDefinitions($definitions); } } @@ -123,7 +126,7 @@ public function addDefinitions(array $definitions) public function register(string $id, string $class = null): ?Definition { if (!$this->isBundleConfigMode) { - return parent::register($id, $class); // TODO: Change the autogenerated stub + return parent::register($id, $class); } return null; @@ -142,7 +145,7 @@ public function register(string $id, string $class = null): ?Definition public function setDefinition(string $id, Definition $definition): ?Definition { if (!$this->isBundleConfigMode) { - return parent::setDefinition($id, $definition); // TODO: Change the autogenerated stub + return parent::setDefinition($id, $definition); } return null; @@ -185,7 +188,8 @@ public function setDefinitions(array $definitions) * Dictates whether bundle config paths are being loaded outside of the bundle configuration part of the * config load process (namely the {@see MergeExtensionConfigurationPass}). * - * @param bool $isBundleConfigMode A boolean which sets the bundleConfigMode either to true or false (if set to true, no services will be registered to the container). + * @param bool $isBundleConfigMode A boolean which sets the bundleConfigMode either to true or false + * (if set to true, no services will be registered to the container). */ public function setIsBundleConfigMode(bool $isBundleConfigMode): void { diff --git a/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php b/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php index 27526ba..3f54f97 100644 --- a/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php +++ b/src/LocationAwareConfigLoadBundle/CustomDelegatingLoader.php @@ -17,7 +17,9 @@ class CustomDelegatingLoader extends DelegatingLoader { - /** @var CustomContainerBuilder A container builder which serves to build the container while keeping track of the files used to do so. */ + /** + * @var CustomContainerBuilder A container builder which serves to build the container while keeping track of the files used to do so. + */ private $container; public function __construct(LoaderResolverInterface $resolver, CustomContainerBuilder $containerBuilder) diff --git a/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php b/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php index bad28d9..cb98ec7 100644 --- a/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php +++ b/src/LocationAwareConfigLoadBundle/CustomGlobLoader.php @@ -19,7 +19,6 @@ */ class CustomGlobLoader extends GlobFileLoader { - /** * CustomGlobLoader constructor. Its only difference is, that instead of taking a "normal" ContainerBuilder or -Interface, * this constructor takes a CustomContainerBuilder in order to ensure compatibility with the rest of the location-aware diff --git a/src/LocationAwareConfigLoadBundle/CustomValueStorage.php b/src/LocationAwareConfigLoadBundle/CustomValueStorage.php index faff2db..acfee7d 100644 --- a/src/LocationAwareConfigLoadBundle/CustomValueStorage.php +++ b/src/LocationAwareConfigLoadBundle/CustomValueStorage.php @@ -46,7 +46,7 @@ class CustomValueStorage * overwritten and the first value is **not** stored separately in the array. * * @param string $parameterName The name of the parameter to add. This serves as a key for the then following entries into the array. - * @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 mixed $value The value attached to both the parameter name 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): void diff --git a/src/LocationAwareConfigLoadBundle/LoadInitializer.php b/src/LocationAwareConfigLoadBundle/LoadInitializer.php index b4a1bc6..70bd82e 100644 --- a/src/LocationAwareConfigLoadBundle/LoadInitializer.php +++ b/src/LocationAwareConfigLoadBundle/LoadInitializer.php @@ -154,8 +154,9 @@ protected function getContainerBuilder(): CustomContainerBuilder /** * @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. + * + * Overrides the standard kernel function to configure the container in order to incorporate the custom paths + * that have been gathered during the custom load process. * * @param ContainerBuilder $container * @param LoaderInterface $loader diff --git a/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php b/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php index a7da293..f64ca77 100644 --- a/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php +++ b/src/LocationAwareConfigLoadBundle/LocationRetrievalCoordinator.php @@ -25,17 +25,17 @@ class LocationRetrievalCoordinator 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 parameters that have been parsed. */ private static $cache; /** - * @var bool + * @var bool Boolean which describes whether the class has been instantiated and all important attributes of it have been initialized. */ private static $initialized = false; @@ -91,7 +91,8 @@ public static function initializeCoordinator(): void /** * 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. + * @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 { @@ -108,8 +109,10 @@ public static function getParametersAndLocations(): array * 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. + * @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. */ @@ -127,8 +130,10 @@ public static function getParameterLocations (string $parameterName, array $site * the parameters, values or other information. It resembles a plain "stack" of locations. * * @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. + * @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. */ diff --git a/src/Utility/Utility.php b/src/Utility/Utility.php index 5733b00..5a3ee43 100644 --- a/src/Utility/Utility.php +++ b/src/Utility/Utility.php @@ -177,7 +177,8 @@ public static function determinePureSiteAccessGroups (array $processedParameterA * 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. + * @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. */ @@ -212,7 +213,8 @@ public static function removeEntryThroughKeyList (array $parameters, array $keyL * @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). + * @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 {