From 3910fef5d45028e8bfb8891bec5781821998dc36 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:14 +0200 Subject: [PATCH 01/75] Make it a bundle --- .gitignore | 3 +- .../AbstractModuleNavigation.php | 705 ---------------- .../ModuleNavigationChainPreorder.php | 51 -- .../ModuleNavigationMenu.php | 288 ------- .../backboneit_navigation/NavigationDCA.php | 39 - .../backboneit_navigation/config/.htaccess | 2 - .../backboneit_navigation/config/autoload.ini | 19 - .../backboneit_navigation/config/autoload.php | 22 - .../backboneit_navigation/config/config.php | 4 - .../backboneit_navigation/dca/.htaccess | 2 - .../languages/de/.htaccess | 2 - .../mod_backboneit_navigation_menu.xhtml | 13 - .../templates/nav_bbit.xhtml | 16 - build.xml | 34 - composer.json | 41 +- ext/yui-compressor/yui.xml | 92 -- ext/yui-compressor/yuicompressor-2.4.2.jar | Bin 851219 -> 0 bytes src/ContaoManager/Plugin.php | 24 + src/EventListener/Dca/NavigationDCA.php | 54 ++ .../AbstractModuleNavigation.php | 787 ++++++++++++++++++ src/FrontendModule/ModuleNavigationMenu.php | 330 ++++++++ src/HofffContaoNavigationBundle.php | 12 + src/Resources/contao/config/config.php | 5 + .../Resources/contao}/config/database.sql | 0 .../Resources/contao}/dca/tl_module.php | 0 .../contao}/languages/de/modules.php | 0 .../contao}/languages/de/tl_module.php | 0 .../mod_backboneit_navigation_menu.html5 | 0 .../contao}/templates/nav_bbit.html5 | 0 29 files changed, 1245 insertions(+), 1300 deletions(-) delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/AbstractModuleNavigation.php delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationChainPreorder.php delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationMenu.php delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/NavigationDCA.php delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/config/.htaccess delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/config/autoload.ini delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/config/autoload.php delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/config/config.php delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/dca/.htaccess delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/languages/de/.htaccess delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/templates/mod_backboneit_navigation_menu.xhtml delete mode 100644 TL_ROOT/system/modules/backboneit_navigation/templates/nav_bbit.xhtml delete mode 100644 build.xml delete mode 100644 ext/yui-compressor/yui.xml delete mode 100644 ext/yui-compressor/yuicompressor-2.4.2.jar create mode 100644 src/ContaoManager/Plugin.php create mode 100644 src/EventListener/Dca/NavigationDCA.php create mode 100644 src/FrontendModule/AbstractModuleNavigation.php create mode 100644 src/FrontendModule/ModuleNavigationMenu.php create mode 100644 src/HofffContaoNavigationBundle.php create mode 100644 src/Resources/contao/config/config.php rename {TL_ROOT/system/modules/backboneit_navigation => src/Resources/contao}/config/database.sql (100%) rename {TL_ROOT/system/modules/backboneit_navigation => src/Resources/contao}/dca/tl_module.php (100%) rename {TL_ROOT/system/modules/backboneit_navigation => src/Resources/contao}/languages/de/modules.php (100%) rename {TL_ROOT/system/modules/backboneit_navigation => src/Resources/contao}/languages/de/tl_module.php (100%) rename {TL_ROOT/system/modules/backboneit_navigation => src/Resources/contao}/templates/mod_backboneit_navigation_menu.html5 (100%) rename {TL_ROOT/system/modules/backboneit_navigation => src/Resources/contao}/templates/nav_bbit.html5 (100%) diff --git a/.gitignore b/.gitignore index f2870aa..feb1d99 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ !/publish/ !/build.xml !/README.md -!/composer.json \ No newline at end of file +!/composer.json +!/src diff --git a/TL_ROOT/system/modules/backboneit_navigation/AbstractModuleNavigation.php b/TL_ROOT/system/modules/backboneit_navigation/AbstractModuleNavigation.php deleted file mode 100644 index aae5129..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/AbstractModuleNavigation.php +++ /dev/null @@ -1,705 +0,0 @@ - the ID of the current item (optional) - * isTrail => whether this item is in the trail path - * class => CSS classes - * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities - * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities - * link => page name (with Insert-Tags and XML specialchars NOT replaced; as stored in the db) - * href => URL of target page - * nofollow => true, if nofollow should be set on rel attribute - * target => either ' onclick="window.open(this.href); return false;"' or empty string - * description => page description with line breaks (\r and \n) replaced by whitespaces - * - * Calculated while rendering: - * subitems => subnavigation as HTML string or empty string (rendered if subpages & items setup correctly) - * isActive => whether this item is the current active navigation item - * - * Following CSS classes are calculated while rendering: level_x, trail, sibling, submenu, first, last - * - * Additionally all page dataset values from the database are available unter their field name, - * if the field name does not collide with the listed keys. - * - * For the collisions of the Contao core page dataset fields the following keys are available: - * _type - * _title - * _pageTitle - * _target - * _description - * - * @author Oliver Hoff - */ -abstract class AbstractModuleNavigation extends Module { - - const HOOK_DISABLE = 0; - const HOOK_ENABLE = 1; - const HOOK_FORCE = 2; - - public static $arrDefaultFields = array( - 'id' => true, - 'pid' => true, - 'sorting' => true, - 'tstamp' => true, - 'type' => true, - 'alias' => true, - 'title' => true, - 'protected' => true, - 'groups' => true, - 'jumpTo' => true, - 'pageTitle' => true, - 'target' => true, - 'description' => true, - 'url' => true, - 'robots' => true, - 'cssClass' => true, - 'accesskey' => true, - 'tabindex' => true - ); - - protected $arrFields = array(); // the fields to use for navigation tpl - protected $strJumpToQuery; - protected $strJumpToFallbackQuery; - - protected $objStmt; // a reusable stmt object - - protected $arrGroups; // set of groups of the current user - protected $arrTrail; // same as trail but with current page included - - public $varActiveID; // the id of the active page - - public $arrItems = array(); // compiled page datasets - public $arrSubitems = array(); // ordered IDs of subnavigations - /** @Deprecated */ public $arrSubpages; - - protected $blnTreeHook = false; // execute tree hook? - protected $blnItemHook = false; // execute item hook? - - public function __construct($objModule, $strColumn = 'main') { - parent::__construct($objModule, $strColumn); - if(TL_MODE == 'BE') - return; - - $this->arrSubpages = &$this->arrSubitems; // for deprecated compat - - $this->import('Database'); - - $this->varActiveID = $this->backboneit_navigation_isSitemap || $this->Input->get('articles') ? false : $GLOBALS['objPage']->id; - $this->arrTrail = array_flip($GLOBALS['objPage']->trail); - - if(FE_USER_LOGGED_IN) { - $this->import('FrontendUser', 'User'); - $this->User->groups && $this->arrGroups = $this->User->groups; - } - - if(!strlen($this->navigationTpl)) - $this->navigationTpl = 'nav_default'; - - $arrFields = deserialize($this->backboneit_navigation_addFields, true); - - if(count($arrFields) > 10) { - $this->arrFields[] = '*'; - - } elseif($arrFields) { - $arrFields = array_flip($arrFields); - foreach($this->Database->listFields('tl_page') as $arrField) - if(isset($arrFields[$arrField['name']])) - $this->arrFields[$arrField['name']] = true; - - $this->arrFields = array_keys(array_merge($this->arrFields, self::$arrDefaultFields)); - - } else { - $this->arrFields = array_keys(self::$arrDefaultFields); - } - - $this->objStmt = $this->Database->prepare('*'); - - $arrConditions = array( - $this->getQueryPartGuests(), - $this->getQueryPartPublish() - ); - $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - $strConditions && $strConditions = ' AND (' . $strConditions . ')'; - - $this->strJumpToQuery = - 'SELECT * - FROM tl_page - WHERE id = ? - ' . $strConditions . ' - LIMIT 0, 1'; - - $this->strJumpToFallbackQuery = - 'SELECT * - FROM tl_page - WHERE pid = ? - AND type = \'regular\' - ' . $strConditions . ' - ORDER BY sorting - LIMIT 0, 1'; - - if(!$this->backboneit_navigation_disableHooks) { - $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_tree']); - $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['bbit_navi_item']); - } - } - - public function __get($strKey) { - switch($strKey) { - case 'strJumpToFallbackQuery': - case 'strJumpToQuery': - case 'arrFields': - case 'arrGroups': - case 'arrTrail': - return $this->$strKey; - } - return parent::__get($strKey); - } - - /** - * Filters the given array of page IDs in regard of publish state, - * required permissions (protected and guests only) and hidden state, according to - * this navigations settings. - * Maintains relative order of the input array. - * - * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages - * contains no hazardous code. - * - * @param array $arrPages An array of page IDs to filter - * @return array Filtered array of page IDs - */ - public function filterPages(array $arrPages, $strConditions = '') { - if(!$arrPages) - return $arrPages; - - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - $objPage = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' - FROM tl_page - WHERE id IN (' . implode(',', array_keys(array_flip($arrPages))) . ') - ' . $strConditions - ); - - if(!$this->isPermissionCheckRequired()) - return array_intersect($arrPages, $objPage->fetchEach('id')); // restore order - - $arrPIDs = array(); - $arrValid = array(); - while($arrPage = $objPage->fetchAssoc()) { - if($this->isPermissionDenied($arrPage)) - continue; - - $arrValid[] = $arrPage['id']; - /* - * do not remove the protected check! permission denied checks for - * more, but we need to know, if we must recurse to parent pages, - * for permission check, which must not be done, when this page - * defines access rights. - */ - if(!$arrPage['protected'] && $arrPage['pid'] != 0) - $arrPIDs[$arrPage['pid']][] = $arrPage['id']; - } - - // exclude pages which are in a protected path - while(count($arrPIDs)) { - $arrIDs = $arrPIDs; - $arrPIDs = array(); - - $objPage = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' - FROM tl_page - WHERE id IN (' . implode(',', array_keys($arrIDs)) . ')' - ); - - while($arrPage = $objPage->fetchAssoc()) { - if(!$arrPage['protected']) { // do not remove, see above - if($arrPage['pid'] != 0) { - $arrPIDs[$arrPage['pid']] = isset($arrPIDs[$arrPage['pid']]) - ? array_merge($arrPIDs[$arrPage['pid']], $arrIDs[$arrPage['id']]) - : $arrIDs[$arrPage['id']]; - } - } elseif($this->isPermissionDenied($arrPage)) { - $arrValid = array_diff($arrValid, $arrIDs[$arrPage['id']]); - } - } - } - - return array_intersect($arrPages, $arrValid); - } - - /** - * Retrieves the subpages of the given array of page IDs in respect of the - * given conditions, which are added to the WHERE clause of the query. - * Maintains relative order of the input array. - * - * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages - * contains no hazardous code. - * - * @param array $arrPages An array of parent IDs - * @return array The child IDs - */ - public function getNextLevel(array $arrPages, $strConditions = '') { - if(!$arrPages) - return $arrPages; - - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - $objNext = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' - FROM tl_page - WHERE pid IN (' . implode(',', array_keys(array_flip($arrPages))) . ') - ' . $strConditions . ' - ORDER BY sorting' - ); - - $arrNext = array(); - if($this->isPermissionCheckRequired()) { - while($arrPage = $objNext->fetchAssoc()) - if(!$this->isPermissionDenied($arrPage)) - $arrNext[$arrPage['pid']][] = $arrPage['id']; - } else { - while($arrPage = $objNext->fetchAssoc()) - $arrNext[$arrPage['pid']][] = $arrPage['id']; - } - - $arrNextLevel = array(); - foreach($arrPages as $intID) - if(isset($arrNext[$intID])) - $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); - - return $arrNextLevel; - } - - /** - * Retrieves the parents of the given array of page IDs in respect of the - * given conditions, which are added to the WHERE clause of the query. - * Maintains relative order of the input array and merges subsequent parent - * IDs. - * - * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages - * contains no hazardous code. - * - * @param array $arrPages An array of child IDs - * @return array The parent IDs - */ - public function getPrevLevel(array $arrPages, $strConditions = '') { - if(!$arrPages) - return $arrPages; - - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - $objPrev = $this->objStmt->query( - 'SELECT id, pid - FROM tl_page - WHERE id IN (' . implode(',', array_keys(array_flip($arrPages))) . ') - ' . $strConditions - ); - - $arrPrev = array(); - while($objPrev->next()) - $arrPrev[$objPrev->id] = $objPrev->pid; - - $arrPrevLevel = array(); - $intPID = -1; - foreach($arrPages as $intID) - if(isset($arrPrev[$intID]) && $arrPrev[$intID] != $intPID) - $arrPrevLevel[] = $intPID = $arrPrev[$intID]; - - return $arrPrevLevel; - } - - - /** - * Renders the navigation of the given IDs into the navigation template. - * Adds CSS classes "first" and "last" to the appropriate navigation item arrays. - * If the given array is empty, the empty string is returned. - * - * @param array $arrRoots The navigation items arrays - * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $intLevel (optional, defaults to 1) The current level of this navigation layer - * @return string The parsed navigation template, could be empty string. - */ - protected function renderNavigationTree(array $arrIDs, $strTemplate, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX, $intLevel = 1) { - if(!$arrIDs) - return ''; - - $arrStop = (array) $arrStop; - $arrStop || $arrStop = array(PHP_INT_MAX); - $intStop = $intLevel >= $arrStop[0] ? array_shift($arrStop) : $arrStop[0]; - $arrItems = array(); - - foreach($arrIDs as $varID) { - if(!$this->arrItems[$varID]) { - continue; - } - - $arrItem = $this->arrItems[$varID]; - - if($varID == $this->varActiveID) { - $blnContainsActive = true; - - if ($arrItem['href'] === Environment::get('request')) { - $arrItem['isActive'] = true; // nothing else (active class is set in template) - $arrItem['isTrail'] = false; - } else { - $arrItem['isActive'] = false; // nothing else (active class is set in template) - $arrItem['isTrail'] = true; - } - - } else { // do not flatten if/else - if($arrItem['tid'] == $this->varActiveID) { - if ($arrItem['href'] === Environment::get('request')) { - $arrItem['isActive'] = true; // nothing else (active class is set in template) - $arrItem['isTrail'] = false; - } else { - $arrItem['isActive'] = false; // nothing else (active class is set in template) - $arrItem['isTrail'] = true; - } - } - } - - if($arrItem['isTrail']) { - $arrItem['class'] .= ' trail'; - } - - if(!isset($this->arrSubitems[$varID])) { - $arrItem['class'] .= ' leaf'; - - } elseif($intLevel >= $intHard) { - // we are at hard level, never draw submenu - $arrItem['class'] .= ' submenu leaf'; - - } elseif($intLevel >= $intStop && !$arrItem['isTrail'] && $varID !== $this->varActiveID && $arrItem['tid'] != $this->varActiveID) { - // we are at stop level and not trail and not active, never draw submenu - $arrItem['class'] .= ' submenu leaf'; - - } elseif($this->arrSubitems[$varID]) { - $arrItem['class'] .= ' submenu inner'; - $arrItem['subitems'] = $this->renderNavigationTree( - $this->arrSubitems[$varID], $arrItem['template'], $arrStop, $intHard, $intLevel + 1 - ); - - } else { // should never be reached, if no hooks are used - $arrItem['class'] .= ' leaf'; - } - - $arrItems[] = $arrItem; - } - - if($blnContainsActive) - foreach($arrItems as &$arrItem) - if(!$arrItem['isActive']) - $arrItem['class'] .= ' sibling'; - - $arrItems[0]['class'] .= ' first'; - $arrItems[count($arrItems) - 1]['class'] .= ' last'; - - foreach($arrItems as &$arrItem) - $arrItem['class'] = ltrim($arrItem['class']); - - strlen($strTemplate) || $strTemplate = $this->navigationTpl; - $objTemplate = new FrontendTemplate($strTemplate); - $objTemplate->setData(array( - 'module' => $this->arrData, - 'level' => 'level_' . $intLevel, - 'items' => $arrItems, - 'type' => get_class($this) - )); - - return $objTemplate->parse(); - } - - /** - * Compiles a navigation item array from a page dataset with the given subnavi - * - * @param array $arrPage The page dataset as an array - * @return array The compiled navigation item array - */ - public function compileNavigationItem(array $arrPage, $blnForwardResolution = true, $intItemHook = self::HOOK_DISABLE) { - // fallback for dataset field collisions - $arrPage['_title'] = $arrPage['title']; - $arrPage['_pageTitle'] = $arrPage['pageTitle']; - $arrPage['_target'] = $arrPage['target']; - $arrPage['_description'] = $arrPage['description']; - - $arrPage['link'] = $arrPage['_title']; - $arrPage['class'] = $arrPage['cssClass'] . ' ' . $arrPage['type']; - $arrPage['title'] = specialchars($arrPage['_title'], true); - $arrPage['pageTitle'] = specialchars($arrPage['_pageTitle'], true); - $arrPage['target'] = ''; // overwrite DB value - $arrPage['nofollow'] = strncmp($arrPage['robots'], 'noindex', 7) === 0; - $arrPage['description'] = str_replace(array("\n", "\r"), array(' ' , ''), $arrPage['_description']); - $arrPage['isTrail'] = isset($this->arrTrail[$arrPage['id']]); - - switch($arrPage['type']) { - case 'forward': - if($blnForwardResolution) { - if($arrPage['jumpTo']) { - $intFallbackSearchID = $arrPage['id']; - $intJumpToID = $arrPage['jumpTo']; - do { - $objNext = $this->objStmt->prepare($this->strJumpToQuery)->execute($intJumpToID); - - if(!$objNext->numRows) { - $objNext = $this->objStmt->prepare($this->strJumpToFallbackQuery)->execute($intFallbackSearchID); - break; - } - - $intFallbackSearchID = $intJumpToID; - $intJumpToID = $objNext->jumpTo; - - } while($objNext->type == 'forward'); - - } else { - $objNext = $this->objStmt->prepare($this->strJumpToFallbackQuery)->execute($arrPage['id']); - } - - if(!$objNext->numRows) { - $arrPage['href'] = $this->generatePageUrl($arrPage); - - } elseif($objNext->type == 'redirect') { - $arrPage['href'] = $this->encodeEmailURL($objNext->url); - $arrPage['target'] = $objNext->target ? LINK_NEW_WINDOW : ''; - - } else { - $arrPage['tid'] = $objNext->id; - $arrPage['href'] = $this->generatePageUrl($objNext->row()); - } - } else { - $arrPage['tid'] = $arrPage['jumpTo']; - $arrPage['href'] = $this->generatePageUrl($arrPage); - } - break; - - case 'redirect': - $arrPage['href'] = $this->encodeEmailURL($arrPage['url']); - $arrPage['target'] = $arrPage['_target'] ? LINK_NEW_WINDOW : ''; - break; - - case 'root': - if(!$arrPage['dns'] - || preg_replace('/^www\./', '', $arrPage['dns']) == preg_replace('/^www\./', '', $this->Environment->httpHost)) { - $arrPage['href'] = $this->Environment->base; - break; // we only break on root pages; pages in different roots should be handled by DomainLink extension - } - // do not break - - default: - case 'regular': - case 'error_401': - case 'error_403': - case 'error_404': - $arrPage['href'] = $this->generatePageUrl($arrPage); - break; - } - - if($intItemHook != self::HOOK_DISABLE) { - $this->executeItemHook($arrPage, $intItemHook == self::HOOK_FORCE); - } - - return $arrPage; - } - - /** - * Utility method of compileNavigationItem. - * - * If the given URL starts with "mailto:", the E-Mail is encoded, - * otherwise nothing is done. - * - * @param string $strHref The URL to check and possibly encode - * @return string The modified URL - */ - public function encodeEmailURL($strHref) { - if(strncasecmp($strHref, 'mailto:', 7) !== 0) - return $strHref; - - if (version_compare(VERSION . '.' . BUILD, '3.5.5', '>=')) { - return \StringUtil::encodeEmail($strHref); - } else { - return \String::encodeEmail($strHref); - } - } - - public function isPermissionCheckRequired() { - return !BE_USER_LOGGED_IN && !$this->backboneit_navigation_showProtected; - } - - /** - * Utility method. - * - * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! - * - * Checks if the current user has no permission to view the page of the - * given page dataset, in regards to the permission requirements of the - * page. - * - * @param array $arrPage The page dataset of the current page, with at least - * groups and protected attributes set. - * - * @return boolean If the permission is denied true, otherwise false. - */ - public function isPermissionDenied($arrPage) { - if(!$arrPage['protected']) // this page is not protected - return false; - - if(!$this->arrGroups) // the current user is not in any group - return true; - - // check if the current user is not in any group, which is allowed to access the current page - return !array_intersect($this->arrGroups, deserialize($arrPage['groups'], true)); - } - - /** - * Utility method. - * - * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! - * - * Checks if the current user has permission to view the page of the given - * page dataset, in regards to the current navigation settings and the - * permission requirements of the page. - * - * Context property: backboneit_navigation_showProtected - * - * @param array $arrPage The page dataset of the current page, with at least - * groups and protected attributes set. - * - * @return boolean If the permission is granted true, otherwise false. - */ - public function isPermissionGranted($arrPage) { - if(BE_USER_LOGGED_IN) // be users have access everywhere - return true; - - if($this->backboneit_navigation_showProtected) // protection is ignored - return true; - - return !$this->isPermissionDenied($arrPage); - } - - /** - * Returns the part of the where condition, checking for hidden state of a page. - * - * @return string The where condition - */ - public function getQueryPartHidden($blnShowHidden = false, $blnSitemap = false) { - if($blnShowHidden) { - return ''; - } elseif($blnSitemap) { - return '(sitemap = \'map_always\' OR (hide != 1 AND sitemap != \'map_never\'))'; - } else { - return 'hide != 1'; - } - } - - /** - * Returns the part of the where condition, checking for guest visibility state of a page. - * - * @return string The where condition - */ - public function getQueryPartGuests() { - if(FE_USER_LOGGED_IN && !BE_USER_LOGGED_IN) { - return 'guests != 1'; - } else { - return ''; - } - } - - /** - * Returns the part of the where condition checking for publication state of a page. - * - * @return string The where condition - */ - public function getQueryPartPublish() { - if(BE_USER_LOGGED_IN) { - return ''; - } else { - static $intTime; if(!$intTime) $intTime = time(); - return '(start = \'\' OR start < ' . $intTime . ') AND (stop = \'\' OR stop > ' . $intTime . ') AND published = 1'; - } - } - - public function getQueryPartErrorPages($blnShowErrorPages = false) { - if($blnShowErrorPages) { - return ''; - } else { - return 'type != \'error_401\' AND type != \'error_403\' AND type != \'error_404\''; - } - } - - protected function getQuotedFieldsPart(array $fields) : string - { - return implode(', ', array_map([$this->Database, 'quoteIdentifier'], $fields)); - } - - /** - * A helper method to generate BE wildcard. - * - * @param string $strBEType (optional, defaults to "NAVIGATION") The type to be displayed in the wildcard - * @return string The wildcard HTML string - */ - protected function generateBE($strBEType = 'NAVIGATION') { - $objTemplate = new BackendTemplate('be_wildcard'); - - $objTemplate->wildcard = '### ' . $strBEType . ' ###'; - $objTemplate->title = $this->headline; - $objTemplate->id = $this->id; - $objTemplate->link = $this->name; - $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; - - return $objTemplate->parse(); - } - - public function addForwardItem($varID, $varTargetID) { - if(is_array($this->arrItems[$varID])) { - $this->arrItems[$varID]['href'] = $this->arrItems[$varTargetID]['href']; - } else { - $this->arrItems[$varID] = $this->arrItems[$varTargetID]; - $this->arrItems[$varID]['id'] = $varID; - unset($this->arrItems[$varID]['pid']); - } - $this->arrItems[$varID]['tid'] = $varTargetID; - } - - /** - * Executes the tree hook, to dynamically add navigations items to the tree - * the navigation is rendered from. - * - * The callback receives the following parameters: - * $this - This navigation module instance - * - * @param array $arrRootIDs The root pages before hook execution - * @return array $arrRootIDs The root pages after hook execution - */ - protected function executeTreeHook($blnForce = false) { - if(!$blnForce && !$this->blnTreeHook) { - return; - } - - foreach((array) $GLOBALS['TL_HOOKS']['backboneit_navigation_tree'] as $arrCallback) { - $this->import($arrCallback[0]); - $this->{$arrCallback[0]}->{$arrCallback[1]}($this); - } - } - - protected function executeItemHook(array &$arrPage, $blnForce = false) { - if(!$blnForce && !$this->blnItemHook) { - return; - } - - foreach((array) $GLOBALS['TL_HOOKS']['bbit_navi_item'] as $arrCallback) { - $this->import($arrCallback[0]); - $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrPage); - } - } - - private function generatePageUrl(array $arrPage) - { - $pageModel = \Contao\PageModel::findByPk($arrPage['id']); - if ($pageModel) { - return $pageModel->getFrontendUrl(); - } - - return null; - } -} diff --git a/TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationChainPreorder.php b/TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationChainPreorder.php deleted file mode 100644 index 6aef02f..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationChainPreorder.php +++ /dev/null @@ -1,51 +0,0 @@ -generateBE('NAVIGATION CHAIN PREORDER'); - - return $this->strNavigation ? parent::generate() : ''; - } - - protected function compile() { - $this->Template->request = $this->getIndexFreeRequest(true); - $this->Template->skipId = 'skipNavigation' . $this->id; - $this->Template->items = $this->strNavigation; - } - - /** - * Executes the navigation chain hook. - * - * The callback receives the following parameters: - * $this - This navigation module instance - * $arrChainIDs - The (ordered) IDs of the navigation chain to be rendered. - * - * And should return a new chain array or null - * - * @param array $arrRootIDs The root pages before hook execution - * @return array $arrRootIDs The root pages after hook execution - */ - protected function executeChainHook(array $arrChainIDs, $blnForce = false) { - if(!$blnForce && $this->backboneit_navigation_disableHooks) - return $arrChainIDs; - if(!is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_chain'])) - return $arrChainIDs; - - foreach($GLOBALS['TL_HOOKS']['backboneit_navigation_chain'] as $arrCallback) { - $this->import($arrCallback[0]); - $arrNewChain = $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrChainIDs); - - if($arrNewChain !== null) - $arrChainIDs = $arrNewChain; - } - - return $arrChainIDs; - } - -} diff --git a/TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationMenu.php b/TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationMenu.php deleted file mode 100644 index bf605b2..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/ModuleNavigationMenu.php +++ /dev/null @@ -1,288 +0,0 @@ -generateBE('NAVIGATION MENU'); - - $arrStop = $this->getStop(); - $intHard = $this->getHard(); - - $arrRootIDs = $this->calculateRootIDs($arrStop); - $this->compileNavigationTree($arrRootIDs, $arrStop, $intHard); - $this->executeTreeHook(); - $arrRootIDs = $this->executeMenuHook($arrRootIDs); - $arrFirstIDs = $this->getFirstNavigationLevel($arrRootIDs); - - if($this->backboneit_navigation_hideSingleLevel) { - foreach($arrFirstIDs as $id) { - if($this->arrSubitems[$id]) { - $hasMultipleLevels = true; - break; - } - } - if(!$hasMultipleLevels) { - return ''; - } - } - - $arrStop[0] == 0 && array_shift($arrStop); // special case renderNavigationTree cannot handle - $this->strNavigation = trim($this->renderNavigationTree($arrFirstIDs, $this->strFirstLevelTemplate, $arrStop, $intHard)); - - return $this->strNavigation ? parent::generate() : ''; - } - - public function getStop() { - if(!$this->backboneit_navigation_defineStop) { - return array(PHP_INT_MAX); - } - $intMin = -1; - foreach(array_map('intval', explode(',', $this->backboneit_navigation_stop)) as $intLevel) if($intLevel > $intMin) { - $arrStop[] = $intMin = $intLevel; - } - return $arrStop ? $arrStop : array(PHP_INT_MAX); - } - - public function getHard() { - return $this->backboneit_navigation_defineHard ? $this->backboneit_navigation_hard : PHP_INT_MAX; - } - - protected function compile() { - $this->Template->request = $this->getIndexFreeRequest(true); - $this->Template->skipId = 'skipNavigation' . $this->id; - $this->Template->items = $this->strNavigation; - $this->backboneit_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; - } - - protected function calculateRootIDs($arrStop = PHP_INT_MAX) { - $arrRootIDs = $this->backboneit_navigation_defineRoots - ? $this->getRootIds() - : array($GLOBALS['objPage']->rootId); - - $this->backboneit_navigation_currentAsRoot && array_unshift($arrRootIDs, $GLOBALS['objPage']->id); - - $arrConditions = array($this->getQueryPartHidden(!$this->backboneit_navigation_respectHidden, $this->backboneit_navigation_isSitemap)); - $this->backboneit_navigation_respectGuests && $arrConditions[] = $this->getQueryPartGuests(); - $this->backboneit_navigation_respectPublish && $arrConditions[] = $this->getQueryPartPublish(); - $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - - if($this->backboneit_navigation_includeStart) { - $arrStartConditions = array( - $this->getQueryPartHidden($this->backboneit_navigation_showHiddenStart, $this->backboneit_navigation_isSitemap), - $this->getQueryPartPublish(), - $this->getQueryPartErrorPages($this->backboneit_navigation_showErrorPages), - ); - !$this->backboneit_navigation_showGuests && $arrStartConditions[] = $this->getQueryPartGuests(); - $strStartConditions = implode(' AND ', array_filter($arrStartConditions, 'strlen')); - } else { - $strStartConditions = $strConditions; - } - - if($this->backboneit_navigation_start > 0) { - $arrRootIDs = $this->filterPages($arrRootIDs, $strConditions); - for($i = 1, $n = $this->backboneit_navigation_start; $i < $n; $i++) - $arrRootIDs = $this->getNextLevel($arrRootIDs, $strConditions); - $arrRootIDs = $this->getNextLevel($arrRootIDs, $strStartConditions); - - } elseif($this->backboneit_navigation_start < 0) { - for($i = 0, $n = -$this->backboneit_navigation_start; $i < $n; $i++) - $arrRootIDs = $this->getPrevLevel($arrRootIDs); - $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); - - } else { - $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); - } - - $arrStop = (array) $arrStop; - if($arrStop[0] == 0) { // special case, keep only roots within the current path - $arrPath = array_keys($this->arrTrail); - $arrPath[] = $this->varActiveID; - $arrRootIDs = array_intersect($arrRootIDs, $arrPath); - } - - return $arrRootIDs; - } - - public function compileNavigationTree(array $arrRootIDs, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX) { - if(!$arrRootIDs) - return; - - $arrRootIDs = array_keys(array_flip($arrRootIDs)); - $arrStop = (array) $arrStop; - - foreach($arrRootIDs as $intRootID) { - $this->arrItems[$intRootID] = (array) $this->arrItems[$intRootID]; - } - - if($this->backboneit_navigation_includeStart) { - $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard, 2); - - $objRoots = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart($this->arrFields) . ' - FROM tl_page - WHERE id IN (' . implode(',', $arrRootIDs) . ')' - ); - - while($objRoots->next()) { - $this->arrItems[$objRoots->id] = $objRoots->row(); - $arrFetched[$objRoots->id] = true; - } - - } else { - $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard); - } - - $blnForwardResolution = !$this->backboneit_navigation_noForwardResolution; - foreach($arrFetched as $intID => $_) { - $this->arrItems[$intID] = $this->compileNavigationItem($this->arrItems[$intID], $blnForwardResolution, self::HOOK_ENABLE); - } - } - - /** - * Fetches page data for all navigation items below the given roots. - * - * @param integer $arrPIDs The root pages of the navigation. - * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $intLevel (optional, defaults to 1) The level of the PIDs. - * @return null - */ - protected function fetchItems(array $arrPIDs, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX, $intLevel = 1) { - $intLevel = max(1, $intLevel); - $arrStop = (array) $arrStop; - - // nothing todo - // $intLevel == $intHard + 1 requires subitem detection for css class "submenu" calculation - if(!$arrPIDs || $intLevel - 1 > $intHard) - return; - - $arrConditions = array( - $this->getQueryPartHidden($this->backboneit_navigation_showHidden, $this->backboneit_navigation_isSitemap), - $this->getQueryPartPublish(), - $this->getQueryPartErrorPages($this->backboneit_navigation_showErrorPages), - ); - !$this->backboneit_navigation_showGuests && $arrConditions[] = $this->getQueryPartGuests(); - $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - - $strLevelQueryStart = - 'SELECT ' . $this->getQuotedFieldsPart($this->arrFields) . ' - FROM tl_page - WHERE pid IN ('; - $strLevelQueryEnd = ') - AND type != \'root\' - ' . $strConditions . ' - ORDER BY sorting'; - - $arrFetched = array(); - - while($arrPIDs) { - // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop - if($intLevel > $intHard) { - $arrEndPIDs = $arrPIDs; - - } elseif($intLevel > $arrStop[0]) { - count($arrStop) > 1 && array_shift($arrStop); - $arrEndPIDs = array(); - foreach($arrPIDs as $intPID) if(!isset($this->arrTrail[$intPID])) { - $arrEndPIDs[$intPID] = true; - } - - } else { - $arrEndPIDs = array(); - } - - $objSubpages = $this->objStmt->query($strLevelQueryStart . implode(',', $arrPIDs) . $strLevelQueryEnd); - - if(!$objSubpages->numRows) - break; - - $arrPIDs = array(); - while($arrPage = $objSubpages->fetchAssoc()) { - if(isset($this->arrItems[$arrPage['id']])) - continue; - - if(!$this->isPermissionGranted($arrPage)) - continue; - - if(!isset($arrEndPIDs[$arrPage['pid']])) { - $this->arrSubitems[$arrPage['pid']][] = $arrPage['id']; // for order of items - $this->arrItems[$arrPage['id']] = $arrPage; // item datasets - $arrPIDs[] = $arrPage['id']; // ids of current layer (for next layer pids) - $arrFetched[$arrPage['id']] = true; // fetched in this method - - } elseif(!isset($this->arrSubitems[$arrPage['pid']])) { - $this->arrSubitems[$arrPage['pid']] = array(); - } - } - - $intLevel++; - } - - return $arrFetched; - } - - /** - * Executes the navigation hook. - * The callback receives the following parameters: - * $this - This navigation module instance - * $arrRootIDs - The IDs of the first navigation level - * - * And should return a new root array or null - * - * @param array $arrRootIDs The root pages before hook execution - * @return array $arrRootIDs The root pages after hook execution - */ - protected function executeMenuHook(array $arrRootIDs, $blnForce = false) { - if(!$blnForce && $this->backboneit_navigation_disableHooks) - return $arrRootIDs; - if(!is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'])) - return $arrRootIDs; - - foreach($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'] as $arrCallback) { - $this->import($arrCallback[0]); - $arrNewRoots = $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrRootIDs); - - if($arrNewRoots !== null) - $arrRootIDs = $arrNewRoots; - } - - return $arrRootIDs; - } - - protected function getFirstNavigationLevel(array $arrRootIDs) { - if($this->backboneit_navigation_includeStart) - return $arrRootIDs; - - // if we do not want to show the root level - $arrFirstIDs = array(); - foreach($arrRootIDs as $varRootID) - if(isset($this->arrSubitems[$varRootID])) - $arrFirstIDs = array_merge($arrFirstIDs, $this->arrSubitems[$varRootID]); - - return $arrFirstIDs; - } - - protected function getRootIds() - { - return array_map( - 'intval', - array_values( - array_unique( - array_merge( - \Contao\StringUtil::deserialize($this->backboneit_navigation_roots_order, true), - \Contao\StringUtil::deserialize($this->backboneit_navigation_roots, true) - ) - ) - ) - ); - } - -} diff --git a/TL_ROOT/system/modules/backboneit_navigation/NavigationDCA.php b/TL_ROOT/system/modules/backboneit_navigation/NavigationDCA.php deleted file mode 100644 index 108d26d..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/NavigationDCA.php +++ /dev/null @@ -1,39 +0,0 @@ -loadLanguageFile('tl_page'); - $this->loadDataContainer('tl_page'); - - $arrFields = array(); - - foreach($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) - if(!isset(AbstractModuleNavigation::$arrDefaultFields[$strField])) - $arrFields[$strField] = &$arrConfig['label'][0]; - - return $arrFields; - } - - public function saveStop($varValue) { - $intMin = -1; - foreach(array_map('intval', explode(',', strval($varValue))) as $intLevel) if($intLevel > $intMin) { - $arrStop[] = $intMin = $intLevel; - } - return implode(',', $arrStop); - } - - protected function __construct() { - parent::__construct(); - } - - private static $objInstance; - - public static function getInstance() { - if(!isset(self::$objInstance)) - self::$objInstance = new self(); - - return self::$objInstance; - } - -} diff --git a/TL_ROOT/system/modules/backboneit_navigation/config/.htaccess b/TL_ROOT/system/modules/backboneit_navigation/config/.htaccess deleted file mode 100644 index f239fe8..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/config/.htaccess +++ /dev/null @@ -1,2 +0,0 @@ -order deny,allow -deny from all \ No newline at end of file diff --git a/TL_ROOT/system/modules/backboneit_navigation/config/autoload.ini b/TL_ROOT/system/modules/backboneit_navigation/config/autoload.ini deleted file mode 100644 index cc8452d..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/config/autoload.ini +++ /dev/null @@ -1,19 +0,0 @@ -;; -; List modules which are required to be loaded beforehand -;; -requires[] = "core" - -;; -; Configure what you want the autoload creator to register -;; -register_namespaces = true -register_classes = true -register_templates = true - -;; -; Override the default configuration for certain sub directories -;; -[vendor/*] -register_namespaces = false -register_classes = false -register_templates = false diff --git a/TL_ROOT/system/modules/backboneit_navigation/config/autoload.php b/TL_ROOT/system/modules/backboneit_navigation/config/autoload.php deleted file mode 100644 index b9e0fe5..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/config/autoload.php +++ /dev/null @@ -1,22 +0,0 @@ - 'system/modules/backboneit_navigation/AbstractModuleNavigation.php', - 'ModuleNavigationChainPreorder' => 'system/modules/backboneit_navigation/ModuleNavigationChainPreorder.php', - 'ModuleNavigationMenu' => 'system/modules/backboneit_navigation/ModuleNavigationMenu.php', - 'NavigationDCA' => 'system/modules/backboneit_navigation/NavigationDCA.php', -)); - - -/** - * Register the templates - */ -TemplateLoader::addFiles(array -( - 'mod_backboneit_navigation_menu' => 'system/modules/backboneit_navigation/templates', - 'nav_bbit' => 'system/modules/backboneit_navigation/templates', -)); diff --git a/TL_ROOT/system/modules/backboneit_navigation/config/config.php b/TL_ROOT/system/modules/backboneit_navigation/config/config.php deleted file mode 100644 index 4487e4b..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/config/config.php +++ /dev/null @@ -1,4 +0,0 @@ - -
cssID; ?>style): ?> style="style; ?>"> - -headline): ?> -<hl; ?>>headline; ?>hl; ?>> - - - -items; ?> - - -
- \ No newline at end of file diff --git a/TL_ROOT/system/modules/backboneit_navigation/templates/nav_bbit.xhtml b/TL_ROOT/system/modules/backboneit_navigation/templates/nav_bbit.xhtml deleted file mode 100644 index ff1edc5..0000000 --- a/TL_ROOT/system/modules/backboneit_navigation/templates/nav_bbit.xhtml +++ /dev/null @@ -1,16 +0,0 @@ - \ No newline at end of file diff --git a/build.xml b/build.xml deleted file mode 100644 index 4d9be94..0000000 --- a/build.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/composer.json b/composer.json index 0f97ba5..143b0ed 100644 --- a/composer.json +++ b/composer.json @@ -2,8 +2,8 @@ "name": "hofff/contao-navigation", "description": "Advanced navigation module for Contao CMS", "keywords": [ "navigation", "module", "page", "contao" ], - "type": "contao-module", - "license": "LGPL-3.0+", + "type": "contao-bundle", + "license": "LGPL-3.0-or-later", "authors": [ { "name": "Oliver Hoff", @@ -16,6 +16,12 @@ "email": "nick@hofff.com", "homepage": "https://www.hofff.com/", "role": "Maintainer" + }, + { + "name": "David Molineus", + "email": "david@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Maintainer" } ], "support": { @@ -23,21 +29,36 @@ "source": "https://github.com/hofff/contao-navigation" }, "require": { - "php": "^5.3 || ^7.0", - "contao/core-bundle": "^3.2 || ^4.2", - "contao-community-alliance/composer-plugin": "^2.0 || ^3.0" + "php": "^7.4 || ^8.0", + "contao/core-bundle": "^4.9", + "symfony/http-kernel": "^4.4 || ^5.0" + }, + "require-dev": { + "contao/manager-plugin": "^2.0", + "doctrine/coding-standard": "^9.0.", + "phpcq/runner-bootstrap": "1.x-dev" }, "replace": { "contao-legacy/backboneit_navigation": "self.version", "backboneit/contao-navigation": "self.version" }, "extra": { - "contao": { - "sources": { - "TL_ROOT/system/modules/backboneit_navigation": "system/modules/backboneit_navigation" - } - }, + "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin", "branch-alias": { + "dev-master": "1.9.x", + "dev-develop": "2.0.x" + } + }, + "autoload": { + "psr-4": { + "Hofff\\Contao\\Navigation\\": "src/" + } + }, + "config": { + "allow-plugins": { + "contao-components/installer": false, + "contao/manager-plugin": true, + "dealerdirect/phpcodesniffer-composer-installer": true } } } diff --git a/ext/yui-compressor/yui.xml b/ext/yui-compressor/yui.xml deleted file mode 100644 index 71a253c..0000000 --- a/ext/yui-compressor/yui.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - - - - - - - Deleting source file. - - - - - Minify JS ${minjs.file}... - - - - - - - - - - - - - - - - - - - - - - - Done. - - - - Deleting source file. - - - - - Minify CSS ${mincss.file}... - - - - - - - - - - - - - - - - - - - - - - - - Done. - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/ext/yui-compressor/yuicompressor-2.4.2.jar b/ext/yui-compressor/yuicompressor-2.4.2.jar deleted file mode 100644 index c29470bd0d0175ddd98e7f82079a9566c2aebf4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 851219 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
vQWQ81PSRYsyy%}BasMgW*@C!F^ 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

mDlI*-YYr4^5Gs;u7l7((%~7noXQa; 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�y9sA{K37k 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 z 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 XH3K=u5BCppxNtlQhqw|l4gU3i%C&)! diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php new file mode 100644 index 0000000..cb366dc --- /dev/null +++ b/src/ContaoManager/Plugin.php @@ -0,0 +1,24 @@ +setLoadAfter([ContaoCoreBundle::class]) + ->setReplace(['backboneit_navigation']), + ]; + } +} diff --git a/src/EventListener/Dca/NavigationDCA.php b/src/EventListener/Dca/NavigationDCA.php new file mode 100644 index 0000000..fd541e3 --- /dev/null +++ b/src/EventListener/Dca/NavigationDCA.php @@ -0,0 +1,54 @@ +loadLanguageFile('tl_page'); + $this->loadDataContainer('tl_page'); + + $arrFields = []; + + foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) { + if (! isset(AbstractModuleNavigation::$arrDefaultFields[$strField])) { + $arrFields[$strField] = &$arrConfig['label'][0]; + } + } + + return $arrFields; + } + + public function saveStop($varValue) + { + $intMin = -1; + foreach (array_map('intval', explode(',', strval($varValue))) as $intLevel) { + if ($intLevel > $intMin) { + $arrStop[] = $intMin = $intLevel; + } + } + + return implode(',', $arrStop); + } + + protected function __construct() + { + parent::__construct(); + } + + private static $objInstance; + + public static function getInstance() + { + if (! isset(self::$objInstance)) { + self::$objInstance = new self(); + } + + return self::$objInstance; + } +} diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php new file mode 100644 index 0000000..24457fa --- /dev/null +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -0,0 +1,787 @@ + the ID of the current item (optional) + * isTrail => whether this item is in the trail path + * class => CSS classes + * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities + * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities + * link => page name (with Insert-Tags and XML specialchars NOT replaced; as stored in the db) + * href => URL of target page + * nofollow => true, if nofollow should be set on rel attribute + * target => either ' onclick="window.open(this.href); return false;"' or empty string + * description => page description with line breaks (\r and \n) replaced by whitespaces + * + * Calculated while rendering: + * subitems => subnavigation as HTML string or empty string (rendered if subpages & items setup correctly) + * isActive => whether this item is the current active navigation item + * + * Following CSS classes are calculated while rendering: level_x, trail, sibling, submenu, first, last + * + * Additionally all page dataset values from the database are available unter their field name, + * if the field name does not collide with the listed keys. + * + * For the collisions of the Contao core page dataset fields the following keys are available: + * _type + * _title + * _pageTitle + * _target + * _description + * + * @author Oliver Hoff + */ +abstract class AbstractModuleNavigation extends Module +{ + + const HOOK_DISABLE = 0; + const HOOK_ENABLE = 1; + const HOOK_FORCE = 2; + + public static $arrDefaultFields = [ + 'id' => true, + 'pid' => true, + 'sorting' => true, + 'tstamp' => true, + 'type' => true, + 'alias' => true, + 'title' => true, + 'protected' => true, + 'groups' => true, + 'jumpTo' => true, + 'pageTitle' => true, + 'target' => true, + 'description' => true, + 'url' => true, + 'robots' => true, + 'cssClass' => true, + 'accesskey' => true, + 'tabindex' => true, + ]; + + protected $arrFields = []; // the fields to use for navigation tpl + protected $strJumpToQuery; + protected $strJumpToFallbackQuery; + + protected $objStmt; // a reusable stmt object + + protected $arrGroups; // set of groups of the current user + protected $arrTrail; // same as trail but with current page included + + public $varActiveID; // the id of the active page + + public $arrItems = []; // compiled page datasets + public $arrSubitems = []; // ordered IDs of subnavigations + /** @Deprecated */ + public $arrSubpages; + + protected $blnTreeHook = false; // execute tree hook? + protected $blnItemHook = false; // execute item hook? + + public function __construct($objModule, $strColumn = 'main') + { + parent::__construct($objModule, $strColumn); + if (TL_MODE == 'BE') { + return; + } + + $this->arrSubpages = &$this->arrSubitems; // for deprecated compat + + $this->import('Database'); + + $this->varActiveID = $this->backboneit_navigation_isSitemap || $this->Input->get( + 'articles' + ) ? false : $GLOBALS['objPage']->id; + $this->arrTrail = array_flip($GLOBALS['objPage']->trail); + + if (FE_USER_LOGGED_IN) { + $this->import('FrontendUser', 'User'); + $this->User->groups && $this->arrGroups = $this->User->groups; + } + + if (! strlen($this->navigationTpl)) { + $this->navigationTpl = 'nav_default'; + } + + $arrFields = deserialize($this->backboneit_navigation_addFields, true); + + if (count($arrFields) > 10) { + $this->arrFields[] = '*'; + } elseif ($arrFields) { + $arrFields = array_flip($arrFields); + foreach ($this->Database->listFields('tl_page') as $arrField) { + if (isset($arrFields[$arrField['name']])) { + $this->arrFields[$arrField['name']] = true; + } + } + + $this->arrFields = array_keys(array_merge($this->arrFields, self::$arrDefaultFields)); + } else { + $this->arrFields = array_keys(self::$arrDefaultFields); + } + + $this->objStmt = $this->Database->prepare('*'); + + $arrConditions = [ + $this->getQueryPartGuests(), + $this->getQueryPartPublish(), + ]; + $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); + $strConditions && $strConditions = ' AND (' . $strConditions . ')'; + + $this->strJumpToQuery = + 'SELECT * + FROM tl_page + WHERE id = ? + ' . $strConditions . ' + LIMIT 0, 1'; + + $this->strJumpToFallbackQuery = + 'SELECT * + FROM tl_page + WHERE pid = ? + AND type = \'regular\' + ' . $strConditions . ' + ORDER BY sorting + LIMIT 0, 1'; + + if (! $this->backboneit_navigation_disableHooks) { + $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_tree']); + $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['bbit_navi_item']); + } + } + + public function __get($strKey) + { + switch ($strKey) { + case 'strJumpToFallbackQuery': + case 'strJumpToQuery': + case 'arrFields': + case 'arrGroups': + case 'arrTrail': + return $this->$strKey; + } + + return parent::__get($strKey); + } + + /** + * Filters the given array of page IDs in regard of publish state, + * required permissions (protected and guests only) and hidden state, according to + * this navigations settings. + * Maintains relative order of the input array. + * + * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * contains no hazardous code. + * + * @param array $arrPages An array of page IDs to filter + * + * @return array Filtered array of page IDs + */ + public function filterPages(array $arrPages, $strConditions = '') + { + if (! $arrPages) { + return $arrPages; + } + + $strConditions && $strConditions = 'AND (' . $strConditions . ')'; + $objPage = $this->objStmt->query( + 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' + FROM tl_page + WHERE id IN (' . implode(',', array_keys(array_flip($arrPages))) . ') + ' . $strConditions + ); + + if (! $this->isPermissionCheckRequired()) { + return array_intersect($arrPages, $objPage->fetchEach('id')); + } // restore order + + $arrPIDs = []; + $arrValid = []; + while ($arrPage = $objPage->fetchAssoc()) { + if ($this->isPermissionDenied($arrPage)) { + continue; + } + + $arrValid[] = $arrPage['id']; + /* + * do not remove the protected check! permission denied checks for + * more, but we need to know, if we must recurse to parent pages, + * for permission check, which must not be done, when this page + * defines access rights. + */ + if (! $arrPage['protected'] && $arrPage['pid'] != 0) { + $arrPIDs[$arrPage['pid']][] = $arrPage['id']; + } + } + + // exclude pages which are in a protected path + while (count($arrPIDs)) { + $arrIDs = $arrPIDs; + $arrPIDs = []; + + $objPage = $this->objStmt->query( + 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' + FROM tl_page + WHERE id IN (' . implode(',', array_keys($arrIDs)) . ')' + ); + + while ($arrPage = $objPage->fetchAssoc()) { + if (! $arrPage['protected']) { // do not remove, see above + if ($arrPage['pid'] != 0) { + $arrPIDs[$arrPage['pid']] = isset($arrPIDs[$arrPage['pid']]) + ? array_merge($arrPIDs[$arrPage['pid']], $arrIDs[$arrPage['id']]) + : $arrIDs[$arrPage['id']]; + } + } elseif ($this->isPermissionDenied($arrPage)) { + $arrValid = array_diff($arrValid, $arrIDs[$arrPage['id']]); + } + } + } + + return array_intersect($arrPages, $arrValid); + } + + /** + * Retrieves the subpages of the given array of page IDs in respect of the + * given conditions, which are added to the WHERE clause of the query. + * Maintains relative order of the input array. + * + * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * contains no hazardous code. + * + * @param array $arrPages An array of parent IDs + * + * @return array The child IDs + */ + public function getNextLevel(array $arrPages, $strConditions = '') + { + if (! $arrPages) { + return $arrPages; + } + + $strConditions && $strConditions = 'AND (' . $strConditions . ')'; + $objNext = $this->objStmt->query( + 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' + FROM tl_page + WHERE pid IN (' . implode(',', array_keys(array_flip($arrPages))) . ') + ' . $strConditions . ' + ORDER BY sorting' + ); + + $arrNext = []; + if ($this->isPermissionCheckRequired()) { + while ($arrPage = $objNext->fetchAssoc()) { + if (! $this->isPermissionDenied($arrPage)) { + $arrNext[$arrPage['pid']][] = $arrPage['id']; + } + } + } else { + while ($arrPage = $objNext->fetchAssoc()) { + $arrNext[$arrPage['pid']][] = $arrPage['id']; + } + } + + $arrNextLevel = []; + foreach ($arrPages as $intID) { + if (isset($arrNext[$intID])) { + $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); + } + } + + return $arrNextLevel; + } + + /** + * Retrieves the parents of the given array of page IDs in respect of the + * given conditions, which are added to the WHERE clause of the query. + * Maintains relative order of the input array and merges subsequent parent + * IDs. + * + * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * contains no hazardous code. + * + * @param array $arrPages An array of child IDs + * + * @return array The parent IDs + */ + public function getPrevLevel(array $arrPages, $strConditions = '') + { + if (! $arrPages) { + return $arrPages; + } + + $strConditions && $strConditions = 'AND (' . $strConditions . ')'; + $objPrev = $this->objStmt->query( + 'SELECT id, pid + FROM tl_page + WHERE id IN (' . implode(',', array_keys(array_flip($arrPages))) . ') + ' . $strConditions + ); + + $arrPrev = []; + while ($objPrev->next()) { + $arrPrev[$objPrev->id] = $objPrev->pid; + } + + $arrPrevLevel = []; + $intPID = -1; + foreach ($arrPages as $intID) { + if (isset($arrPrev[$intID]) && $arrPrev[$intID] != $intPID) { + $arrPrevLevel[] = $intPID = $arrPrev[$intID]; + } + } + + return $arrPrevLevel; + } + + + /** + * Renders the navigation of the given IDs into the navigation template. + * Adds CSS classes "first" and "last" to the appropriate navigation item arrays. + * If the given array is empty, the empty string is returned. + * + * @param array $arrRoots The navigation items arrays + * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param integer $intLevel (optional, defaults to 1) The current level of this navigation layer + * + * @return string The parsed navigation template, could be empty string. + */ + protected function renderNavigationTree( + array $arrIDs, + $strTemplate, + $arrStop = PHP_INT_MAX, + $intHard = PHP_INT_MAX, + $intLevel = 1 + ) { + if (! $arrIDs) { + return ''; + } + + $arrStop = (array) $arrStop; + $arrStop || $arrStop = [PHP_INT_MAX]; + $intStop = $intLevel >= $arrStop[0] ? array_shift($arrStop) : $arrStop[0]; + $arrItems = []; + + foreach ($arrIDs as $varID) { + if (! $this->arrItems[$varID]) { + continue; + } + + $arrItem = $this->arrItems[$varID]; + + if ($varID == $this->varActiveID) { + $blnContainsActive = true; + + if ($arrItem['href'] === Environment::get('request')) { + $arrItem['isActive'] = true; // nothing else (active class is set in template) + $arrItem['isTrail'] = false; + } else { + $arrItem['isActive'] = false; // nothing else (active class is set in template) + $arrItem['isTrail'] = true; + } + } else { // do not flatten if/else + if ($arrItem['tid'] == $this->varActiveID) { + if ($arrItem['href'] === Environment::get('request')) { + $arrItem['isActive'] = true; // nothing else (active class is set in template) + $arrItem['isTrail'] = false; + } else { + $arrItem['isActive'] = false; // nothing else (active class is set in template) + $arrItem['isTrail'] = true; + } + } + } + + if ($arrItem['isTrail']) { + $arrItem['class'] .= ' trail'; + } + + if (! isset($this->arrSubitems[$varID])) { + $arrItem['class'] .= ' leaf'; + } elseif ($intLevel >= $intHard) { + // we are at hard level, never draw submenu + $arrItem['class'] .= ' submenu leaf'; + } elseif ($intLevel >= $intStop && ! $arrItem['isTrail'] && $varID !== $this->varActiveID && $arrItem['tid'] != $this->varActiveID) { + // we are at stop level and not trail and not active, never draw submenu + $arrItem['class'] .= ' submenu leaf'; + } elseif ($this->arrSubitems[$varID]) { + $arrItem['class'] .= ' submenu inner'; + $arrItem['subitems'] = $this->renderNavigationTree( + $this->arrSubitems[$varID], + $arrItem['template'], + $arrStop, + $intHard, + $intLevel + 1 + ); + } else { // should never be reached, if no hooks are used + $arrItem['class'] .= ' leaf'; + } + + $arrItems[] = $arrItem; + } + + if ($blnContainsActive) { + foreach ($arrItems as &$arrItem) { + if (! $arrItem['isActive']) { + $arrItem['class'] .= ' sibling'; + } + } + } + + $arrItems[0]['class'] .= ' first'; + $arrItems[count($arrItems) - 1]['class'] .= ' last'; + + foreach ($arrItems as &$arrItem) { + $arrItem['class'] = ltrim($arrItem['class']); + } + + strlen($strTemplate) || $strTemplate = $this->navigationTpl; + $objTemplate = new FrontendTemplate($strTemplate); + $objTemplate->setData([ + 'module' => $this->arrData, + 'level' => 'level_' . $intLevel, + 'items' => $arrItems, + 'type' => get_class($this), + ]); + + return $objTemplate->parse(); + } + + /** + * Compiles a navigation item array from a page dataset with the given subnavi + * + * @param array $arrPage The page dataset as an array + * + * @return array The compiled navigation item array + */ + public function compileNavigationItem( + array $arrPage, + $blnForwardResolution = true, + $intItemHook = self::HOOK_DISABLE + ) { + // fallback for dataset field collisions + $arrPage['_title'] = $arrPage['title']; + $arrPage['_pageTitle'] = $arrPage['pageTitle']; + $arrPage['_target'] = $arrPage['target']; + $arrPage['_description'] = $arrPage['description']; + + $arrPage['link'] = $arrPage['_title']; + $arrPage['class'] = $arrPage['cssClass'] . ' ' . $arrPage['type']; + $arrPage['title'] = specialchars($arrPage['_title'], true); + $arrPage['pageTitle'] = specialchars($arrPage['_pageTitle'], true); + $arrPage['target'] = ''; // overwrite DB value + $arrPage['nofollow'] = strncmp($arrPage['robots'], 'noindex', 7) === 0; + $arrPage['description'] = str_replace(["\n", "\r"], [' ', ''], $arrPage['_description']); + $arrPage['isTrail'] = isset($this->arrTrail[$arrPage['id']]); + + switch ($arrPage['type']) { + case 'forward': + if ($blnForwardResolution) { + if ($arrPage['jumpTo']) { + $intFallbackSearchID = $arrPage['id']; + $intJumpToID = $arrPage['jumpTo']; + do { + $objNext = $this->objStmt->prepare($this->strJumpToQuery)->execute($intJumpToID); + + if (! $objNext->numRows) { + $objNext = $this->objStmt->prepare($this->strJumpToFallbackQuery)->execute( + $intFallbackSearchID + ); + break; + } + + $intFallbackSearchID = $intJumpToID; + $intJumpToID = $objNext->jumpTo; + } while ($objNext->type == 'forward'); + } else { + $objNext = $this->objStmt->prepare($this->strJumpToFallbackQuery)->execute($arrPage['id']); + } + + if (! $objNext->numRows) { + $arrPage['href'] = $this->generatePageUrl($arrPage); + } elseif ($objNext->type == 'redirect') { + $arrPage['href'] = $this->encodeEmailURL($objNext->url); + $arrPage['target'] = $objNext->target ? LINK_NEW_WINDOW : ''; + } else { + $arrPage['tid'] = $objNext->id; + $arrPage['href'] = $this->generatePageUrl($objNext->row()); + } + } else { + $arrPage['tid'] = $arrPage['jumpTo']; + $arrPage['href'] = $this->generatePageUrl($arrPage); + } + break; + + case 'redirect': + $arrPage['href'] = $this->encodeEmailURL($arrPage['url']); + $arrPage['target'] = $arrPage['_target'] ? LINK_NEW_WINDOW : ''; + break; + + case 'root': + if (! $arrPage['dns'] + || preg_replace('/^www\./', '', $arrPage['dns']) == preg_replace( + '/^www\./', + '', + $this->Environment->httpHost + )) { + $arrPage['href'] = $this->Environment->base; + break; // we only break on root pages; pages in different roots should be handled by DomainLink extension + } + // do not break + + default: + case 'regular': + case 'error_401': + case 'error_403': + case 'error_404': + $arrPage['href'] = $this->generatePageUrl($arrPage); + break; + } + + if ($intItemHook != self::HOOK_DISABLE) { + $this->executeItemHook($arrPage, $intItemHook == self::HOOK_FORCE); + } + + return $arrPage; + } + + /** + * Utility method of compileNavigationItem. + * + * If the given URL starts with "mailto:", the E-Mail is encoded, + * otherwise nothing is done. + * + * @param string $strHref The URL to check and possibly encode + * + * @return string The modified URL + */ + public function encodeEmailURL($strHref) + { + if (strncasecmp($strHref, 'mailto:', 7) !== 0) { + return $strHref; + } + + if (version_compare(VERSION . '.' . BUILD, '3.5.5', '>=')) { + return \StringUtil::encodeEmail($strHref); + } else { + return \String::encodeEmail($strHref); + } + } + + public function isPermissionCheckRequired() + { + return ! BE_USER_LOGGED_IN && ! $this->backboneit_navigation_showProtected; + } + + /** + * Utility method. + * + * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! + * + * Checks if the current user has no permission to view the page of the + * given page dataset, in regards to the permission requirements of the + * page. + * + * @param array $arrPage The page dataset of the current page, with at least + * groups and protected attributes set. + * + * @return boolean If the permission is denied true, otherwise false. + */ + public function isPermissionDenied($arrPage) + { + if (! $arrPage['protected']) // this page is not protected + { + return false; + } + + if (! $this->arrGroups) // the current user is not in any group + { + return true; + } + + // check if the current user is not in any group, which is allowed to access the current page + return ! array_intersect($this->arrGroups, deserialize($arrPage['groups'], true)); + } + + /** + * Utility method. + * + * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! + * + * Checks if the current user has permission to view the page of the given + * page dataset, in regards to the current navigation settings and the + * permission requirements of the page. + * + * Context property: backboneit_navigation_showProtected + * + * @param array $arrPage The page dataset of the current page, with at least + * groups and protected attributes set. + * + * @return boolean If the permission is granted true, otherwise false. + */ + public function isPermissionGranted($arrPage) + { + if (BE_USER_LOGGED_IN) // be users have access everywhere + { + return true; + } + + if ($this->backboneit_navigation_showProtected) // protection is ignored + { + return true; + } + + return ! $this->isPermissionDenied($arrPage); + } + + /** + * Returns the part of the where condition, checking for hidden state of a page. + * + * @return string The where condition + */ + public function getQueryPartHidden($blnShowHidden = false, $blnSitemap = false) + { + if ($blnShowHidden) { + return ''; + } elseif ($blnSitemap) { + return '(sitemap = \'map_always\' OR (hide != 1 AND sitemap != \'map_never\'))'; + } else { + return 'hide != 1'; + } + } + + /** + * Returns the part of the where condition, checking for guest visibility state of a page. + * + * @return string The where condition + */ + public function getQueryPartGuests() + { + if (FE_USER_LOGGED_IN && ! BE_USER_LOGGED_IN) { + return 'guests != 1'; + } else { + return ''; + } + } + + /** + * Returns the part of the where condition checking for publication state of a page. + * + * @return string The where condition + */ + public function getQueryPartPublish() + { + if (BE_USER_LOGGED_IN) { + return ''; + } else { + static $intTime; + if (! $intTime) { + $intTime = time(); + } + + return '(start = \'\' OR start < ' . $intTime . ') AND (stop = \'\' OR stop > ' . $intTime . ') AND published = 1'; + } + } + + public function getQueryPartErrorPages($blnShowErrorPages = false) + { + if ($blnShowErrorPages) { + return ''; + } else { + return 'type != \'error_401\' AND type != \'error_403\' AND type != \'error_404\''; + } + } + + protected function getQuotedFieldsPart(array $fields): string + { + return implode(', ', array_map([$this->Database, 'quoteIdentifier'], $fields)); + } + + /** + * A helper method to generate BE wildcard. + * + * @param string $strBEType (optional, defaults to "NAVIGATION") The type to be displayed in the wildcard + * + * @return string The wildcard HTML string + */ + protected function generateBE($strBEType = 'NAVIGATION') + { + $objTemplate = new BackendTemplate('be_wildcard'); + + $objTemplate->wildcard = '### ' . $strBEType . ' ###'; + $objTemplate->title = $this->headline; + $objTemplate->id = $this->id; + $objTemplate->link = $this->name; + $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; + + return $objTemplate->parse(); + } + + public function addForwardItem($varID, $varTargetID) + { + if (is_array($this->arrItems[$varID])) { + $this->arrItems[$varID]['href'] = $this->arrItems[$varTargetID]['href']; + } else { + $this->arrItems[$varID] = $this->arrItems[$varTargetID]; + $this->arrItems[$varID]['id'] = $varID; + unset($this->arrItems[$varID]['pid']); + } + $this->arrItems[$varID]['tid'] = $varTargetID; + } + + /** + * Executes the tree hook, to dynamically add navigations items to the tree + * the navigation is rendered from. + * + * The callback receives the following parameters: + * $this - This navigation module instance + * + * @param array $arrRootIDs The root pages before hook execution + * + * @return array $arrRootIDs The root pages after hook execution + */ + protected function executeTreeHook($blnForce = false) + { + if (! $blnForce && ! $this->blnTreeHook) { + return; + } + + foreach ((array) $GLOBALS['TL_HOOKS']['backboneit_navigation_tree'] as $arrCallback) { + $this->import($arrCallback[0]); + $this->{$arrCallback[0]}->{$arrCallback[1]}($this); + } + } + + protected function executeItemHook(array &$arrPage, $blnForce = false) + { + if (! $blnForce && ! $this->blnItemHook) { + return; + } + + foreach ((array) $GLOBALS['TL_HOOKS']['bbit_navi_item'] as $arrCallback) { + $this->import($arrCallback[0]); + $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrPage); + } + } + + private function generatePageUrl(array $arrPage) + { + $pageModel = \Contao\PageModel::findByPk($arrPage['id']); + if ($pageModel) { + return $pageModel->getFrontendUrl(); + } + + return null; + } +} diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php new file mode 100644 index 0000000..3c692fc --- /dev/null +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -0,0 +1,330 @@ +generateBE('NAVIGATION MENU'); + } + + $arrStop = $this->getStop(); + $intHard = $this->getHard(); + + $arrRootIDs = $this->calculateRootIDs($arrStop); + $this->compileNavigationTree($arrRootIDs, $arrStop, $intHard); + $this->executeTreeHook(); + $arrRootIDs = $this->executeMenuHook($arrRootIDs); + $arrFirstIDs = $this->getFirstNavigationLevel($arrRootIDs); + + if ($this->backboneit_navigation_hideSingleLevel) { + foreach ($arrFirstIDs as $id) { + if ($this->arrSubitems[$id]) { + $hasMultipleLevels = true; + break; + } + } + if (! $hasMultipleLevels) { + return ''; + } + } + + $arrStop[0] == 0 && array_shift($arrStop); // special case renderNavigationTree cannot handle + $this->strNavigation = trim( + $this->renderNavigationTree($arrFirstIDs, $this->strFirstLevelTemplate, $arrStop, $intHard) + ); + + return $this->strNavigation ? parent::generate() : ''; + } + + public function getStop() + { + if (! $this->backboneit_navigation_defineStop) { + return [PHP_INT_MAX]; + } + $intMin = -1; + foreach (array_map('intval', explode(',', $this->backboneit_navigation_stop)) as $intLevel) { + if ($intLevel > $intMin) { + $arrStop[] = $intMin = $intLevel; + } + } + + return $arrStop ? $arrStop : [PHP_INT_MAX]; + } + + public function getHard() + { + return $this->backboneit_navigation_defineHard ? $this->backboneit_navigation_hard : PHP_INT_MAX; + } + + protected function compile() + { + $this->Template->request = $this->getIndexFreeRequest(true); + $this->Template->skipId = 'skipNavigation' . $this->id; + $this->Template->items = $this->strNavigation; + $this->backboneit_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; + } + + protected function calculateRootIDs($arrStop = PHP_INT_MAX) + { + $arrRootIDs = $this->backboneit_navigation_defineRoots + ? $this->getRootIds() + : [$GLOBALS['objPage']->rootId]; + + $this->backboneit_navigation_currentAsRoot && array_unshift($arrRootIDs, $GLOBALS['objPage']->id); + + $arrConditions = [ + $this->getQueryPartHidden( + ! $this->backboneit_navigation_respectHidden, + $this->backboneit_navigation_isSitemap + ), + ]; + $this->backboneit_navigation_respectGuests && $arrConditions[] = $this->getQueryPartGuests(); + $this->backboneit_navigation_respectPublish && $arrConditions[] = $this->getQueryPartPublish(); + $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); + + if ($this->backboneit_navigation_includeStart) { + $arrStartConditions = [ + $this->getQueryPartHidden( + $this->backboneit_navigation_showHiddenStart, + $this->backboneit_navigation_isSitemap + ), + $this->getQueryPartPublish(), + $this->getQueryPartErrorPages($this->backboneit_navigation_showErrorPages), + ]; + ! $this->backboneit_navigation_showGuests && $arrStartConditions[] = $this->getQueryPartGuests(); + $strStartConditions = implode(' AND ', array_filter($arrStartConditions, 'strlen')); + } else { + $strStartConditions = $strConditions; + } + + if ($this->backboneit_navigation_start > 0) { + $arrRootIDs = $this->filterPages($arrRootIDs, $strConditions); + for ($i = 1, $n = $this->backboneit_navigation_start; $i < $n; $i++) { + $arrRootIDs = $this->getNextLevel($arrRootIDs, $strConditions); + } + $arrRootIDs = $this->getNextLevel($arrRootIDs, $strStartConditions); + } elseif ($this->backboneit_navigation_start < 0) { + for ($i = 0, $n = -$this->backboneit_navigation_start; $i < $n; $i++) { + $arrRootIDs = $this->getPrevLevel($arrRootIDs); + } + $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); + } else { + $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); + } + + $arrStop = (array) $arrStop; + if ($arrStop[0] == 0) { // special case, keep only roots within the current path + $arrPath = array_keys($this->arrTrail); + $arrPath[] = $this->varActiveID; + $arrRootIDs = array_intersect($arrRootIDs, $arrPath); + } + + return $arrRootIDs; + } + + public function compileNavigationTree(array $arrRootIDs, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX) + { + if (! $arrRootIDs) { + return; + } + + $arrRootIDs = array_keys(array_flip($arrRootIDs)); + $arrStop = (array) $arrStop; + + foreach ($arrRootIDs as $intRootID) { + $this->arrItems[$intRootID] = (array) $this->arrItems[$intRootID]; + } + + if ($this->backboneit_navigation_includeStart) { + $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard, 2); + + $objRoots = $this->objStmt->query( + 'SELECT ' . $this->getQuotedFieldsPart($this->arrFields) . ' + FROM tl_page + WHERE id IN (' . implode(',', $arrRootIDs) . ')' + ); + + while ($objRoots->next()) { + $this->arrItems[$objRoots->id] = $objRoots->row(); + $arrFetched[$objRoots->id] = true; + } + } else { + $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard); + } + + $blnForwardResolution = ! $this->backboneit_navigation_noForwardResolution; + foreach ($arrFetched as $intID => $_) { + $this->arrItems[$intID] = $this->compileNavigationItem( + $this->arrItems[$intID], + $blnForwardResolution, + self::HOOK_ENABLE + ); + } + } + + /** + * Fetches page data for all navigation items below the given roots. + * + * @param integer $arrPIDs The root pages of the navigation. + * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param integer $intLevel (optional, defaults to 1) The level of the PIDs. + * + * @return null + */ + protected function fetchItems(array $arrPIDs, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX, $intLevel = 1) + { + $intLevel = max(1, $intLevel); + $arrStop = (array) $arrStop; + + // nothing todo + // $intLevel == $intHard + 1 requires subitem detection for css class "submenu" calculation + if (! $arrPIDs || $intLevel - 1 > $intHard) { + return; + } + + $arrConditions = [ + $this->getQueryPartHidden($this->backboneit_navigation_showHidden, $this->backboneit_navigation_isSitemap), + $this->getQueryPartPublish(), + $this->getQueryPartErrorPages($this->backboneit_navigation_showErrorPages), + ]; + ! $this->backboneit_navigation_showGuests && $arrConditions[] = $this->getQueryPartGuests(); + $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); + $strConditions && $strConditions = 'AND (' . $strConditions . ')'; + + $strLevelQueryStart = + 'SELECT ' . $this->getQuotedFieldsPart($this->arrFields) . ' + FROM tl_page + WHERE pid IN ('; + $strLevelQueryEnd = ') + AND type != \'root\' + ' . $strConditions . ' + ORDER BY sorting'; + + $arrFetched = []; + + while ($arrPIDs) { + // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop + if ($intLevel > $intHard) { + $arrEndPIDs = $arrPIDs; + } elseif ($intLevel > $arrStop[0]) { + count($arrStop) > 1 && array_shift($arrStop); + $arrEndPIDs = []; + foreach ($arrPIDs as $intPID) { + if (! isset($this->arrTrail[$intPID])) { + $arrEndPIDs[$intPID] = true; + } + } + } else { + $arrEndPIDs = []; + } + + $objSubpages = $this->objStmt->query($strLevelQueryStart . implode(',', $arrPIDs) . $strLevelQueryEnd); + + if (! $objSubpages->numRows) { + break; + } + + $arrPIDs = []; + while ($arrPage = $objSubpages->fetchAssoc()) { + if (isset($this->arrItems[$arrPage['id']])) { + continue; + } + + if (! $this->isPermissionGranted($arrPage)) { + continue; + } + + if (! isset($arrEndPIDs[$arrPage['pid']])) { + $this->arrSubitems[$arrPage['pid']][] = $arrPage['id']; // for order of items + $this->arrItems[$arrPage['id']] = $arrPage; // item datasets + $arrPIDs[] = $arrPage['id']; // ids of current layer (for next layer pids) + $arrFetched[$arrPage['id']] = true; // fetched in this method + + } elseif (! isset($this->arrSubitems[$arrPage['pid']])) { + $this->arrSubitems[$arrPage['pid']] = []; + } + } + + $intLevel++; + } + + return $arrFetched; + } + + /** + * Executes the navigation hook. + * The callback receives the following parameters: + * $this - This navigation module instance + * $arrRootIDs - The IDs of the first navigation level + * + * And should return a new root array or null + * + * @param array $arrRootIDs The root pages before hook execution + * + * @return array $arrRootIDs The root pages after hook execution + */ + protected function executeMenuHook(array $arrRootIDs, $blnForce = false) + { + if (! $blnForce && $this->backboneit_navigation_disableHooks) { + return $arrRootIDs; + } + if (! is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'])) { + return $arrRootIDs; + } + + foreach ($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'] as $arrCallback) { + $this->import($arrCallback[0]); + $arrNewRoots = $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrRootIDs); + + if ($arrNewRoots !== null) { + $arrRootIDs = $arrNewRoots; + } + } + + return $arrRootIDs; + } + + protected function getFirstNavigationLevel(array $arrRootIDs) + { + if ($this->backboneit_navigation_includeStart) { + return $arrRootIDs; + } + + // if we do not want to show the root level + $arrFirstIDs = []; + foreach ($arrRootIDs as $varRootID) { + if (isset($this->arrSubitems[$varRootID])) { + $arrFirstIDs = array_merge($arrFirstIDs, $this->arrSubitems[$varRootID]); + } + } + + return $arrFirstIDs; + } + + protected function getRootIds() + { + return array_map( + 'intval', + array_values( + array_unique( + array_merge( + \Contao\StringUtil::deserialize($this->backboneit_navigation_roots_order, true), + \Contao\StringUtil::deserialize($this->backboneit_navigation_roots, true) + ) + ) + ) + ); + } + +} diff --git a/src/HofffContaoNavigationBundle.php b/src/HofffContaoNavigationBundle.php new file mode 100644 index 0000000..99e9a22 --- /dev/null +++ b/src/HofffContaoNavigationBundle.php @@ -0,0 +1,12 @@ + Date: Mon, 30 May 2022 15:48:14 +0200 Subject: [PATCH 02/75] Use spaces insteadof tabs --- src/Resources/contao/dca/tl_module.php | 674 +++++++++--------- src/Resources/contao/languages/de/modules.php | 6 +- .../contao/languages/de/tl_module.php | 89 ++- 3 files changed, 404 insertions(+), 365 deletions(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index e768639..2a81b07 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -8,366 +8,366 @@ $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_defineDepth'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_menu'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_currentAsRoot,backboneit_navigation_defineRoots,' - . 'backboneit_navigation_start,backboneit_navigation_respectHidden,' - . 'backboneit_navigation_respectPublish,backboneit_navigation_respectGuests;' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_includeStart,' - . 'backboneit_navigation_defineStop,' - . 'backboneit_navigation_defineHard,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected,' - . 'backboneit_navigation_showGuests,backboneit_navigation_isSitemap,' - . 'backboneit_navigation_hideSingleLevel;' - . '{template_legend:hide},navigationTpl,backboneit_navigation_addLegacyCss,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; + = '{title_legend},name,headline,type;' + . '{backboneit_navigation_root_legend},' + . 'backboneit_navigation_currentAsRoot,backboneit_navigation_defineRoots,' + . 'backboneit_navigation_start,backboneit_navigation_respectHidden,' + . 'backboneit_navigation_respectPublish,backboneit_navigation_respectGuests;' + . '{backboneit_navigation_legend},' + . 'backboneit_navigation_includeStart,' + . 'backboneit_navigation_defineStop,' + . 'backboneit_navigation_defineHard,' + . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected,' + . 'backboneit_navigation_showGuests,backboneit_navigation_isSitemap,' + . 'backboneit_navigation_hideSingleLevel;' + . '{template_legend:hide},navigationTpl,backboneit_navigation_addLegacyCss,' + . 'backboneit_navigation_addFields;' + . '{protected_legend:hide},protected;' + . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chain'] - = '{title_legend},name,type,backboneit_navigation_rootSelectionType'; + = '{title_legend},name,type,backboneit_navigation_rootSelectionType'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chainsingle'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_rootSelectionType,' - . 'backboneit_navigation_roots,' - . 'backboneit_navigation_respectPublish;' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_chainDirections,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected,' - . 'backboneit_navigation_showGuests;' - . '{template_legend:hide},navigationTpl,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; + = '{title_legend},name,headline,type;' + . '{backboneit_navigation_root_legend},' + . 'backboneit_navigation_rootSelectionType,' + . 'backboneit_navigation_roots,' + . 'backboneit_navigation_respectPublish;' + . '{backboneit_navigation_legend},' + . 'backboneit_navigation_chainDirections,' + . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected,' + . 'backboneit_navigation_showGuests;' + . '{template_legend:hide},navigationTpl,' + . 'backboneit_navigation_addFields;' + . '{protected_legend:hide},protected;' + . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chainsubtrees'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_rootSelectionType,' - . 'backboneit_navigation_roots,' - . 'backboneit_navigation_start,backboneit_navigation_includeStart,' - . 'backboneit_navigation_respectHidden,backboneit_navigation_respectPublish,' - . 'backboneit_navigation_respectGuests;' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_chainDirections,' - . 'backboneit_navigation_defineDepth,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected;' - . 'backboneit_navigation_showGuests;' - . '{template_legend:hide},navigationTpl,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; + = '{title_legend},name,headline,type;' + . '{backboneit_navigation_root_legend},' + . 'backboneit_navigation_rootSelectionType,' + . 'backboneit_navigation_roots,' + . 'backboneit_navigation_start,backboneit_navigation_includeStart,' + . 'backboneit_navigation_respectHidden,backboneit_navigation_respectPublish,' + . 'backboneit_navigation_respectGuests;' + . '{backboneit_navigation_legend},' + . 'backboneit_navigation_chainDirections,' + . 'backboneit_navigation_defineDepth,' + . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected;' + . 'backboneit_navigation_showGuests;' + . '{template_legend:hide},navigationTpl,' + . 'backboneit_navigation_addFields;' + . '{protected_legend:hide},protected;' + . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chaincurrent'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_rootSelectionType,' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_chainDirections,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected;' - . 'backboneit_navigation_showGuests;' - . '{template_legend:hide},navigationTpl,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; + = '{title_legend},name,headline,type;' + . '{backboneit_navigation_root_legend},' + . 'backboneit_navigation_rootSelectionType,' + . '{backboneit_navigation_legend},' + . 'backboneit_navigation_chainDirections,' + . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected;' + . 'backboneit_navigation_showGuests;' + . '{template_legend:hide},navigationTpl,' + . 'backboneit_navigation_addFields;' + . '{protected_legend:hide},protected;' + . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineRoots'] - = 'backboneit_navigation_roots'; + = 'backboneit_navigation_roots'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_includeStart'] - = 'backboneit_navigation_showHiddenStart'; + = 'backboneit_navigation_showHiddenStart'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineStop'] - = 'backboneit_navigation_stop'; + = 'backboneit_navigation_stop'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineHard'] - = 'backboneit_navigation_hard'; + = 'backboneit_navigation_hard'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineDepth'] - = 'backboneit_navigation_depth'; - + = 'backboneit_navigation_depth'; /***** GENERAL FIELDS *********************************************************/ -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots'], - 'exclude' => true, - 'inputType' => 'pageTree', - 'eval' => array( - 'multiple' => true, - 'fieldType' => 'checkbox', - 'tl_class' => 'clr', - 'orderField' => 'backboneit_navigation_roots_order' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots_order'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots_order'], -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_start'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_start'], - 'exclude' => true, - 'inputType' => 'text', - 'eval' => array( - 'maxlength' => 5, - 'rgxp' => 'digit', - 'tl_class' => 'clr w50' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectHidden'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectHidden'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx m12' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectPublish'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectPublish'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'clr w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectGuests'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectGuests'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_includeStart'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_includeStart'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'submitOnChange'=> true, - 'tl_class' => 'clr w50 cbx', - ), -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHiddenStart'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showHiddenStart'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx', - ), -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHidden'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showHidden'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'clr w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showProtected'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showProtected'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showGuests'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showGuests'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'clr w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addFields'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addFields'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'options_callback' => array('NavigationDCA', 'getPageFields'), - 'eval' => array( - 'multiple' => true, - 'tl_class' => 'clr' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_noForwardResolution'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_noForwardResolution'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'clr w50 cbx m12' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showErrorPages'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showErrorPages'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'clr w50 cbx m12' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_disableHooks'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_disableHooks'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx m12' - ) -); - +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots'], + 'exclude' => true, + 'inputType' => 'pageTree', + 'eval' => [ + 'multiple' => true, + 'fieldType' => 'checkbox', + 'tl_class' => 'clr', + 'orderField' => 'backboneit_navigation_roots_order', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots_order'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots_order'], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_start'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_start'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => [ + 'maxlength' => 5, + 'rgxp' => 'digit', + 'tl_class' => 'clr w50', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectHidden'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectHidden'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx m12', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectPublish'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectPublish'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'clr w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectGuests'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectGuests'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_includeStart'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_includeStart'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'submitOnChange' => true, + 'tl_class' => 'clr w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHiddenStart'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showHiddenStart'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHidden'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showHidden'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'clr w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showProtected'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showProtected'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showGuests'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showGuests'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'clr w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addFields'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addFields'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'options_callback' => ['NavigationDCA', 'getPageFields'], + 'eval' => [ + 'multiple' => true, + 'tl_class' => 'clr', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_noForwardResolution'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_noForwardResolution'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'clr w50 cbx m12', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showErrorPages'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showErrorPages'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'clr w50 cbx m12', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_disableHooks'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_disableHooks'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx m12', + ], +]; /***** NAVIGATION MENU ********************************************************/ -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_currentAsRoot'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_currentAsRoot'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineRoots'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineRoots'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'submitOnChange' => true, - 'tl_class' => 'w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineStop'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineStop'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'submitOnChange' => true, - 'tl_class' => 'clr w50 cbx m12' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_stop'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_stop'], - 'exclude' => true, - 'inputType' => 'text', - 'eval' => array( - 'maxlength' => 255, - 'tl_class' => 'w50' - ), - 'save_callback' => array( - array('NavigationDCA', 'saveStop'), - ), -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineHard'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineHard'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'submitOnChange' => true, - 'tl_class' => 'clr w50 cbx m12' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hard'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_hard'], - 'exclude' => true, - 'inputType' => 'text', - 'eval' => array( - 'maxlength' => 5, - 'rgxp' => 'digit', - 'tl_class' => 'w50' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_isSitemap'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_isSitemap'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hideSingleLevel'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_hideSingleLevel'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'clr w50 cbx' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addLegacyCss'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addLegacyCss'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'tl_class' => 'w50 cbx m12' - ) -); - +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_currentAsRoot'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_currentAsRoot'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineRoots'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineRoots'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'submitOnChange' => true, + 'tl_class' => 'w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineStop'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineStop'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'submitOnChange' => true, + 'tl_class' => 'clr w50 cbx m12', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_stop'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_stop'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => [ + 'maxlength' => 255, + 'tl_class' => 'w50', + ], + 'save_callback' => [ + ['NavigationDCA', 'saveStop'], + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineHard'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineHard'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'submitOnChange' => true, + 'tl_class' => 'clr w50 cbx m12', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hard'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_hard'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => [ + 'maxlength' => 5, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_isSitemap'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_isSitemap'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hideSingleLevel'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_hideSingleLevel'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'clr w50 cbx', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addLegacyCss'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addLegacyCss'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'tl_class' => 'w50 cbx m12', + ], +]; /***** NAVIGATION CHAIN *******************************************************/ -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_rootSelectionType'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_rootSelectionType'], - 'exclude' => true, - 'inputType' => 'select', - 'default' => 'current', - 'options' => array('subtrees', 'single', 'current'), - 'reference' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_rootSelectionType_options'], - 'eval' => array( - 'submitOnChange' => true, - 'tl_class' => 'clr w50' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_chainDirections'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_chainDirections'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'default' => array('forward', 'backward'), - 'options' => array('forward', /*'top', */'backward'), - 'reference' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_chainDirections_options'], - 'eval' => array( - 'multiple' => true, - 'tl_class' => 'clr w50' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineDepth'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineDepth'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => array( - 'submitOnChange' => true, - 'tl_class' => 'clr w50 cbx m12' - ) -); - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_depth'] = array( - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_depth'], - 'exclude' => true, - 'inputType' => 'text', - 'eval' => array( - 'maxlength' => 5, - 'rgxp' => 'digit', - 'tl_class' => 'w50' - ) -); +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_rootSelectionType'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_rootSelectionType'], + 'exclude' => true, + 'inputType' => 'select', + 'default' => 'current', + 'options' => ['subtrees', 'single', 'current'], + 'reference' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_rootSelectionType_options'], + 'eval' => [ + 'submitOnChange' => true, + 'tl_class' => 'clr w50', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_chainDirections'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_chainDirections'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => ['forward', 'backward'], + 'options' => [ + 'forward', /*'top', */ + 'backward', + ], + 'reference' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_chainDirections_options'], + 'eval' => [ + 'multiple' => true, + 'tl_class' => 'clr w50', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineDepth'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineDepth'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ + 'submitOnChange' => true, + 'tl_class' => 'clr w50 cbx m12', + ], +]; + +$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_depth'] = [ + 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_depth'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => [ + 'maxlength' => 5, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + ], +]; diff --git a/src/Resources/contao/languages/de/modules.php b/src/Resources/contao/languages/de/modules.php index 5a4056e..8abeee6 100644 --- a/src/Resources/contao/languages/de/modules.php +++ b/src/Resources/contao/languages/de/modules.php @@ -1,7 +1,7 @@ verkettete Weiterleitungen, welche die aktuelle Seite als Weiterleitungsendziel besitzen nicht mehr als aktiv gekennzeichnet werden (kein "isActive" mehr im Template und keine "active" CSS-Klasse).'); + = [ + 'Weiterleitungsauflösung deaktivieren', + 'Deaktiviert das ersetzen von Weiterleitungs-URLs mit der Ziel-URL, was bei sehr vielen Weiterleitungen oder stark besuchten ungecachten Websiten, die Performance verbessern kann. Zu beachten ist, das verkettete Weiterleitungen, welche die aktuelle Seite als Weiterleitungsendziel besitzen nicht mehr als aktiv gekennzeichnet werden (kein "isActive" mehr im Template und keine "active" CSS-Klasse).', +]; $GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showErrorPages'] - = array('Fehlerseiten anzeigen', 'Fehlerseiten vom Typ "403" und "404" werden in der Navigation angezeigt.'); + = ['Fehlerseiten anzeigen', 'Fehlerseiten vom Typ "403" und "404" werden in der Navigation angezeigt.']; $GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_disableHooks'] - = array('Hooks deaktivieren', 'Deaktiviert das Ausführen der Navigations-Hooks. Kann zu einer besseren Performance führen, wenn Hooks für diese Navigation nicht notwendig sind.'); + = [ + 'Hooks deaktivieren', + 'Deaktiviert das Ausführen der Navigations-Hooks. Kann zu einer besseren Performance führen, wenn Hooks für diese Navigation nicht notwendig sind.', +]; From 972947ae9611e0425ec21f032c32fb250090d7b3 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:15 +0200 Subject: [PATCH 03/75] Integrate database definition int dca file --- composer.json | 1 + src/Resources/contao/config/database.sql | 47 -------- src/Resources/contao/dca/tl_module.php | 142 +++++++++++++++++++++++ 3 files changed, 143 insertions(+), 47 deletions(-) delete mode 100644 src/Resources/contao/config/database.sql diff --git a/composer.json b/composer.json index 143b0ed..b498311 100644 --- a/composer.json +++ b/composer.json @@ -31,6 +31,7 @@ "require": { "php": "^7.4 || ^8.0", "contao/core-bundle": "^4.9", + "doctrine/dbal": "^2.11 || ^3.0", "symfony/http-kernel": "^4.4 || ^5.0" }, "require-dev": { diff --git a/src/Resources/contao/config/database.sql b/src/Resources/contao/config/database.sql deleted file mode 100644 index 546be95..0000000 --- a/src/Resources/contao/config/database.sql +++ /dev/null @@ -1,47 +0,0 @@ --- ******************************************************** --- * * --- * IMPORTANT NOTE * --- * * --- * Do not import this file manually but use the Contao * --- * install tool to create and maintain database tables! * --- * * --- ******************************************************** - -CREATE TABLE `tl_module` ( - --- general fields - `backboneit_navigation_roots` blob NULL, - `backboneit_navigation_roots_order` blob NULL, - `backboneit_navigation_start` smallint(5) NOT NULL default '0', - `backboneit_navigation_includeStart` char(1) NOT NULL default '', - `backboneit_navigation_respectHidden` char(1) NOT NULL default '', - `backboneit_navigation_respectPublish` char(1) NOT NULL default '', - `backboneit_navigation_respectGuests` char(1) NOT NULL default '', - `backboneit_navigation_showHiddenStart` char(1) NOT NULL default '', - `backboneit_navigation_showHidden` char(1) NOT NULL default '', - `backboneit_navigation_showProtected` char(1) NOT NULL default '', - `backboneit_navigation_showGuests` char(1) NOT NULL default '', - `backboneit_navigation_addFields` blob NULL, - `backboneit_navigation_noForwardResolution` char(1) NOT NULL default '', - `backboneit_navigation_showErrorPages` char(1) NOT NULL default '', - `backboneit_navigation_disableHooks` char(1) NOT NULL default '', - --- navigation menu fields - `backboneit_navigation_currentAsRoot` char(1) NOT NULL default '', - `backboneit_navigation_defineRoots` char(1) NOT NULL default '', - `backboneit_navigation_defineStop` char(1) NOT NULL default '', - `backboneit_navigation_stop` varchar(255) NOT NULL default '', - `backboneit_navigation_defineHard` char(1) NOT NULL default '', - `backboneit_navigation_hard` smallint(5) unsigned NOT NULL default '0', - `backboneit_navigation_isSitemap` char(1) NOT NULL default '', - `backboneit_navigation_hideSingleLevel` char(1) NOT NULL default '', - `backboneit_navigation_addLegacyCss` char(1) NOT NULL default '', - --- navigation preorder fields - `backboneit_navigation_rootSelectionType` varchar(32) NOT NULL default '', - `backboneit_navigation_chainDirections` blob NULL, - `backboneit_navigation_defineDepth` char(1) NOT NULL default '', - `backboneit_navigation_depth` smallint(5) unsigned NOT NULL default '0', - - -) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 2a81b07..788d0a0 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -1,5 +1,7 @@ 'clr', 'orderField' => 'backboneit_navigation_roots_order', ], + 'sql' => [ + 'type' => Types::BLOB, + 'default' => null, + 'notnull' => false, + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots_order'] = [ 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots_order'], + 'sql' => [ + 'type' => Types::BLOB, + 'default' => null, + 'notnull' => false, + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_start'] = [ @@ -113,6 +125,11 @@ 'rgxp' => 'digit', 'tl_class' => 'clr w50', ], + 'sql' => [ + 'type' => Types::SMALLINT, + 'default' => 0, + 'length' => 5, + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectHidden'] = [ @@ -122,6 +139,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectPublish'] = [ @@ -131,6 +153,11 @@ 'eval' => [ 'tl_class' => 'clr w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectGuests'] = [ @@ -140,6 +167,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_includeStart'] = [ @@ -150,6 +182,11 @@ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHiddenStart'] = [ @@ -159,6 +196,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHidden'] = [ @@ -168,6 +210,11 @@ 'eval' => [ 'tl_class' => 'clr w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showProtected'] = [ @@ -177,6 +224,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showGuests'] = [ @@ -186,6 +238,11 @@ 'eval' => [ 'tl_class' => 'clr w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addFields'] = [ @@ -197,6 +254,11 @@ 'multiple' => true, 'tl_class' => 'clr', ], + 'sql' => [ + 'type' => Types::BLOB, + 'default' => null, + 'notnull' => false, + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_noForwardResolution'] = [ @@ -206,6 +268,11 @@ 'eval' => [ 'tl_class' => 'clr w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showErrorPages'] = [ @@ -215,6 +282,11 @@ 'eval' => [ 'tl_class' => 'clr w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_disableHooks'] = [ @@ -224,6 +296,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; @@ -236,6 +313,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineRoots'] = [ @@ -246,6 +328,11 @@ 'submitOnChange' => true, 'tl_class' => 'w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineStop'] = [ @@ -256,6 +343,11 @@ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_stop'] = [ @@ -269,6 +361,11 @@ 'save_callback' => [ ['NavigationDCA', 'saveStop'], ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 255, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineHard'] = [ @@ -279,6 +376,11 @@ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hard'] = [ @@ -290,6 +392,11 @@ 'rgxp' => 'digit', 'tl_class' => 'w50', ], + 'sql' => [ + 'type' => Types::SMALLINT, + 'default' => 0, + 'length' => 5, + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_isSitemap'] = [ @@ -299,6 +406,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hideSingleLevel'] = [ @@ -308,6 +420,11 @@ 'eval' => [ 'tl_class' => 'clr w50 cbx', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addLegacyCss'] = [ @@ -317,6 +434,11 @@ 'eval' => [ 'tl_class' => 'w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; @@ -333,6 +455,11 @@ 'submitOnChange' => true, 'tl_class' => 'clr w50', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 32, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_chainDirections'] = [ @@ -349,6 +476,11 @@ 'multiple' => true, 'tl_class' => 'clr w50', ], + 'sql' => [ + 'type' => Types::BLOB, + 'default' => null, + 'notnull' => false, + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineDepth'] = [ @@ -359,6 +491,11 @@ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx m12', ], + 'sql' => [ + 'type' => Types::STRING, + 'length' => 1, + 'default' => '', + ], ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_depth'] = [ @@ -370,4 +507,9 @@ 'rgxp' => 'digit', 'tl_class' => 'w50', ], + 'sql' => [ + 'type' => Types::SMALLINT, + 'default' => 0, + 'length' => 5, + ], ]; From a9caa977224ed7e2420e7dc35aab95bedfa4eb4d Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:15 +0200 Subject: [PATCH 04/75] Register callbacks using service annotations --- composer.json | 2 + .../HofffContaoNavigationExtension.php | 20 +++++++ src/EventListener/Dca/NavigationDCA.php | 54 ----------------- .../Dca/NavigationDcaListener.php | 59 +++++++++++++++++++ src/Resources/config/services.xml | 14 +++++ src/Resources/contao/dca/tl_module.php | 4 -- 6 files changed, 95 insertions(+), 58 deletions(-) create mode 100644 src/DependencyInjection/HofffContaoNavigationExtension.php delete mode 100644 src/EventListener/Dca/NavigationDCA.php create mode 100644 src/EventListener/Dca/NavigationDcaListener.php create mode 100644 src/Resources/config/services.xml diff --git a/composer.json b/composer.json index b498311..688cfb1 100644 --- a/composer.json +++ b/composer.json @@ -32,6 +32,8 @@ "php": "^7.4 || ^8.0", "contao/core-bundle": "^4.9", "doctrine/dbal": "^2.11 || ^3.0", + "symfony/config": "^4.4 || ^5.0", + "symfony/dependency-injection": "^4.4 || ^5.0", "symfony/http-kernel": "^4.4 || ^5.0" }, "require-dev": { diff --git a/src/DependencyInjection/HofffContaoNavigationExtension.php b/src/DependencyInjection/HofffContaoNavigationExtension.php new file mode 100644 index 0000000..a6c7f18 --- /dev/null +++ b/src/DependencyInjection/HofffContaoNavigationExtension.php @@ -0,0 +1,20 @@ +load('services.xml'); + } +} diff --git a/src/EventListener/Dca/NavigationDCA.php b/src/EventListener/Dca/NavigationDCA.php deleted file mode 100644 index fd541e3..0000000 --- a/src/EventListener/Dca/NavigationDCA.php +++ /dev/null @@ -1,54 +0,0 @@ -loadLanguageFile('tl_page'); - $this->loadDataContainer('tl_page'); - - $arrFields = []; - - foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) { - if (! isset(AbstractModuleNavigation::$arrDefaultFields[$strField])) { - $arrFields[$strField] = &$arrConfig['label'][0]; - } - } - - return $arrFields; - } - - public function saveStop($varValue) - { - $intMin = -1; - foreach (array_map('intval', explode(',', strval($varValue))) as $intLevel) { - if ($intLevel > $intMin) { - $arrStop[] = $intMin = $intLevel; - } - } - - return implode(',', $arrStop); - } - - protected function __construct() - { - parent::__construct(); - } - - private static $objInstance; - - public static function getInstance() - { - if (! isset(self::$objInstance)) { - self::$objInstance = new self(); - } - - return self::$objInstance; - } -} diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php new file mode 100644 index 0000000..9fff433 --- /dev/null +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -0,0 +1,59 @@ +framework = $framework; + } + + /** + * @Callback(table="tl_module", target="fields.backboneit_navigation_addFields.options") + * + * @return array + */ + public function getPageFields(): array + { + $controller = $this->framework->getAdapter(Controller::class); + $controller->loadLanguageFile('tl_page'); + $controller->loadDataContainer('tl_page'); + + $fields = []; + + foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) { + if (! isset(AbstractModuleNavigation::$arrDefaultFields[$strField])) { + $fields[$strField] = &$arrConfig['label'][0]; + } + } + + return $fields; + } + + /** + * @param mixed $value + * + * @Callback(table="tl_module", target="fields.backboneit_navigation_stop.save") + */ + public function saveStop($value): string + { + $intMin = -1; + $stop = []; + + foreach (array_map('intval', explode(',', (string) $value)) as $intLevel) { + if ($intLevel > $intMin) { + $stop[] = $intMin = $intLevel; + } + } + + return implode(',', $stop); + } +} diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml new file mode 100644 index 0000000..313b04b --- /dev/null +++ b/src/Resources/config/services.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 788d0a0..80c3d64 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -249,7 +249,6 @@ 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addFields'], 'exclude' => true, 'inputType' => 'checkbox', - 'options_callback' => ['NavigationDCA', 'getPageFields'], 'eval' => [ 'multiple' => true, 'tl_class' => 'clr', @@ -358,9 +357,6 @@ 'maxlength' => 255, 'tl_class' => 'w50', ], - 'save_callback' => [ - ['NavigationDCA', 'saveStop'], - ], 'sql' => [ 'type' => Types::STRING, 'length' => 255, From d033ba489174f680e930ab9367a56c36ec42494e Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:15 +0200 Subject: [PATCH 05/75] Remove labels --- src/Resources/contao/dca/tl_module.php | 94 +++++++++----------------- 1 file changed, 33 insertions(+), 61 deletions(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 80c3d64..b60bc95 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -91,7 +91,6 @@ /***** GENERAL FIELDS *********************************************************/ $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots'], 'exclude' => true, 'inputType' => 'pageTree', 'eval' => [ @@ -100,7 +99,7 @@ 'tl_class' => 'clr', 'orderField' => 'backboneit_navigation_roots_order', ], - 'sql' => [ + 'sql' => [ 'type' => Types::BLOB, 'default' => null, 'notnull' => false, @@ -108,7 +107,6 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots_order'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_roots_order'], 'sql' => [ 'type' => Types::BLOB, 'default' => null, @@ -117,7 +115,6 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_start'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_start'], 'exclude' => true, 'inputType' => 'text', 'eval' => [ @@ -125,7 +122,7 @@ 'rgxp' => 'digit', 'tl_class' => 'clr w50', ], - 'sql' => [ + 'sql' => [ 'type' => Types::SMALLINT, 'default' => 0, 'length' => 5, @@ -133,13 +130,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectHidden'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectHidden'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -147,13 +143,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectPublish'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectPublish'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'clr w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -161,13 +156,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectGuests'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_respectGuests'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -175,14 +169,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_includeStart'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_includeStart'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -190,13 +183,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHiddenStart'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showHiddenStart'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -204,13 +196,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHidden'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showHidden'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'clr w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -218,13 +209,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showProtected'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showProtected'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -232,13 +222,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showGuests'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showGuests'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'clr w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -246,14 +235,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addFields'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addFields'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => [ + 'exclude' => true, + 'inputType' => 'checkbox', + 'eval' => [ 'multiple' => true, 'tl_class' => 'clr', ], - 'sql' => [ + 'sql' => [ 'type' => Types::BLOB, 'default' => null, 'notnull' => false, @@ -261,13 +249,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_noForwardResolution'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_noForwardResolution'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'clr w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -275,13 +262,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showErrorPages'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showErrorPages'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'clr w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -289,13 +275,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_disableHooks'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_disableHooks'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -306,13 +291,12 @@ /***** NAVIGATION MENU ********************************************************/ $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_currentAsRoot'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_currentAsRoot'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -320,14 +304,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineRoots'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineRoots'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'submitOnChange' => true, 'tl_class' => 'w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -335,14 +318,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineStop'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineStop'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -350,14 +332,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_stop'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_stop'], - 'exclude' => true, - 'inputType' => 'text', - 'eval' => [ + 'exclude' => true, + 'inputType' => 'text', + 'eval' => [ 'maxlength' => 255, 'tl_class' => 'w50', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 255, 'default' => '', @@ -365,14 +346,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineHard'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineHard'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -380,7 +360,6 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hard'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_hard'], 'exclude' => true, 'inputType' => 'text', 'eval' => [ @@ -388,7 +367,7 @@ 'rgxp' => 'digit', 'tl_class' => 'w50', ], - 'sql' => [ + 'sql' => [ 'type' => Types::SMALLINT, 'default' => 0, 'length' => 5, @@ -396,13 +375,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_isSitemap'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_isSitemap'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -410,13 +388,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hideSingleLevel'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_hideSingleLevel'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'clr w50 cbx', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -424,13 +401,12 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addLegacyCss'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_addLegacyCss'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'tl_class' => 'w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -441,7 +417,6 @@ /***** NAVIGATION CHAIN *******************************************************/ $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_rootSelectionType'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_rootSelectionType'], 'exclude' => true, 'inputType' => 'select', 'default' => 'current', @@ -451,7 +426,7 @@ 'submitOnChange' => true, 'tl_class' => 'clr w50', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 32, 'default' => '', @@ -459,7 +434,6 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_chainDirections'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_chainDirections'], 'exclude' => true, 'inputType' => 'checkbox', 'default' => ['forward', 'backward'], @@ -472,7 +446,7 @@ 'multiple' => true, 'tl_class' => 'clr w50', ], - 'sql' => [ + 'sql' => [ 'type' => Types::BLOB, 'default' => null, 'notnull' => false, @@ -480,14 +454,13 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineDepth'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_defineDepth'], 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ 'submitOnChange' => true, 'tl_class' => 'clr w50 cbx m12', ], - 'sql' => [ + 'sql' => [ 'type' => Types::STRING, 'length' => 1, 'default' => '', @@ -495,7 +468,6 @@ ]; $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_depth'] = [ - 'label' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_depth'], 'exclude' => true, 'inputType' => 'text', 'eval' => [ @@ -503,7 +475,7 @@ 'rgxp' => 'digit', 'tl_class' => 'w50', ], - 'sql' => [ + 'sql' => [ 'type' => Types::SMALLINT, 'default' => 0, 'length' => 5, From e256be8d43291954486614e0065af92293cdc538 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:15 +0200 Subject: [PATCH 06/75] Drop navigation chain fields They are not used anywhere --- src/Resources/contao/dca/tl_module.php | 71 -------------------------- 1 file changed, 71 deletions(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index b60bc95..c0ad865 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -84,8 +84,6 @@ = 'backboneit_navigation_stop'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineHard'] = 'backboneit_navigation_hard'; -$GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineDepth'] - = 'backboneit_navigation_depth'; /***** GENERAL FIELDS *********************************************************/ @@ -412,72 +410,3 @@ 'default' => '', ], ]; - - -/***** NAVIGATION CHAIN *******************************************************/ - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_rootSelectionType'] = [ - 'exclude' => true, - 'inputType' => 'select', - 'default' => 'current', - 'options' => ['subtrees', 'single', 'current'], - 'reference' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_rootSelectionType_options'], - 'eval' => [ - 'submitOnChange' => true, - 'tl_class' => 'clr w50', - ], - 'sql' => [ - 'type' => Types::STRING, - 'length' => 32, - 'default' => '', - ], -]; - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_chainDirections'] = [ - 'exclude' => true, - 'inputType' => 'checkbox', - 'default' => ['forward', 'backward'], - 'options' => [ - 'forward', /*'top', */ - 'backward', - ], - 'reference' => &$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_chainDirections_options'], - 'eval' => [ - 'multiple' => true, - 'tl_class' => 'clr w50', - ], - 'sql' => [ - 'type' => Types::BLOB, - 'default' => null, - 'notnull' => false, - ], -]; - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineDepth'] = [ - 'exclude' => true, - 'inputType' => 'checkbox', - 'eval' => [ - 'submitOnChange' => true, - 'tl_class' => 'clr w50 cbx m12', - ], - 'sql' => [ - 'type' => Types::STRING, - 'length' => 1, - 'default' => '', - ], -]; - -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_depth'] = [ - 'exclude' => true, - 'inputType' => 'text', - 'eval' => [ - 'maxlength' => 5, - 'rgxp' => 'digit', - 'tl_class' => 'w50', - ], - 'sql' => [ - 'type' => Types::SMALLINT, - 'default' => 0, - 'length' => 5, - ], -]; From d2d5392f1fc62b8c7d9fae1f73ae9d31cb7c5f9e Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:16 +0200 Subject: [PATCH 07/75] Rename field prefix to hofff_navigation_ --- .../Dca/NavigationDcaListener.php | 4 +- .../AbstractModuleNavigation.php | 12 +-- src/FrontendModule/ModuleNavigationMenu.php | 52 +++++----- src/Migration/BackboneNavigationMigration.php | 97 +++++++++++++++++++ src/Resources/config/services.xml | 5 + src/Resources/contao/dca/tl_module.php | 44 ++++----- .../contao/languages/de/tl_module.php | 50 +++++----- 7 files changed, 183 insertions(+), 81 deletions(-) create mode 100644 src/Migration/BackboneNavigationMigration.php diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index 9fff433..c7d45d6 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -17,7 +17,7 @@ public function __construct(ContaoFramework $framework) } /** - * @Callback(table="tl_module", target="fields.backboneit_navigation_addFields.options") + * @Callback(table="tl_module", target="fields.hofff_navigation_addFields.options") * * @return array */ @@ -41,7 +41,7 @@ public function getPageFields(): array /** * @param mixed $value * - * @Callback(table="tl_module", target="fields.backboneit_navigation_stop.save") + * @Callback(table="tl_module", target="fields.hofff_navigation_stop.save") */ public function saveStop($value): string { diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index 24457fa..2163c63 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -99,7 +99,7 @@ public function __construct($objModule, $strColumn = 'main') $this->import('Database'); - $this->varActiveID = $this->backboneit_navigation_isSitemap || $this->Input->get( + $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get( 'articles' ) ? false : $GLOBALS['objPage']->id; $this->arrTrail = array_flip($GLOBALS['objPage']->trail); @@ -113,7 +113,7 @@ public function __construct($objModule, $strColumn = 'main') $this->navigationTpl = 'nav_default'; } - $arrFields = deserialize($this->backboneit_navigation_addFields, true); + $arrFields = deserialize($this->hofff_navigation_addFields, true); if (count($arrFields) > 10) { $this->arrFields[] = '*'; @@ -155,7 +155,7 @@ public function __construct($objModule, $strColumn = 'main') ORDER BY sorting LIMIT 0, 1'; - if (! $this->backboneit_navigation_disableHooks) { + if (! $this->hofff_navigation_disableHooks) { $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_tree']); $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['bbit_navi_item']); } @@ -581,7 +581,7 @@ public function encodeEmailURL($strHref) public function isPermissionCheckRequired() { - return ! BE_USER_LOGGED_IN && ! $this->backboneit_navigation_showProtected; + return ! BE_USER_LOGGED_IN && ! $this->hofff_navigation_showProtected; } /** @@ -623,7 +623,7 @@ public function isPermissionDenied($arrPage) * page dataset, in regards to the current navigation settings and the * permission requirements of the page. * - * Context property: backboneit_navigation_showProtected + * Context property: hofff_navigation_showProtected * * @param array $arrPage The page dataset of the current page, with at least * groups and protected attributes set. @@ -637,7 +637,7 @@ public function isPermissionGranted($arrPage) return true; } - if ($this->backboneit_navigation_showProtected) // protection is ignored + if ($this->hofff_navigation_showProtected) // protection is ignored { return true; } diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 3c692fc..df0c442 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -26,7 +26,7 @@ public function generate() $arrRootIDs = $this->executeMenuHook($arrRootIDs); $arrFirstIDs = $this->getFirstNavigationLevel($arrRootIDs); - if ($this->backboneit_navigation_hideSingleLevel) { + if ($this->hofff_navigation_hideSingleLevel) { foreach ($arrFirstIDs as $id) { if ($this->arrSubitems[$id]) { $hasMultipleLevels = true; @@ -48,11 +48,11 @@ public function generate() public function getStop() { - if (! $this->backboneit_navigation_defineStop) { + if (! $this->hofff_navigation_defineStop) { return [PHP_INT_MAX]; } $intMin = -1; - foreach (array_map('intval', explode(',', $this->backboneit_navigation_stop)) as $intLevel) { + foreach (array_map('intval', explode(',', $this->hofff_navigation_stop)) as $intLevel) { if ($intLevel > $intMin) { $arrStop[] = $intMin = $intLevel; } @@ -63,7 +63,7 @@ public function getStop() public function getHard() { - return $this->backboneit_navigation_defineHard ? $this->backboneit_navigation_hard : PHP_INT_MAX; + return $this->hofff_navigation_defineHard ? $this->hofff_navigation_hard : PHP_INT_MAX; } protected function compile() @@ -71,50 +71,50 @@ protected function compile() $this->Template->request = $this->getIndexFreeRequest(true); $this->Template->skipId = 'skipNavigation' . $this->id; $this->Template->items = $this->strNavigation; - $this->backboneit_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; + $this->hofff_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; } protected function calculateRootIDs($arrStop = PHP_INT_MAX) { - $arrRootIDs = $this->backboneit_navigation_defineRoots + $arrRootIDs = $this->hofff_navigation_defineRoots ? $this->getRootIds() : [$GLOBALS['objPage']->rootId]; - $this->backboneit_navigation_currentAsRoot && array_unshift($arrRootIDs, $GLOBALS['objPage']->id); + $this->hofff_navigation_currentAsRoot && array_unshift($arrRootIDs, $GLOBALS['objPage']->id); $arrConditions = [ $this->getQueryPartHidden( - ! $this->backboneit_navigation_respectHidden, - $this->backboneit_navigation_isSitemap + ! $this->hofff_navigation_respectHidden, + $this->hofff_navigation_isSitemap ), ]; - $this->backboneit_navigation_respectGuests && $arrConditions[] = $this->getQueryPartGuests(); - $this->backboneit_navigation_respectPublish && $arrConditions[] = $this->getQueryPartPublish(); + $this->hofff_navigation_respectGuests && $arrConditions[] = $this->getQueryPartGuests(); + $this->hofff_navigation_respectPublish && $arrConditions[] = $this->getQueryPartPublish(); $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - if ($this->backboneit_navigation_includeStart) { + if ($this->hofff_navigation_includeStart) { $arrStartConditions = [ $this->getQueryPartHidden( - $this->backboneit_navigation_showHiddenStart, - $this->backboneit_navigation_isSitemap + $this->hofff_navigation_showHiddenStart, + $this->hofff_navigation_isSitemap ), $this->getQueryPartPublish(), - $this->getQueryPartErrorPages($this->backboneit_navigation_showErrorPages), + $this->getQueryPartErrorPages($this->hofff_navigation_showErrorPages), ]; - ! $this->backboneit_navigation_showGuests && $arrStartConditions[] = $this->getQueryPartGuests(); + ! $this->hofff_navigation_showGuests && $arrStartConditions[] = $this->getQueryPartGuests(); $strStartConditions = implode(' AND ', array_filter($arrStartConditions, 'strlen')); } else { $strStartConditions = $strConditions; } - if ($this->backboneit_navigation_start > 0) { + if ($this->hofff_navigation_start > 0) { $arrRootIDs = $this->filterPages($arrRootIDs, $strConditions); - for ($i = 1, $n = $this->backboneit_navigation_start; $i < $n; $i++) { + for ($i = 1, $n = $this->hofff_navigation_start; $i < $n; $i++) { $arrRootIDs = $this->getNextLevel($arrRootIDs, $strConditions); } $arrRootIDs = $this->getNextLevel($arrRootIDs, $strStartConditions); - } elseif ($this->backboneit_navigation_start < 0) { - for ($i = 0, $n = -$this->backboneit_navigation_start; $i < $n; $i++) { + } elseif ($this->hofff_navigation_start < 0) { + for ($i = 0, $n = -$this->hofff_navigation_start; $i < $n; $i++) { $arrRootIDs = $this->getPrevLevel($arrRootIDs); } $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); @@ -145,7 +145,7 @@ public function compileNavigationTree(array $arrRootIDs, $arrStop = PHP_INT_MAX, $this->arrItems[$intRootID] = (array) $this->arrItems[$intRootID]; } - if ($this->backboneit_navigation_includeStart) { + if ($this->hofff_navigation_includeStart) { $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard, 2); $objRoots = $this->objStmt->query( @@ -162,7 +162,7 @@ public function compileNavigationTree(array $arrRootIDs, $arrStop = PHP_INT_MAX, $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard); } - $blnForwardResolution = ! $this->backboneit_navigation_noForwardResolution; + $blnForwardResolution = ! $this->hofff_navigation_noForwardResolution; foreach ($arrFetched as $intID => $_) { $this->arrItems[$intID] = $this->compileNavigationItem( $this->arrItems[$intID], @@ -194,11 +194,11 @@ protected function fetchItems(array $arrPIDs, $arrStop = PHP_INT_MAX, $intHard = } $arrConditions = [ - $this->getQueryPartHidden($this->backboneit_navigation_showHidden, $this->backboneit_navigation_isSitemap), + $this->getQueryPartHidden($this->hofff_navigation_showHidden, $this->hofff_navigation_isSitemap), $this->getQueryPartPublish(), - $this->getQueryPartErrorPages($this->backboneit_navigation_showErrorPages), + $this->getQueryPartErrorPages($this->hofff_navigation_showErrorPages), ]; - ! $this->backboneit_navigation_showGuests && $arrConditions[] = $this->getQueryPartGuests(); + ! $this->hofff_navigation_showGuests && $arrConditions[] = $this->getQueryPartGuests(); $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); $strConditions && $strConditions = 'AND (' . $strConditions . ')'; @@ -276,7 +276,7 @@ protected function fetchItems(array $arrPIDs, $arrStop = PHP_INT_MAX, $intHard = */ protected function executeMenuHook(array $arrRootIDs, $blnForce = false) { - if (! $blnForce && $this->backboneit_navigation_disableHooks) { + if (! $blnForce && $this->hofff_navigation_disableHooks) { return $arrRootIDs; } if (! is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'])) { diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php new file mode 100644 index 0000000..2aa6715 --- /dev/null +++ b/src/Migration/BackboneNavigationMigration.php @@ -0,0 +1,97 @@ +connection = $connection; + } + + public function shouldRun(): bool + { + $affectedFields = $this->determineAffectedFields(); + + return $affectedFields !== []; + } + + public function run(): MigrationResult + { + $affectedFields = $this->determineAffectedFields(); + + foreach ($affectedFields as $field) { + $this->renameField($field); + } + + return $this->createResult(true, 'Renamed field prefix from backboneit_navigation_ to hofff_navigation_.'); + } + + /** @return list */ + private function determineAffectedFields(): array + { + $table = $this->connection->getSchemaManager()->listTableDetails('tl_module'); + $fields = []; + + foreach (self::FIELDS as $field) { + if (! $table->hasColumn(self::OLD_PREFIX . $field) || $table->hasColumn(self::NEW_PREFIX . $field)) { + continue; + } + + $fields[] = $field; + } + + return $fields; + } + + private function renameField(string $field): void + { + $this->connection->executeStatement( + sprintf( + 'ALTER TABLE tl_module RENAME COLUMN %s%s TO %s%s', + self::OLD_PREFIX, + $field, + self::NEW_PREFIX, + $field, + ) + ); + } +} diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 313b04b..c673be8 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -10,5 +10,10 @@ + + + + + diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index c0ad865..c94904b 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -2,33 +2,33 @@ use Doctrine\DBAL\Types\Types; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_rootSelectionType'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_defineRoots'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_includeStart'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_defineStop'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_defineHard'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'backboneit_navigation_defineDepth'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_rootSelectionType'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineRoots'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_includeStart'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineStop'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineHard'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineDepth'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_menu'] = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_currentAsRoot,backboneit_navigation_defineRoots,' - . 'backboneit_navigation_start,backboneit_navigation_respectHidden,' - . 'backboneit_navigation_respectPublish,backboneit_navigation_respectGuests;' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_includeStart,' - . 'backboneit_navigation_defineStop,' - . 'backboneit_navigation_defineHard,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected,' - . 'backboneit_navigation_showGuests,backboneit_navigation_isSitemap,' - . 'backboneit_navigation_hideSingleLevel;' - . '{template_legend:hide},navigationTpl,backboneit_navigation_addLegacyCss,' - . 'backboneit_navigation_addFields;' + . '{hofff_navigation_root_legend},' + . 'hofff_navigation_currentAsRoot,hofff_navigation_defineRoots,' + . 'hofff_navigation_start,hofff_navigation_respectHidden,' + . 'hofff_navigation_respectPublish,hofff_navigation_respectGuests;' + . '{hofff_navigation_legend},' + . 'hofff_navigation_includeStart,' + . 'hofff_navigation_defineStop,' + . 'hofff_navigation_defineHard,' + . 'hofff_navigation_showHidden,hofff_navigation_showProtected,' + . 'hofff_navigation_showGuests,hofff_navigation_isSitemap,' + . 'hofff_navigation_hideSingleLevel;' + . '{template_legend:hide},navigationTpl,hofff_navigation_addLegacyCss,' + . 'hofff_navigation_addFields;' . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; + . '{expert_legend:hide},hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages,hofff_navigation_disableHooks,guests,cssID,space'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chain'] - = '{title_legend},name,type,backboneit_navigation_rootSelectionType'; +$GLOBALS['TL_DCA']['tl_module']['palettes']['hofff_navigation_chain'] + = '{title_legend},name,type,hofff_navigation_rootSelectionType'; $GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chainsingle'] = '{title_legend},name,headline,type;' diff --git a/src/Resources/contao/languages/de/tl_module.php b/src/Resources/contao/languages/de/tl_module.php index d811e87..cbf1a1e 100644 --- a/src/Resources/contao/languages/de/tl_module.php +++ b/src/Resources/contao/languages/de/tl_module.php @@ -1,95 +1,95 @@ verkettete Weiterleitungen, welche die aktuelle Seite als Weiterleitungsendziel besitzen nicht mehr als aktiv gekennzeichnet werden (kein "isActive" mehr im Template und keine "active" CSS-Klasse).', ]; -$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_showErrorPages'] +$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_showErrorPages'] = ['Fehlerseiten anzeigen', 'Fehlerseiten vom Typ "403" und "404" werden in der Navigation angezeigt.']; -$GLOBALS['TL_LANG']['tl_module']['backboneit_navigation_disableHooks'] +$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_disableHooks'] = [ 'Hooks deaktivieren', 'Deaktiviert das Ausführen der Navigations-Hooks. Kann zu einer besseren Performance führen, wenn Hooks für diese Navigation nicht notwendig sind.', From 6f99a2bd250f7ea1bcda8ebb431ec2baf20f4a5b Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:16 +0200 Subject: [PATCH 08/75] Drop leftover chain references --- src/Resources/contao/dca/tl_module.php | 54 -------------------------- 1 file changed, 54 deletions(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index c94904b..e93b9a2 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -27,55 +27,6 @@ . '{protected_legend:hide},protected;' . '{expert_legend:hide},hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages,hofff_navigation_disableHooks,guests,cssID,space'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['hofff_navigation_chain'] - = '{title_legend},name,type,hofff_navigation_rootSelectionType'; - -$GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chainsingle'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_rootSelectionType,' - . 'backboneit_navigation_roots,' - . 'backboneit_navigation_respectPublish;' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_chainDirections,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected,' - . 'backboneit_navigation_showGuests;' - . '{template_legend:hide},navigationTpl,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; - -$GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chainsubtrees'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_rootSelectionType,' - . 'backboneit_navigation_roots,' - . 'backboneit_navigation_start,backboneit_navigation_includeStart,' - . 'backboneit_navigation_respectHidden,backboneit_navigation_respectPublish,' - . 'backboneit_navigation_respectGuests;' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_chainDirections,' - . 'backboneit_navigation_defineDepth,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected;' - . 'backboneit_navigation_showGuests;' - . '{template_legend:hide},navigationTpl,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; - -$GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_chaincurrent'] - = '{title_legend},name,headline,type;' - . '{backboneit_navigation_root_legend},' - . 'backboneit_navigation_rootSelectionType,' - . '{backboneit_navigation_legend},' - . 'backboneit_navigation_chainDirections,' - . 'backboneit_navigation_showHidden,backboneit_navigation_showProtected;' - . 'backboneit_navigation_showGuests;' - . '{template_legend:hide},navigationTpl,' - . 'backboneit_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},backboneit_navigation_noForwardResolution,backboneit_navigation_showErrorPages,backboneit_navigation_disableHooks,guests,cssID,space'; - $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineRoots'] = 'backboneit_navigation_roots'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_includeStart'] @@ -86,8 +37,6 @@ = 'backboneit_navigation_hard'; -/***** GENERAL FIELDS *********************************************************/ - $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots'] = [ 'exclude' => true, 'inputType' => 'pageTree', @@ -285,9 +234,6 @@ ], ]; - -/***** NAVIGATION MENU ********************************************************/ - $GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_currentAsRoot'] = [ 'exclude' => true, 'inputType' => 'checkbox', From dd62bf9b772a980d2bd8df3d4fb0c58d5aed1921 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:16 +0200 Subject: [PATCH 09/75] Rename leftover field prefixes --- src/FrontendModule/ModuleNavigationMenu.php | 6 +- src/Resources/contao/dca/tl_module.php | 69 +++++++++++---------- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index df0c442..8ee0739 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -297,7 +297,7 @@ protected function executeMenuHook(array $arrRootIDs, $blnForce = false) protected function getFirstNavigationLevel(array $arrRootIDs) { - if ($this->backboneit_navigation_includeStart) { + if ($this->hofff_navigation_includeStart) { return $arrRootIDs; } @@ -319,8 +319,8 @@ protected function getRootIds() array_values( array_unique( array_merge( - \Contao\StringUtil::deserialize($this->backboneit_navigation_roots_order, true), - \Contao\StringUtil::deserialize($this->backboneit_navigation_roots, true) + \Contao\StringUtil::deserialize($this->hofff_navigation_roots_order, true), + \Contao\StringUtil::deserialize($this->hofff_navigation_roots, true) ) ) ) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index e93b9a2..d467e71 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -25,26 +25,27 @@ . '{template_legend:hide},navigationTpl,hofff_navigation_addLegacyCss,' . 'hofff_navigation_addFields;' . '{protected_legend:hide},protected;' - . '{expert_legend:hide},hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages,hofff_navigation_disableHooks,guests,cssID,space'; + . '{expert_legend:hide},hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages,' + . 'hofff_navigation_disableHooks,guests,cssID,space'; -$GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineRoots'] - = 'backboneit_navigation_roots'; -$GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_includeStart'] - = 'backboneit_navigation_showHiddenStart'; -$GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineStop'] - = 'backboneit_navigation_stop'; -$GLOBALS['TL_DCA']['tl_module']['subpalettes']['backboneit_navigation_defineHard'] - = 'backboneit_navigation_hard'; +$GLOBALS['TL_DCA']['tl_module']['subpalettes']['hofff_navigation_defineRoots'] + = 'hofff_navigation_roots'; +$GLOBALS['TL_DCA']['tl_module']['subpalettes']['hofff_navigation_includeStart'] + = 'hofff_navigation_showHiddenStart'; +$GLOBALS['TL_DCA']['tl_module']['subpalettes']['hofff_navigation_defineStop'] + = 'hofff_navigation_stop'; +$GLOBALS['TL_DCA']['tl_module']['subpalettes']['hofff_navigation_defineHard'] + = 'hofff_navigation_hard'; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_roots'] = [ 'exclude' => true, 'inputType' => 'pageTree', 'eval' => [ 'multiple' => true, 'fieldType' => 'checkbox', 'tl_class' => 'clr', - 'orderField' => 'backboneit_navigation_roots_order', + 'orderField' => 'hofff_navigation_roots_order', ], 'sql' => [ 'type' => Types::BLOB, @@ -53,7 +54,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_roots_order'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_roots_order'] = [ 'sql' => [ 'type' => Types::BLOB, 'default' => null, @@ -61,7 +62,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_start'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_start'] = [ 'exclude' => true, 'inputType' => 'text', 'eval' => [ @@ -76,7 +77,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectHidden'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_respectHidden'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -89,7 +90,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectPublish'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_respectPublish'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -102,7 +103,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_respectGuests'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_respectGuests'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -115,7 +116,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_includeStart'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_includeStart'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -129,7 +130,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHiddenStart'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_showHiddenStart'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -142,7 +143,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showHidden'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_showHidden'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -155,7 +156,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showProtected'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_showProtected'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -168,7 +169,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showGuests'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_showGuests'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -181,7 +182,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addFields'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_addFields'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -195,7 +196,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_noForwardResolution'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_noForwardResolution'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -208,7 +209,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_showErrorPages'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_showErrorPages'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -221,7 +222,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_disableHooks'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_disableHooks'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -234,7 +235,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_currentAsRoot'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_currentAsRoot'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -247,7 +248,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineRoots'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_defineRoots'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -261,7 +262,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineStop'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_defineStop'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -275,7 +276,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_stop'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_stop'] = [ 'exclude' => true, 'inputType' => 'text', 'eval' => [ @@ -289,7 +290,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_defineHard'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_defineHard'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -303,7 +304,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hard'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_hard'] = [ 'exclude' => true, 'inputType' => 'text', 'eval' => [ @@ -318,7 +319,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_isSitemap'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_isSitemap'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -331,7 +332,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_hideSingleLevel'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_hideSingleLevel'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ @@ -344,7 +345,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['backboneit_navigation_addLegacyCss'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_addLegacyCss'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ From c0ab43fbdda927af4b4d7a5ab10821dd74db6e5d Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:17 +0200 Subject: [PATCH 10/75] Use hoff prefix for module and hooks --- .../AbstractModuleNavigation.php | 4 +-- src/FrontendModule/ModuleNavigationMenu.php | 6 ++-- src/Migration/BackboneNavigationMigration.php | 28 +++++++++++++++++-- src/Resources/contao/config/config.php | 2 +- src/Resources/contao/dca/tl_module.php | 2 +- src/Resources/contao/languages/de/modules.php | 6 ++-- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index 2163c63..bdcc633 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -156,7 +156,7 @@ public function __construct($objModule, $strColumn = 'main') LIMIT 0, 1'; if (! $this->hofff_navigation_disableHooks) { - $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_tree']); + $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_tree']); $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['bbit_navi_item']); } } @@ -757,7 +757,7 @@ protected function executeTreeHook($blnForce = false) return; } - foreach ((array) $GLOBALS['TL_HOOKS']['backboneit_navigation_tree'] as $arrCallback) { + foreach ((array) $GLOBALS['TL_HOOKS']['hofff_navigation_tree'] as $arrCallback) { $this->import($arrCallback[0]); $this->{$arrCallback[0]}->{$arrCallback[1]}($this); } diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 8ee0739..5efb54a 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -5,7 +5,7 @@ class ModuleNavigationMenu extends AbstractModuleNavigation { - protected $strTemplate = 'mod_backboneit_navigation_menu'; + protected $strTemplate = 'mod_hofff_navigation_menu'; protected $strNavigation; @@ -279,11 +279,11 @@ protected function executeMenuHook(array $arrRootIDs, $blnForce = false) if (! $blnForce && $this->hofff_navigation_disableHooks) { return $arrRootIDs; } - if (! is_array($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'])) { + if (! is_array($GLOBALS['TL_HOOKS']['hofff_navigation_menu'])) { return $arrRootIDs; } - foreach ($GLOBALS['TL_HOOKS']['backboneit_navigation_menu'] as $arrCallback) { + foreach ($GLOBALS['TL_HOOKS']['hofff_navigation_menu'] as $arrCallback) { $this->import($arrCallback[0]); $arrNewRoots = $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrRootIDs); diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 2aa6715..10d2448 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -49,6 +49,10 @@ public function __construct(Connection $connection) public function shouldRun(): bool { + if ($this->hasBackboneItNavigationModules()) { + return true; + } + $affectedFields = $this->determineAffectedFields(); return $affectedFields !== []; @@ -56,13 +60,33 @@ public function shouldRun(): bool public function run(): MigrationResult { - $affectedFields = $this->determineAffectedFields(); + $this->renameNavigationModules(); + $affectedFields = $this->determineAffectedFields(); foreach ($affectedFields as $field) { $this->renameField($field); } - return $this->createResult(true, 'Renamed field prefix from backboneit_navigation_ to hofff_navigation_.'); + return $this->createResult(true); + } + + private function hasBackboneItNavigationModules(): bool + { + $result = $this->connection->executeQuery( + 'SELECT count(id) FROM tl_navigation WHERE type=:type', + ['type' => 'backboneit_navigation_menu'] + ); + + return $result->fetchOne() > 0; + } + + private function renameNavigationModules(): void + { + $this->connection->update( + 'tl_module', + ['type' => 'hofff_navigation_menu'], + ['type' => 'backboneit_navigation_menu'] + ); } /** @return list */ diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php index f77fbfb..b5ac27d 100644 --- a/src/Resources/contao/config/config.php +++ b/src/Resources/contao/config/config.php @@ -2,4 +2,4 @@ use Hofff\Contao\Navigation\FrontendModule\ModuleNavigationMenu; -$GLOBALS['FE_MOD']['navigationMenu']['backboneit_navigation_menu'] = ModuleNavigationMenu::class; +$GLOBALS['FE_MOD']['navigationMenu']['hofff_navigation_menu'] = ModuleNavigationMenu::class; diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index d467e71..3ed7ac5 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -9,7 +9,7 @@ $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineHard'; $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineDepth'; -$GLOBALS['TL_DCA']['tl_module']['palettes']['backboneit_navigation_menu'] +$GLOBALS['TL_DCA']['tl_module']['palettes']['hofff_navigation_menu'] = '{title_legend},name,headline,type;' . '{hofff_navigation_root_legend},' . 'hofff_navigation_currentAsRoot,hofff_navigation_defineRoots,' diff --git a/src/Resources/contao/languages/de/modules.php b/src/Resources/contao/languages/de/modules.php index 8abeee6..4cff4cf 100644 --- a/src/Resources/contao/languages/de/modules.php +++ b/src/Resources/contao/languages/de/modules.php @@ -1,7 +1,7 @@ Date: Mon, 30 May 2022 15:48:17 +0200 Subject: [PATCH 11/75] Remove contao < 3.5.5 compatibility layer --- src/FrontendModule/AbstractModuleNavigation.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index bdcc633..5defa14 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -3,6 +3,7 @@ namespace Hofff\Contao\Navigation\FrontendModule; use BackendTemplate; +use Contao\StringUtil; use Environment; use FrontendTemplate; use Module; @@ -572,11 +573,7 @@ public function encodeEmailURL($strHref) return $strHref; } - if (version_compare(VERSION . '.' . BUILD, '3.5.5', '>=')) { - return \StringUtil::encodeEmail($strHref); - } else { - return \String::encodeEmail($strHref); - } + return StringUtil::encodeEmail($strHref); } public function isPermissionCheckRequired() From e61e8bf6e8c47eda53b5cac63fbae2c3241c2ff9 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:18 +0200 Subject: [PATCH 12/75] Rename templates --- ..._navigation_menu.html5 => mod_hofff_navigation_menu.html5} | 4 ++-- .../contao/templates/{nav_bbit.html5 => nav_hofff.html5} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename src/Resources/contao/templates/{mod_backboneit_navigation_menu.html5 => mod_hofff_navigation_menu.html5} (78%) rename src/Resources/contao/templates/{nav_bbit.html5 => nav_hofff.html5} (100%) diff --git a/src/Resources/contao/templates/mod_backboneit_navigation_menu.html5 b/src/Resources/contao/templates/mod_hofff_navigation_menu.html5 similarity index 78% rename from src/Resources/contao/templates/mod_backboneit_navigation_menu.html5 rename to src/Resources/contao/templates/mod_hofff_navigation_menu.html5 index 10ed943..a18196a 100644 --- a/src/Resources/contao/templates/mod_backboneit_navigation_menu.html5 +++ b/src/Resources/contao/templates/mod_hofff_navigation_menu.html5 @@ -5,9 +5,9 @@ <hl; ?>>headline; ?>hl; ?>> - + items; ?> - \ No newline at end of file + diff --git a/src/Resources/contao/templates/nav_bbit.html5 b/src/Resources/contao/templates/nav_hofff.html5 similarity index 100% rename from src/Resources/contao/templates/nav_bbit.html5 rename to src/Resources/contao/templates/nav_hofff.html5 From ca5112cebc806fd8783bb8183d924b4a0a824913 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:18 +0200 Subject: [PATCH 13/75] Fix typo --- src/FrontendModule/AbstractModuleNavigation.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index 5defa14..04caac6 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -182,7 +182,7 @@ public function __get($strKey) * this navigations settings. * Maintains relative order of the input array. * - * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * * @param array $arrPages An array of page IDs to filter @@ -258,7 +258,7 @@ public function filterPages(array $arrPages, $strConditions = '') * given conditions, which are added to the WHERE clause of the query. * Maintains relative order of the input array. * - * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * * @param array $arrPages An array of parent IDs @@ -309,7 +309,7 @@ public function getNextLevel(array $arrPages, $strConditions = '') * Maintains relative order of the input array and merges subsequent parent * IDs. * - * For permance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * * @param array $arrPages An array of child IDs From c5fba898092a55bbae607aab38f7e466619550a0 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:18 +0200 Subject: [PATCH 14/75] Rename hook bbit_navi_item to hofff_navigation_item --- src/FrontendModule/AbstractModuleNavigation.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index 04caac6..e49b92c 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -158,7 +158,7 @@ public function __construct($objModule, $strColumn = 'main') if (! $this->hofff_navigation_disableHooks) { $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_tree']); - $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['bbit_navi_item']); + $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_item']); } } @@ -766,7 +766,7 @@ protected function executeItemHook(array &$arrPage, $blnForce = false) return; } - foreach ((array) $GLOBALS['TL_HOOKS']['bbit_navi_item'] as $arrCallback) { + foreach ((array) $GLOBALS['TL_HOOKS']['hofff_navigation_item'] as $arrCallback) { $this->import($arrCallback[0]); $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrPage); } From c9b19a23b751b1a83b53fbc6977288463cb1cd09 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:18 +0200 Subject: [PATCH 15/75] Split navigation module into smaller classes --- .../AbstractModuleNavigation.php | 366 +------------- src/FrontendModule/ModuleNavigationMenu.php | 252 ++-------- src/Items/PageItems.php | 27 + src/Items/PageItemsLoader.php | 256 ++++++++++ src/Migration/BackboneNavigationMigration.php | 2 +- src/QueryBuilder/PageQueryBuilder.php | 87 ++++ src/Renderer/NavigationRenderer.php | 468 ++++++++++++++++++ src/Resources/config/services.xml | 13 + 8 files changed, 891 insertions(+), 580 deletions(-) create mode 100644 src/Items/PageItems.php create mode 100644 src/Items/PageItemsLoader.php create mode 100644 src/QueryBuilder/PageQueryBuilder.php create mode 100644 src/Renderer/NavigationRenderer.php diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index e49b92c..aabff5b 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -2,11 +2,8 @@ namespace Hofff\Contao\Navigation\FrontendModule; -use BackendTemplate; -use Contao\StringUtil; -use Environment; -use FrontendTemplate; -use Module; +use Contao\BackendTemplate; +use Contao\Module; /** * Abstract base class for navigation modules @@ -14,7 +11,7 @@ * Navigation item array layout: * Before rendering: * id => the ID of the current item (optional) - * isTrail => whether this item is in the trail path + * isInTrail => whether this item is in the trail path * class => CSS classes * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities @@ -44,7 +41,6 @@ */ abstract class AbstractModuleNavigation extends Module { - const HOOK_DISABLE = 0; const HOOK_ENABLE = 1; const HOOK_FORCE = 2; @@ -71,21 +67,13 @@ abstract class AbstractModuleNavigation extends Module ]; protected $arrFields = []; // the fields to use for navigation tpl - protected $strJumpToQuery; - protected $strJumpToFallbackQuery; protected $objStmt; // a reusable stmt object protected $arrGroups; // set of groups of the current user - protected $arrTrail; // same as trail but with current page included public $varActiveID; // the id of the active page - public $arrItems = []; // compiled page datasets - public $arrSubitems = []; // ordered IDs of subnavigations - /** @Deprecated */ - public $arrSubpages; - protected $blnTreeHook = false; // execute tree hook? protected $blnItemHook = false; // execute item hook? @@ -96,14 +84,12 @@ public function __construct($objModule, $strColumn = 'main') return; } - $this->arrSubpages = &$this->arrSubitems; // for deprecated compat $this->import('Database'); - $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get( - 'articles' - ) ? false : $GLOBALS['objPage']->id; - $this->arrTrail = array_flip($GLOBALS['objPage']->trail); + $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get('articles') + ? false + : $GLOBALS['objPage']->id; if (FE_USER_LOGGED_IN) { $this->import('FrontendUser', 'User'); @@ -133,29 +119,6 @@ public function __construct($objModule, $strColumn = 'main') $this->objStmt = $this->Database->prepare('*'); - $arrConditions = [ - $this->getQueryPartGuests(), - $this->getQueryPartPublish(), - ]; - $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - $strConditions && $strConditions = ' AND (' . $strConditions . ')'; - - $this->strJumpToQuery = - 'SELECT * - FROM tl_page - WHERE id = ? - ' . $strConditions . ' - LIMIT 0, 1'; - - $this->strJumpToFallbackQuery = - 'SELECT * - FROM tl_page - WHERE pid = ? - AND type = \'regular\' - ' . $strConditions . ' - ORDER BY sorting - LIMIT 0, 1'; - if (! $this->hofff_navigation_disableHooks) { $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_tree']); $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_item']); @@ -347,235 +310,6 @@ public function getPrevLevel(array $arrPages, $strConditions = '') } - /** - * Renders the navigation of the given IDs into the navigation template. - * Adds CSS classes "first" and "last" to the appropriate navigation item arrays. - * If the given array is empty, the empty string is returned. - * - * @param array $arrRoots The navigation items arrays - * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $intLevel (optional, defaults to 1) The current level of this navigation layer - * - * @return string The parsed navigation template, could be empty string. - */ - protected function renderNavigationTree( - array $arrIDs, - $strTemplate, - $arrStop = PHP_INT_MAX, - $intHard = PHP_INT_MAX, - $intLevel = 1 - ) { - if (! $arrIDs) { - return ''; - } - - $arrStop = (array) $arrStop; - $arrStop || $arrStop = [PHP_INT_MAX]; - $intStop = $intLevel >= $arrStop[0] ? array_shift($arrStop) : $arrStop[0]; - $arrItems = []; - - foreach ($arrIDs as $varID) { - if (! $this->arrItems[$varID]) { - continue; - } - - $arrItem = $this->arrItems[$varID]; - - if ($varID == $this->varActiveID) { - $blnContainsActive = true; - - if ($arrItem['href'] === Environment::get('request')) { - $arrItem['isActive'] = true; // nothing else (active class is set in template) - $arrItem['isTrail'] = false; - } else { - $arrItem['isActive'] = false; // nothing else (active class is set in template) - $arrItem['isTrail'] = true; - } - } else { // do not flatten if/else - if ($arrItem['tid'] == $this->varActiveID) { - if ($arrItem['href'] === Environment::get('request')) { - $arrItem['isActive'] = true; // nothing else (active class is set in template) - $arrItem['isTrail'] = false; - } else { - $arrItem['isActive'] = false; // nothing else (active class is set in template) - $arrItem['isTrail'] = true; - } - } - } - - if ($arrItem['isTrail']) { - $arrItem['class'] .= ' trail'; - } - - if (! isset($this->arrSubitems[$varID])) { - $arrItem['class'] .= ' leaf'; - } elseif ($intLevel >= $intHard) { - // we are at hard level, never draw submenu - $arrItem['class'] .= ' submenu leaf'; - } elseif ($intLevel >= $intStop && ! $arrItem['isTrail'] && $varID !== $this->varActiveID && $arrItem['tid'] != $this->varActiveID) { - // we are at stop level and not trail and not active, never draw submenu - $arrItem['class'] .= ' submenu leaf'; - } elseif ($this->arrSubitems[$varID]) { - $arrItem['class'] .= ' submenu inner'; - $arrItem['subitems'] = $this->renderNavigationTree( - $this->arrSubitems[$varID], - $arrItem['template'], - $arrStop, - $intHard, - $intLevel + 1 - ); - } else { // should never be reached, if no hooks are used - $arrItem['class'] .= ' leaf'; - } - - $arrItems[] = $arrItem; - } - - if ($blnContainsActive) { - foreach ($arrItems as &$arrItem) { - if (! $arrItem['isActive']) { - $arrItem['class'] .= ' sibling'; - } - } - } - - $arrItems[0]['class'] .= ' first'; - $arrItems[count($arrItems) - 1]['class'] .= ' last'; - - foreach ($arrItems as &$arrItem) { - $arrItem['class'] = ltrim($arrItem['class']); - } - - strlen($strTemplate) || $strTemplate = $this->navigationTpl; - $objTemplate = new FrontendTemplate($strTemplate); - $objTemplate->setData([ - 'module' => $this->arrData, - 'level' => 'level_' . $intLevel, - 'items' => $arrItems, - 'type' => get_class($this), - ]); - - return $objTemplate->parse(); - } - - /** - * Compiles a navigation item array from a page dataset with the given subnavi - * - * @param array $arrPage The page dataset as an array - * - * @return array The compiled navigation item array - */ - public function compileNavigationItem( - array $arrPage, - $blnForwardResolution = true, - $intItemHook = self::HOOK_DISABLE - ) { - // fallback for dataset field collisions - $arrPage['_title'] = $arrPage['title']; - $arrPage['_pageTitle'] = $arrPage['pageTitle']; - $arrPage['_target'] = $arrPage['target']; - $arrPage['_description'] = $arrPage['description']; - - $arrPage['link'] = $arrPage['_title']; - $arrPage['class'] = $arrPage['cssClass'] . ' ' . $arrPage['type']; - $arrPage['title'] = specialchars($arrPage['_title'], true); - $arrPage['pageTitle'] = specialchars($arrPage['_pageTitle'], true); - $arrPage['target'] = ''; // overwrite DB value - $arrPage['nofollow'] = strncmp($arrPage['robots'], 'noindex', 7) === 0; - $arrPage['description'] = str_replace(["\n", "\r"], [' ', ''], $arrPage['_description']); - $arrPage['isTrail'] = isset($this->arrTrail[$arrPage['id']]); - - switch ($arrPage['type']) { - case 'forward': - if ($blnForwardResolution) { - if ($arrPage['jumpTo']) { - $intFallbackSearchID = $arrPage['id']; - $intJumpToID = $arrPage['jumpTo']; - do { - $objNext = $this->objStmt->prepare($this->strJumpToQuery)->execute($intJumpToID); - - if (! $objNext->numRows) { - $objNext = $this->objStmt->prepare($this->strJumpToFallbackQuery)->execute( - $intFallbackSearchID - ); - break; - } - - $intFallbackSearchID = $intJumpToID; - $intJumpToID = $objNext->jumpTo; - } while ($objNext->type == 'forward'); - } else { - $objNext = $this->objStmt->prepare($this->strJumpToFallbackQuery)->execute($arrPage['id']); - } - - if (! $objNext->numRows) { - $arrPage['href'] = $this->generatePageUrl($arrPage); - } elseif ($objNext->type == 'redirect') { - $arrPage['href'] = $this->encodeEmailURL($objNext->url); - $arrPage['target'] = $objNext->target ? LINK_NEW_WINDOW : ''; - } else { - $arrPage['tid'] = $objNext->id; - $arrPage['href'] = $this->generatePageUrl($objNext->row()); - } - } else { - $arrPage['tid'] = $arrPage['jumpTo']; - $arrPage['href'] = $this->generatePageUrl($arrPage); - } - break; - - case 'redirect': - $arrPage['href'] = $this->encodeEmailURL($arrPage['url']); - $arrPage['target'] = $arrPage['_target'] ? LINK_NEW_WINDOW : ''; - break; - - case 'root': - if (! $arrPage['dns'] - || preg_replace('/^www\./', '', $arrPage['dns']) == preg_replace( - '/^www\./', - '', - $this->Environment->httpHost - )) { - $arrPage['href'] = $this->Environment->base; - break; // we only break on root pages; pages in different roots should be handled by DomainLink extension - } - // do not break - - default: - case 'regular': - case 'error_401': - case 'error_403': - case 'error_404': - $arrPage['href'] = $this->generatePageUrl($arrPage); - break; - } - - if ($intItemHook != self::HOOK_DISABLE) { - $this->executeItemHook($arrPage, $intItemHook == self::HOOK_FORCE); - } - - return $arrPage; - } - - /** - * Utility method of compileNavigationItem. - * - * If the given URL starts with "mailto:", the E-Mail is encoded, - * otherwise nothing is done. - * - * @param string $strHref The URL to check and possibly encode - * - * @return string The modified URL - */ - public function encodeEmailURL($strHref) - { - if (strncasecmp($strHref, 'mailto:', 7) !== 0) { - return $strHref; - } - - return StringUtil::encodeEmail($strHref); - } - public function isPermissionCheckRequired() { return ! BE_USER_LOGGED_IN && ! $this->hofff_navigation_showProtected; @@ -611,37 +345,6 @@ public function isPermissionDenied($arrPage) return ! array_intersect($this->arrGroups, deserialize($arrPage['groups'], true)); } - /** - * Utility method. - * - * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! - * - * Checks if the current user has permission to view the page of the given - * page dataset, in regards to the current navigation settings and the - * permission requirements of the page. - * - * Context property: hofff_navigation_showProtected - * - * @param array $arrPage The page dataset of the current page, with at least - * groups and protected attributes set. - * - * @return boolean If the permission is granted true, otherwise false. - */ - public function isPermissionGranted($arrPage) - { - if (BE_USER_LOGGED_IN) // be users have access everywhere - { - return true; - } - - if ($this->hofff_navigation_showProtected) // protection is ignored - { - return true; - } - - return ! $this->isPermissionDenied($arrPage); - } - /** * Returns the part of the where condition, checking for hidden state of a page. * @@ -724,61 +427,4 @@ protected function generateBE($strBEType = 'NAVIGATION') return $objTemplate->parse(); } - - public function addForwardItem($varID, $varTargetID) - { - if (is_array($this->arrItems[$varID])) { - $this->arrItems[$varID]['href'] = $this->arrItems[$varTargetID]['href']; - } else { - $this->arrItems[$varID] = $this->arrItems[$varTargetID]; - $this->arrItems[$varID]['id'] = $varID; - unset($this->arrItems[$varID]['pid']); - } - $this->arrItems[$varID]['tid'] = $varTargetID; - } - - /** - * Executes the tree hook, to dynamically add navigations items to the tree - * the navigation is rendered from. - * - * The callback receives the following parameters: - * $this - This navigation module instance - * - * @param array $arrRootIDs The root pages before hook execution - * - * @return array $arrRootIDs The root pages after hook execution - */ - protected function executeTreeHook($blnForce = false) - { - if (! $blnForce && ! $this->blnTreeHook) { - return; - } - - foreach ((array) $GLOBALS['TL_HOOKS']['hofff_navigation_tree'] as $arrCallback) { - $this->import($arrCallback[0]); - $this->{$arrCallback[0]}->{$arrCallback[1]}($this); - } - } - - protected function executeItemHook(array &$arrPage, $blnForce = false) - { - if (! $blnForce && ! $this->blnItemHook) { - return; - } - - foreach ((array) $GLOBALS['TL_HOOKS']['hofff_navigation_item'] as $arrCallback) { - $this->import($arrCallback[0]); - $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrPage); - } - } - - private function generatePageUrl(array $arrPage) - { - $pageModel = \Contao\PageModel::findByPk($arrPage['id']); - if ($pageModel) { - return $pageModel->getFrontendUrl(); - } - - return null; - } } diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 5efb54a..7583e6c 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -2,66 +2,61 @@ namespace Hofff\Contao\Navigation\FrontendModule; -class ModuleNavigationMenu extends AbstractModuleNavigation -{ +use Contao\StringUtil; +use Contao\System; +use Hofff\Contao\Navigation\Items\PageItemsLoader; +use Hofff\Contao\Navigation\Renderer\NavigationRenderer; + +use function assert; +final class ModuleNavigationMenu extends AbstractModuleNavigation +{ protected $strTemplate = 'mod_hofff_navigation_menu'; protected $strNavigation; - public $strFirstLevelTemplate; - public function generate() { - if (TL_MODE == 'BE') { + if (TL_MODE === 'BE') { return $this->generateBE('NAVIGATION MENU'); } - $arrStop = $this->getStop(); - $intHard = $this->getHard(); + $stopLevels = $this->getStopLevels(); + $hardLevel = $this->getHardLevel(); + $arrRootIDs = $this->calculateRootIDs($stopLevels); - $arrRootIDs = $this->calculateRootIDs($arrStop); - $this->compileNavigationTree($arrRootIDs, $arrStop, $intHard); - $this->executeTreeHook(); - $arrRootIDs = $this->executeMenuHook($arrRootIDs); - $arrFirstIDs = $this->getFirstNavigationLevel($arrRootIDs); + $loader = System::getContainer()->get(PageItemsLoader::class); + assert($loader instanceof PageItemsLoader); - if ($this->hofff_navigation_hideSingleLevel) { - foreach ($arrFirstIDs as $id) { - if ($this->arrSubitems[$id]) { - $hasMultipleLevels = true; - break; - } - } - if (! $hasMultipleLevels) { - return ''; - } - } + $renderer = System::getContainer()->get(NavigationRenderer::class); + assert($renderer instanceof NavigationRenderer); - $arrStop[0] == 0 && array_shift($arrStop); // special case renderNavigationTree cannot handle - $this->strNavigation = trim( - $this->renderNavigationTree($arrFirstIDs, $this->strFirstLevelTemplate, $arrStop, $intHard) - ); + $items = $loader->load($this->objModel, $arrRootIDs, $this->arrFields, $stopLevels, $hardLevel); + + $this->strNavigation = $renderer->render($this->objModel, $items, $arrRootIDs, $stopLevels, $hardLevel); return $this->strNavigation ? parent::generate() : ''; } - public function getStop() + public function getStopLevels(): array { if (! $this->hofff_navigation_defineStop) { return [PHP_INT_MAX]; } - $intMin = -1; - foreach (array_map('intval', explode(',', $this->hofff_navigation_stop)) as $intLevel) { - if ($intLevel > $intMin) { - $arrStop[] = $intMin = $intLevel; + + $minLevel = -1; + $stopLevel = []; + + foreach (array_map('intval', explode(',', $this->hofff_navigation_stop)) as $level) { + if ($level > $minLevel) { + $stopLevel[] = $minLevel = $level; } } - return $arrStop ? $arrStop : [PHP_INT_MAX]; + return $stopLevel ?: [PHP_INT_MAX]; } - public function getHard() + public function getHardLevel() { return $this->hofff_navigation_defineHard ? $this->hofff_navigation_hard : PHP_INT_MAX; } @@ -124,7 +119,7 @@ protected function calculateRootIDs($arrStop = PHP_INT_MAX) $arrStop = (array) $arrStop; if ($arrStop[0] == 0) { // special case, keep only roots within the current path - $arrPath = array_keys($this->arrTrail); + $arrPath = $GLOBALS['objPage']->trail; $arrPath[] = $this->varActiveID; $arrRootIDs = array_intersect($arrRootIDs, $arrPath); } @@ -132,199 +127,18 @@ protected function calculateRootIDs($arrStop = PHP_INT_MAX) return $arrRootIDs; } - public function compileNavigationTree(array $arrRootIDs, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX) - { - if (! $arrRootIDs) { - return; - } - - $arrRootIDs = array_keys(array_flip($arrRootIDs)); - $arrStop = (array) $arrStop; - - foreach ($arrRootIDs as $intRootID) { - $this->arrItems[$intRootID] = (array) $this->arrItems[$intRootID]; - } - - if ($this->hofff_navigation_includeStart) { - $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard, 2); - - $objRoots = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart($this->arrFields) . ' - FROM tl_page - WHERE id IN (' . implode(',', $arrRootIDs) . ')' - ); - - while ($objRoots->next()) { - $this->arrItems[$objRoots->id] = $objRoots->row(); - $arrFetched[$objRoots->id] = true; - } - } else { - $arrFetched = $this->fetchItems($arrRootIDs, $arrStop, $intHard); - } - - $blnForwardResolution = ! $this->hofff_navigation_noForwardResolution; - foreach ($arrFetched as $intID => $_) { - $this->arrItems[$intID] = $this->compileNavigationItem( - $this->arrItems[$intID], - $blnForwardResolution, - self::HOOK_ENABLE - ); - } - } - - /** - * Fetches page data for all navigation items below the given roots. - * - * @param integer $arrPIDs The root pages of the navigation. - * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $intLevel (optional, defaults to 1) The level of the PIDs. - * - * @return null - */ - protected function fetchItems(array $arrPIDs, $arrStop = PHP_INT_MAX, $intHard = PHP_INT_MAX, $intLevel = 1) - { - $intLevel = max(1, $intLevel); - $arrStop = (array) $arrStop; - - // nothing todo - // $intLevel == $intHard + 1 requires subitem detection for css class "submenu" calculation - if (! $arrPIDs || $intLevel - 1 > $intHard) { - return; - } - - $arrConditions = [ - $this->getQueryPartHidden($this->hofff_navigation_showHidden, $this->hofff_navigation_isSitemap), - $this->getQueryPartPublish(), - $this->getQueryPartErrorPages($this->hofff_navigation_showErrorPages), - ]; - ! $this->hofff_navigation_showGuests && $arrConditions[] = $this->getQueryPartGuests(); - $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - - $strLevelQueryStart = - 'SELECT ' . $this->getQuotedFieldsPart($this->arrFields) . ' - FROM tl_page - WHERE pid IN ('; - $strLevelQueryEnd = ') - AND type != \'root\' - ' . $strConditions . ' - ORDER BY sorting'; - - $arrFetched = []; - - while ($arrPIDs) { - // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop - if ($intLevel > $intHard) { - $arrEndPIDs = $arrPIDs; - } elseif ($intLevel > $arrStop[0]) { - count($arrStop) > 1 && array_shift($arrStop); - $arrEndPIDs = []; - foreach ($arrPIDs as $intPID) { - if (! isset($this->arrTrail[$intPID])) { - $arrEndPIDs[$intPID] = true; - } - } - } else { - $arrEndPIDs = []; - } - - $objSubpages = $this->objStmt->query($strLevelQueryStart . implode(',', $arrPIDs) . $strLevelQueryEnd); - - if (! $objSubpages->numRows) { - break; - } - - $arrPIDs = []; - while ($arrPage = $objSubpages->fetchAssoc()) { - if (isset($this->arrItems[$arrPage['id']])) { - continue; - } - - if (! $this->isPermissionGranted($arrPage)) { - continue; - } - - if (! isset($arrEndPIDs[$arrPage['pid']])) { - $this->arrSubitems[$arrPage['pid']][] = $arrPage['id']; // for order of items - $this->arrItems[$arrPage['id']] = $arrPage; // item datasets - $arrPIDs[] = $arrPage['id']; // ids of current layer (for next layer pids) - $arrFetched[$arrPage['id']] = true; // fetched in this method - - } elseif (! isset($this->arrSubitems[$arrPage['pid']])) { - $this->arrSubitems[$arrPage['pid']] = []; - } - } - - $intLevel++; - } - - return $arrFetched; - } - - /** - * Executes the navigation hook. - * The callback receives the following parameters: - * $this - This navigation module instance - * $arrRootIDs - The IDs of the first navigation level - * - * And should return a new root array or null - * - * @param array $arrRootIDs The root pages before hook execution - * - * @return array $arrRootIDs The root pages after hook execution - */ - protected function executeMenuHook(array $arrRootIDs, $blnForce = false) - { - if (! $blnForce && $this->hofff_navigation_disableHooks) { - return $arrRootIDs; - } - if (! is_array($GLOBALS['TL_HOOKS']['hofff_navigation_menu'])) { - return $arrRootIDs; - } - - foreach ($GLOBALS['TL_HOOKS']['hofff_navigation_menu'] as $arrCallback) { - $this->import($arrCallback[0]); - $arrNewRoots = $this->{$arrCallback[0]}->{$arrCallback[1]}($this, $arrRootIDs); - - if ($arrNewRoots !== null) { - $arrRootIDs = $arrNewRoots; - } - } - - return $arrRootIDs; - } - - protected function getFirstNavigationLevel(array $arrRootIDs) - { - if ($this->hofff_navigation_includeStart) { - return $arrRootIDs; - } - - // if we do not want to show the root level - $arrFirstIDs = []; - foreach ($arrRootIDs as $varRootID) { - if (isset($this->arrSubitems[$varRootID])) { - $arrFirstIDs = array_merge($arrFirstIDs, $this->arrSubitems[$varRootID]); - } - } - - return $arrFirstIDs; - } - - protected function getRootIds() + protected function getRootIds(): array { return array_map( 'intval', array_values( array_unique( array_merge( - \Contao\StringUtil::deserialize($this->hofff_navigation_roots_order, true), - \Contao\StringUtil::deserialize($this->hofff_navigation_roots, true) + StringUtil::deserialize($this->hofff_navigation_roots_order, true), + StringUtil::deserialize($this->hofff_navigation_roots, true) ) ) ) ); } - } diff --git a/src/Items/PageItems.php b/src/Items/PageItems.php new file mode 100644 index 0000000..30060c3 --- /dev/null +++ b/src/Items/PageItems.php @@ -0,0 +1,27 @@ + */ + public array $roots = []; + + /** @var array */ + public array $items = []; + + /** @var array> */ + public array $subItems = []; + + /** @var array */ + public array $trail = []; + + public function isInTrail(int $pageId): bool + { + return array_key_exists($pageId, $this->trail); + } +} diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php new file mode 100644 index 0000000..f036ac7 --- /dev/null +++ b/src/Items/PageItemsLoader.php @@ -0,0 +1,256 @@ +connection = $connection; + $this->security = $security; + $this->pageQueryBuilder = $pageQueryBuilder; + } + + public function load( + ModuleModel $moduleModel, + array $rootIds, + array $fields, + $arrStop = PHP_INT_MAX, + $intHard = PHP_INT_MAX + ): PageItems { + $items = new PageItems(); + $items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); + if (! $rootIds) { + return $items; + } + + $rootIds = array_keys(array_flip($rootIds)); + $arrStop = (array) $arrStop; + + foreach ($rootIds as $rootId) { + $items->items[$rootId] = $items->items[$rootId] ?? []; + } + + if (! $moduleModel->hofff_navigation_includeStart) { + $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $arrStop, $intHard); + + return $items; + } + + $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $arrStop, $intHard, 2); + + $result = $this->connection->executeQuery( + sprintf( + 'SELECT %s FROM tl_page WHERE id IN (:rootIds)', + $this->getQuotedFieldsPart($fields) + ), + ['rootIds' => $rootIds], + ['rootIds' => Connection::PARAM_STR_ARRAY] + ); + + while ($row = $result->fetchAssociative()) { + $items->items[$row['id']] = $row; + $items->roots[$row['id']] = true; + } + + return $items; + } + + /** + * Fetches page data for all navigation items below the given roots. + * + * @param integer $arrPIDs The root pages of the navigation. + * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param integer $intLevel (optional, defaults to 1) The level of the PIDs. + * + * @return array + */ + protected function fetchItems( + ModuleModel $moduleModel, + PageItems $items, + array $fields, + array $arrPIDs, + $arrStop = PHP_INT_MAX, + $intHard = PHP_INT_MAX, + $intLevel = 1 + ): array { + $intLevel = max(1, $intLevel); + $arrStop = (array) $arrStop; + + // nothing todo + // $intLevel == $intHard + 1 requires subitem detection for css class "submenu" calculation + if (! $arrPIDs || $intLevel - 1 > $intHard) { + return []; + } + + $queryBuilder = $this->connection->createQueryBuilder() + ->from('tl_page') + ->select(... $fields) + ->andWhere('type != :rootType') + ->setParameter('rootType', 'root') + ->andWhere('pid IN (:pids)') + ->orderBy('sorting'); + + $this->pageQueryBuilder + ->addHiddenCondition( + $queryBuilder, + (bool) $moduleModel->hofff_navigation_showHidden, + (bool) $moduleModel->hofff_navigation_isSitemap + ) + ->addPublishedCondition($queryBuilder) + ->addErrorPagesCondition($queryBuilder, (bool) $moduleModel->hofff_navigation_showErrorPages) + ->addGuestsQueryParts($queryBuilder, (bool) $moduleModel->backboneit_navigation_showGuests); + + $arrFetched = []; + + while ($arrPIDs) { + // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop + if ($intLevel > $intHard) { + $arrEndPIDs = $arrPIDs; + } elseif ($intLevel > $arrStop[0]) { + count($arrStop) > 1 && array_shift($arrStop); + $arrEndPIDs = []; + foreach ($arrPIDs as $intPID) { + if ($items->isInTrail((int) $intPID)) { + $arrEndPIDs[$intPID] = true; + } + } + } else { + $arrEndPIDs = []; + } + + $query = clone $queryBuilder; + $query->setParameter('pids', $arrPIDs, Connection::PARAM_INT_ARRAY); + + $result = $query->execute(); + if ($result->rowCount() === 0) { + break; + } + + $arrPIDs = []; + while ($arrPage = $result->fetchAssociative()) { + if (isset($items->items[$arrPage['id']])) { + continue; + } + + if (! $this->isPermissionGranted($moduleModel, $arrPage)) { + continue; + } + + if (! isset($arrEndPIDs[$arrPage['pid']])) { + $items->subItems[(int) $arrPage['pid']][] = (int) $arrPage['id']; // for order of items + $items->items[(int) $arrPage['id']] = $arrPage; // item datasets + $arrPIDs[] = $arrPage['id']; // ids of current layer (for next layer pids) + $arrFetched[$arrPage['id']] = true; // fetched in this method + + } elseif (! isset($items->subItems[$arrPage['pid']])) { + $items->subItems[$arrPage['pid']] = []; + } + } + + $intLevel++; + } + + return $arrFetched; + } + + + protected function getQuotedFieldsPart(array $fields): string + { + return implode(', ', array_map([$this->connection, 'quoteIdentifier'], $fields)); + } + + /** + * Utility method. + * + * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! + * + * Checks if the current user has permission to view the page of the given + * page dataset, in regards to the current navigation settings and the + * permission requirements of the page. + * + * Context property: hofff_navigation_showProtected + * + * @param array $arrPage The page dataset of the current page, with at least + * groups and protected attributes set. + * + * @return boolean If the permission is granted true, otherwise false. + */ + public function isPermissionGranted(ModuleModel $model, array $arrPage): bool + { + // TODO: Replace with non deprecated check + // be users have access everywhere + if (BE_USER_LOGGED_IN) { + return true; + } + + // protection is ignored + if ($model->hofff_navigation_showProtected) { + return true; + } + + return ! $this->isPermissionDenied($arrPage); + } + + /** + * Utility method. + * + * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! + * + * Checks if the current user has no permission to view the page of the + * given page dataset, in regards to the permission requirements of the + * page. + * + * @param array $arrPage The page dataset of the current page, with at least + * groups and protected attributes set. + * + * @return boolean If the permission is denied true, otherwise false. + */ + public function isPermissionDenied(array $arrPage): bool + { + // this page is not protected + if (! $arrPage['protected']) { + return false; + } + + $user = $this->security->getUser(); + if (! $user instanceof FrontendUser) { + return true; + } + + // the current user is not in any group + if (! $user->groups) { + return true; + } + + // check if the current user is not in any group, which is allowed to access the current page + return ! array_intersect((array) $user->groups, StringUtil::deserialize($arrPage['groups'], true)); + } +} diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 10d2448..1ceefef 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -73,7 +73,7 @@ public function run(): MigrationResult private function hasBackboneItNavigationModules(): bool { $result = $this->connection->executeQuery( - 'SELECT count(id) FROM tl_navigation WHERE type=:type', + 'SELECT count(id) FROM tl_module WHERE type=:type', ['type' => 'backboneit_navigation_menu'] ); diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php new file mode 100644 index 0000000..c13563e --- /dev/null +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -0,0 +1,87 @@ +andWhere('(start = \'\' OR start < :time) AND (stop = \'\' OR stop > :time) AND published = 1') + ->setParameter('time', $time); + + return $this; + } + + /** + * Adds the or hidden state of a page. + * + * @return self + */ + public function addHiddenCondition( + QueryBuilder $queryBuilder, + bool $showHidden = false, + bool $sitemap = false + ): self { + if ($showHidden) { + return $this; + } + + if ($sitemap) { + $queryBuilder->andWhere('(sitemap = \'map_always\' OR (hide != 1 AND sitemap != \'map_never\'))'); + + return $this; + } + + $queryBuilder->andWhere('hide != 1'); + + return $this; + } + + public function addErrorPagesCondition(QueryBuilder $queryBuilder, bool $showErrorPages): self + { + if (! $showErrorPages) { + $queryBuilder + ->andWhere('type NOT IN (:errorPages)') + ->setParameter('errorPages', self::ERROR_PAGE_TYPES, Connection::PARAM_STR_ARRAY); + } + + return $this; + } + + public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests): self + { + if ($showGuests) { + return $this; + } + + if (FE_USER_LOGGED_IN && ! BE_USER_LOGGED_IN) { + $queryBuilder->andWhere('guests != 1'); + } + + return $this; + } +} diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php new file mode 100644 index 0000000..7a85689 --- /dev/null +++ b/src/Renderer/NavigationRenderer.php @@ -0,0 +1,468 @@ +connection = $connection; + $this->pageQueryBuilder = $pageQueryBuilder; + } + + /** + * Renders the navigation of the given IDs into the navigation template. + * Adds CSS classes "first" and "last" to the appropriate navigation item arrays. + * If the given array is empty, the empty string is returned. + * + * @param array $arrIDs The navigation items arrays + * @param array $stopLimit (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param integer $currentLevel (optional, defaults to 1) The current level of this navigation layer + * + * @return string The parsed navigation template, could be empty string. + */ + public function render( + ModuleModel $moduleModel, + PageItems $items, + array $itemIds, + array $stopLimit = [PHP_INT_MAX], + int $intHard = PHP_INT_MAX, + int $currentLevel = 1 + ): string { + if ($stopLimit === []) { + $stopLimit = [PHP_INT_MAX]; + } + + $this->compileTree($moduleModel, $items); + $this->executeTreeHook($moduleModel, $items); + + $arrRootIDs = $this->executeMenuHook($moduleModel, $itemIds); + $arrFirstIDs = $this->getFirstNavigationLevel($moduleModel, $items, $arrRootIDs); + + if ($moduleModel->hofff_navigation_hideSingleLevel) { + foreach ($arrFirstIDs as $id) { + if ($items->subItems[$id]) { + $hasMultipleLevels = true; + break; + } + } + + if (! $hasMultipleLevels) { + return ''; + } + } + + $stopLimit[0] == 0 && array_shift($stopLimit); // special case renderNavigationTree cannot handle + + return trim($this->renderTree($moduleModel, $items, $arrFirstIDs, $stopLimit, $intHard, $currentLevel)); + } + + private function renderTree( + ModuleModel $moduleModel, + PageItems $items, + array $itemIds, + array $stopLimit = [PHP_INT_MAX], + int $intHard = PHP_INT_MAX, + int $currentLevel = 1 + ): string { + if (! $itemIds) { + return ''; + } + + $intStop = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; + $arrItems = []; + + foreach ($itemIds as $varID) { + if (! isset($items->items[$varID])) { + continue; + } + + $arrItem = $items->items[$varID]; + + if ($varID == $this->activeId) { + $blnContainsActive = true; + + if ($arrItem['href'] === Environment::get('request')) { + $arrItem['isActive'] = true; // nothing else (active class is set in template) + $arrItem['isInTrail'] = false; + } else { + $arrItem['isActive'] = false; // nothing else (active class is set in template) + $arrItem['isInTrail'] = true; + } + } else { // do not flatten if/else + if ($arrItem['tid'] == $this->activeId) { + if ($arrItem['href'] === Environment::get('request')) { + $arrItem['isActive'] = true; // nothing else (active class is set in template) + $arrItem['isInTrail'] = false; + } else { + $arrItem['isActive'] = false; // nothing else (active class is set in template) + $arrItem['isInTrail'] = true; + } + } + } + + if ($arrItem['isInTrail']) { + $arrItem['class'] .= ' trail'; + } + + if (! isset($items->subItems[$varID])) { + $arrItem['class'] .= ' leaf'; + } elseif ($currentLevel >= $intHard) { + // we are at hard level, never draw submenu + $arrItem['class'] .= ' submenu leaf'; + } elseif ($currentLevel >= $intStop && ! $arrItem['isInTrail'] && $varID !== $this->activeId && $arrItem['tid'] != $this->activeId) { + // we are at stop level and not trail and not active, never draw submenu + $arrItem['class'] .= ' submenu leaf'; + } elseif ($items->subItems[$varID]) { + $arrItem['class'] .= ' submenu inner'; + $arrItem['subitems'] = $this->renderTree( + $moduleModel, + $items, + $items->subItems[$varID] ?? [], + $stopLimit, + $intHard, + $currentLevel + 1 + ); + } else { // should never be reached, if no hooks are used + $arrItem['class'] .= ' leaf'; + } + + $arrItems[] = $arrItem; + } + + if ($blnContainsActive) { + foreach ($arrItems as &$arrItem) { + if (! $arrItem['isActive']) { + $arrItem['class'] .= ' sibling'; + } + } + unset($arrItem); + } + + $arrItems[0]['class'] .= ' first'; + $arrItems[count($arrItems) - 1]['class'] .= ' last'; + + foreach ($arrItems as &$arrItem) { + $arrItem['class'] = ltrim($arrItem['class']); + } + unset($arrItem); + + $objTemplate = new FrontendTemplate($moduleModel->navigationTpl ?: 'nav_hofff'); + $objTemplate->setData([ + 'module' => $moduleModel->row(), + 'level' => 'level_' . $currentLevel, + 'items' => $arrItems, + 'type' => get_class($this), + ]); + + return $objTemplate->parse(); + } + + public function compileTree(ModuleModel $moduleModel, PageItems $items): void + { + $blnForwardResolution = ! $moduleModel->hofff_navigation_noForwardResolution; + foreach ($items->roots as $intID => $_) { + if (!isset($items->items[$intID])) { + continue; + } + + $items->items[$intID] = $this->compileNavigationItem( + $moduleModel, + $items, + $items->items[$intID], + $blnForwardResolution, + AbstractModuleNavigation::HOOK_ENABLE + ); + } + } + + /** + * Compiles a navigation item array from a page dataset with the given subnavi + * + * @param array $arrPage The page dataset as an array + * + * @return array The compiled navigation item array + */ + public function compileNavigationItem( + ModuleModel $moduleModel, + PageItems $items, + array $arrPage, + $blnForwardResolution = true, + $intItemHook = AbstractModuleNavigation::HOOK_DISABLE + ) { + // fallback for dataset field collisions + $arrPage['_title'] = $arrPage['title']; + $arrPage['_pageTitle'] = $arrPage['pageTitle']; + $arrPage['_target'] = $arrPage['target']; + $arrPage['_description'] = $arrPage['description']; + + $arrPage['link'] = $arrPage['_title']; + $arrPage['class'] = $arrPage['cssClass'] . ' ' . $arrPage['type']; + $arrPage['title'] = StringUtil::specialchars($arrPage['_title'], true); + $arrPage['pageTitle'] = StringUtil::specialchars($arrPage['_pageTitle'], true); + $arrPage['target'] = ''; // overwrite DB value + $arrPage['nofollow'] = strncmp($arrPage['robots'], 'noindex', 7) === 0; + $arrPage['description'] = str_replace(["\n", "\r"], [' ', ''], $arrPage['_description']); + $arrPage['isInTrail'] = $items->isInTrail((int) $arrPage['id']); + + switch ($arrPage['type']) { + case 'forward': + if ($blnForwardResolution) { + $redirectPage = $this->getRedirectPage($arrPage); + if (! $redirectPage) { + $arrPage['href'] = $this->generatePageUrl($arrPage); + } elseif ($redirectPage['type'] === 'redirect') { + $arrPage['href'] = $this->encodeEmailURL($redirectPage['url']); + $arrPage['target'] = $redirectPage['target'] ? LINK_NEW_WINDOW : ''; + } else { + $arrPage['tid'] = $redirectPage['id']; + $arrPage['href'] = $this->generatePageUrl($redirectPage); + } + } else { + $arrPage['tid'] = $arrPage['jumpTo']; + $arrPage['href'] = $this->generatePageUrl($arrPage); + } + break; + + case 'redirect': + $arrPage['href'] = $this->encodeEmailURL($arrPage['url']); + $arrPage['target'] = $arrPage['_target'] ? LINK_NEW_WINDOW : ''; + break; + + case 'root': + if (! $arrPage['dns'] + || preg_replace('/^www\./', '', $arrPage['dns']) == preg_replace( + '/^www\./', + '', + Environment::get('httpHost') + )) { + $arrPage['href'] = Environment::get('base'); + break; // we only break on root pages; pages in different roots should be handled by DomainLink extension + } + // do not break + + default: + case 'regular': + case 'error_401': + case 'error_403': + case 'error_404': + $arrPage['href'] = $this->generatePageUrl($arrPage); + break; + } + + if ($intItemHook != AbstractModuleNavigation::HOOK_DISABLE) { + $this->executeItemHook($moduleModel, $arrPage, $intItemHook == AbstractModuleNavigation::HOOK_FORCE); + } + + return $arrPage; + } + + private function generatePageUrl(array $arrPage): ?string + { + $pageModel = PageModel::findByPk($arrPage['id']); + if ($pageModel) { + return $pageModel->getFrontendUrl(); + } + + return null; + } + + /** + * Utility method of compileNavigationItem. + * + * If the given URL starts with "mailto:", the E-Mail is encoded, + * otherwise nothing is done. + * + * @param string $strHref The URL to check and possibly encode + * + * @return string The modified URL + */ + public function encodeEmailURL(string $strHref): string + { + if (strncasecmp($strHref, 'mailto:', 7) !== 0) { + return $strHref; + } + + return StringUtil::encodeEmail($strHref); + } + + protected function executeItemHook(ModuleModel $moduleModel, array &$arrPage, $blnForce = false): void + { + if (! $blnForce && ! $moduleModel->hofff_navigation_disableHooks) { + return; + } + + foreach ((array) ($GLOBALS['TL_HOOKS']['hofff_navigation_item'] ?? []) as $arrCallback) { + $arrCallback[0] = System::importStatic($arrCallback[0]); + $arrCallback[0]->{$arrCallback[1]}($moduleModel, $arrPage); + } + } + + /** + * Executes the tree hook, to dynamically add navigations items to the tree + * the navigation is rendered from. + * + * The callback receives the following parameters: + * $this - This navigation module instance + * + * @param array $arrRootIDs The root pages before hook execution + * + * @return void + */ + protected function executeTreeHook(ModuleModel $moduleModel, PageItems $items, $blnForce = false): void + { + if (! $blnForce && ! $moduleModel->hofff_navigation_disableHooks) { + return; + } + + foreach ((array) $GLOBALS['TL_HOOKS']['hofff_navigation_tree'] as $arrCallback) { + $arrCallback[0] = System::importStatic($arrCallback[0]); + $arrCallback[0]->{$arrCallback[1]}($moduleModel, $items); + } + } + + /** + * Executes the navigation hook. + * The callback receives the following parameters: + * $this - This navigation module instance + * $arrRootIDs - The IDs of the first navigation level + * + * And should return a new root array or null + * + * @param array $arrRootIDs The root pages before hook execution + * + * @return array $arrRootIDs The root pages after hook execution + */ + protected function executeMenuHook(ModuleModel $moduleModel, array $arrRootIDs, $blnForce = false) + { + if (! $blnForce && $moduleModel->hofff_navigation_disableHooks) { + return $arrRootIDs; + } + + if (! is_array($GLOBALS['TL_HOOKS']['hofff_navigation_menu'])) { + return $arrRootIDs; + } + + foreach ($GLOBALS['TL_HOOKS']['hofff_navigation_menu'] as $arrCallback) { + $arrCallback[0] = System::importStatic($arrCallback[0]); + $arrNewRoots = $this->{$arrCallback[0]}->{$arrCallback[1]}($moduleModel, $arrRootIDs); + + if ($arrNewRoots !== null) { + $arrRootIDs = $arrNewRoots; + } + } + + return $arrRootIDs; + } + + protected function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $arrRootIDs): array + { + if ($moduleModel->hofff_navigation_includeStart) { + return $arrRootIDs; + } + + // if we do not want to show the root level + $arrFirstIDs = []; + foreach ($arrRootIDs as $varRootID) { + if (isset($items->subItems[$varRootID])) { + $arrFirstIDs = array_merge($arrFirstIDs, $items->subItems[$varRootID]); + } + } + + return $arrFirstIDs; + } + + private function getRedirectPage(array $arrPage): array + { + static $jumpToQuery = null; + static $jumpToFallbackQuery = null; + + if ($jumpToQuery === null) { + $jumpToQuery = $this->connection->createQueryBuilder() + ->select('*') + ->from('tl_page') + ->where('id=:id') + ->setMaxResults(1); + + $this->pageQueryBuilder + ->addGuestsQueryParts($jumpToQuery) + ->addPublishedCondition($jumpToQuery); + } + + if ($jumpToFallbackQuery === null) { + $jumpToFallbackQuery = $this->connection->createQueryBuilder() + ->select('*') + ->from('tl_page') + ->where('type=:type') + ->andWhere('pid=:pid') + ->setParameter('type', 'regular') + ->orderBy('sorting') + ->setMaxResults(1); + + $this->pageQueryBuilder + ->addGuestsQueryParts($jumpToFallbackQuery); + } + + if ($arrPage['jumpTo']) { + $intFallbackSearchID = $arrPage['id']; + $intJumpToID = $arrPage['jumpTo']; + do { + $query = clone $jumpToQuery; + $query->setParameter('id', $intJumpToID); + $result = $query->execute(); + $next = $result->fetchAssociative(); + + if (! $result->rowCount()) { + $query = clone $jumpToFallbackQuery; + $query->setParameter('pid', $intFallbackSearchID); + $next = $query->execute()->fetchAssociative(); + break; + } + + $intFallbackSearchID = $intJumpToID; + $intJumpToID = $next['jumpTo'] ?? 0; + } while ($next['type'] === 'forward'); + } else { + $query = clone $jumpToFallbackQuery; + $query->setParameter('pid', $arrPage['id']); + $next = $query->execute()->fetchAssociative(); + } + + return $next; + } +} diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index c673be8..89ce909 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -15,5 +15,18 @@ + + + + + + + + + + + + + From bf7e6ac62198f7ad5922894871618ec4c1277a29 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:18 +0200 Subject: [PATCH 16/75] Fix active id handling --- src/FrontendModule/AbstractModuleNavigation.php | 4 ++-- src/FrontendModule/ModuleNavigationMenu.php | 2 +- src/Renderer/NavigationRenderer.php | 17 ++++++++--------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index aabff5b..052ebb1 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -88,8 +88,8 @@ public function __construct($objModule, $strColumn = 'main') $this->import('Database'); $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get('articles') - ? false - : $GLOBALS['objPage']->id; + ? null + : (int) $GLOBALS['objPage']->id; if (FE_USER_LOGGED_IN) { $this->import('FrontendUser', 'User'); diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 7583e6c..b80ba05 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -33,7 +33,7 @@ public function generate() $items = $loader->load($this->objModel, $arrRootIDs, $this->arrFields, $stopLevels, $hardLevel); - $this->strNavigation = $renderer->render($this->objModel, $items, $arrRootIDs, $stopLevels, $hardLevel); + $this->strNavigation = $renderer->render($this->objModel, $items, $arrRootIDs, $stopLevels, $hardLevel, $this->varActiveID); return $this->strNavigation ? parent::generate() : ''; } diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 7a85689..252d19d 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -35,9 +35,6 @@ final class NavigationRenderer private PageQueryBuilder $pageQueryBuilder; - private ?int $activeId = null; - - public function __construct(Connection $connection, PageQueryBuilder $pageQueryBuilder) { $this->connection = $connection; @@ -62,7 +59,8 @@ public function render( array $itemIds, array $stopLimit = [PHP_INT_MAX], int $intHard = PHP_INT_MAX, - int $currentLevel = 1 + int $currentLevel = 1, + ?int $activeId = null ): string { if ($stopLimit === []) { $stopLimit = [PHP_INT_MAX]; @@ -89,7 +87,7 @@ public function render( $stopLimit[0] == 0 && array_shift($stopLimit); // special case renderNavigationTree cannot handle - return trim($this->renderTree($moduleModel, $items, $arrFirstIDs, $stopLimit, $intHard, $currentLevel)); + return trim($this->renderTree($moduleModel, $items, $arrFirstIDs, $stopLimit, $intHard, $currentLevel, $activeId)); } private function renderTree( @@ -98,7 +96,8 @@ private function renderTree( array $itemIds, array $stopLimit = [PHP_INT_MAX], int $intHard = PHP_INT_MAX, - int $currentLevel = 1 + int $currentLevel = 1, + ?int $activeId = null ): string { if (! $itemIds) { return ''; @@ -114,7 +113,7 @@ private function renderTree( $arrItem = $items->items[$varID]; - if ($varID == $this->activeId) { + if ($varID == $activeId) { $blnContainsActive = true; if ($arrItem['href'] === Environment::get('request')) { @@ -125,7 +124,7 @@ private function renderTree( $arrItem['isInTrail'] = true; } } else { // do not flatten if/else - if ($arrItem['tid'] == $this->activeId) { + if ($arrItem['tid'] == $activeId) { if ($arrItem['href'] === Environment::get('request')) { $arrItem['isActive'] = true; // nothing else (active class is set in template) $arrItem['isInTrail'] = false; @@ -145,7 +144,7 @@ private function renderTree( } elseif ($currentLevel >= $intHard) { // we are at hard level, never draw submenu $arrItem['class'] .= ' submenu leaf'; - } elseif ($currentLevel >= $intStop && ! $arrItem['isInTrail'] && $varID !== $this->activeId && $arrItem['tid'] != $this->activeId) { + } elseif ($currentLevel >= $intStop && ! $arrItem['isInTrail'] && $varID !== $activeId && $arrItem['tid'] != $activeId) { // we are at stop level and not trail and not active, never draw submenu $arrItem['class'] .= ' submenu leaf'; } elseif ($items->subItems[$varID]) { From 1bf5123bc629cdff71fa488d7334e05b6bf7d6ab Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:19 +0200 Subject: [PATCH 17/75] Move dependencies to the constructor --- src/FrontendModule/ModuleNavigationMenu.php | 39 +++++++++++++-------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index b80ba05..2e3beab 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -7,15 +7,25 @@ use Hofff\Contao\Navigation\Items\PageItemsLoader; use Hofff\Contao\Navigation\Renderer\NavigationRenderer; -use function assert; - final class ModuleNavigationMenu extends AbstractModuleNavigation { protected $strTemplate = 'mod_hofff_navigation_menu'; - protected $strNavigation; + protected string $strNavigation = ''; + + private PageItemsLoader $loader; + + private NavigationRenderer $renderer; + + public function __construct($objModule, $strColumn = 'main') + { + parent::__construct($objModule, $strColumn); + + $this->loader = System::getContainer()->get(PageItemsLoader::class); + $this->renderer = System::getContainer()->get(NavigationRenderer::class); + } - public function generate() + public function generate(): string { if (TL_MODE === 'BE') { return $this->generateBE('NAVIGATION MENU'); @@ -23,17 +33,18 @@ public function generate() $stopLevels = $this->getStopLevels(); $hardLevel = $this->getHardLevel(); - $arrRootIDs = $this->calculateRootIDs($stopLevels); - - $loader = System::getContainer()->get(PageItemsLoader::class); - assert($loader instanceof PageItemsLoader); + $rootIds = $this->calculateRootIDs($stopLevels); - $renderer = System::getContainer()->get(NavigationRenderer::class); - assert($renderer instanceof NavigationRenderer); + $items = $this->loader->load($this->objModel, $rootIds, $this->arrFields, $stopLevels, $hardLevel); - $items = $loader->load($this->objModel, $arrRootIDs, $this->arrFields, $stopLevels, $hardLevel); - - $this->strNavigation = $renderer->render($this->objModel, $items, $arrRootIDs, $stopLevels, $hardLevel, $this->varActiveID); + $this->strNavigation = $this->renderer->render( + $this->objModel, + $items, + $rootIds, + $stopLevels, + $hardLevel, + $this->varActiveID + ); return $this->strNavigation ? parent::generate() : ''; } @@ -61,7 +72,7 @@ public function getHardLevel() return $this->hofff_navigation_defineHard ? $this->hofff_navigation_hard : PHP_INT_MAX; } - protected function compile() + protected function compile(): void { $this->Template->request = $this->getIndexFreeRequest(true); $this->Template->skipId = 'skipNavigation' . $this->id; From 7db9749e3370b46d199abc66543c7dccdf7b96ea Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:19 +0200 Subject: [PATCH 18/75] Fix stop level detection --- src/Items/PageItemsLoader.php | 61 +++++++++++++++++------------------ 1 file changed, 29 insertions(+), 32 deletions(-) diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index f036ac7..332dad9 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -41,8 +41,8 @@ public function load( ModuleModel $moduleModel, array $rootIds, array $fields, - $arrStop = PHP_INT_MAX, - $intHard = PHP_INT_MAX + array $stopLevels = [PHP_INT_MAX], + int $hardLvel = PHP_INT_MAX ): PageItems { $items = new PageItems(); $items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); @@ -51,19 +51,17 @@ public function load( } $rootIds = array_keys(array_flip($rootIds)); - $arrStop = (array) $arrStop; - foreach ($rootIds as $rootId) { $items->items[$rootId] = $items->items[$rootId] ?? []; } if (! $moduleModel->hofff_navigation_includeStart) { - $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $arrStop, $intHard); + $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $stopLevels, $hardLvel); return $items; } - $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $arrStop, $intHard, 2); + $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $stopLevels, $hardLvel, 2); $result = $this->connection->executeQuery( sprintf( @@ -85,10 +83,10 @@ public function load( /** * Fetches page data for all navigation items below the given roots. * - * @param integer $arrPIDs The root pages of the navigation. - * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $intLevel (optional, defaults to 1) The level of the PIDs. + * @param integer $parentIds The root pages of the navigation. + * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param integer $hardStop (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param integer $level (optional, defaults to 1) The level of the PIDs. * * @return array */ @@ -96,17 +94,16 @@ protected function fetchItems( ModuleModel $moduleModel, PageItems $items, array $fields, - array $arrPIDs, - $arrStop = PHP_INT_MAX, - $intHard = PHP_INT_MAX, - $intLevel = 1 + array $parentIds, + array $stopLevels, + int $hardStop = PHP_INT_MAX, + int $level = 1 ): array { - $intLevel = max(1, $intLevel); - $arrStop = (array) $arrStop; + $level = max(1, $level); // nothing todo - // $intLevel == $intHard + 1 requires subitem detection for css class "submenu" calculation - if (! $arrPIDs || $intLevel - 1 > $intHard) { + // $level == $hardStop + 1 requires subitem detection for css class "submenu" calculation + if (! $parentIds || $level - 1 > $hardStop) { return []; } @@ -128,17 +125,17 @@ protected function fetchItems( ->addErrorPagesCondition($queryBuilder, (bool) $moduleModel->hofff_navigation_showErrorPages) ->addGuestsQueryParts($queryBuilder, (bool) $moduleModel->backboneit_navigation_showGuests); - $arrFetched = []; + $fetched = []; - while ($arrPIDs) { + while ($parentIds) { // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop - if ($intLevel > $intHard) { - $arrEndPIDs = $arrPIDs; - } elseif ($intLevel > $arrStop[0]) { - count($arrStop) > 1 && array_shift($arrStop); + if ($level > $hardStop) { + $arrEndPIDs = $parentIds; + } elseif ($level > $stopLevels[0]) { + count($stopLevels) > 1 && array_shift($stopLevels); $arrEndPIDs = []; - foreach ($arrPIDs as $intPID) { - if ($items->isInTrail((int) $intPID)) { + foreach ($parentIds as $intPID) { + if (!$items->isInTrail((int) $intPID)) { $arrEndPIDs[$intPID] = true; } } @@ -147,14 +144,14 @@ protected function fetchItems( } $query = clone $queryBuilder; - $query->setParameter('pids', $arrPIDs, Connection::PARAM_INT_ARRAY); + $query->setParameter('pids', $parentIds, Connection::PARAM_INT_ARRAY); $result = $query->execute(); if ($result->rowCount() === 0) { break; } - $arrPIDs = []; + $parentIds = []; while ($arrPage = $result->fetchAssociative()) { if (isset($items->items[$arrPage['id']])) { continue; @@ -167,18 +164,18 @@ protected function fetchItems( if (! isset($arrEndPIDs[$arrPage['pid']])) { $items->subItems[(int) $arrPage['pid']][] = (int) $arrPage['id']; // for order of items $items->items[(int) $arrPage['id']] = $arrPage; // item datasets - $arrPIDs[] = $arrPage['id']; // ids of current layer (for next layer pids) - $arrFetched[$arrPage['id']] = true; // fetched in this method + $parentIds[] = $arrPage['id']; // ids of current layer (for next layer pids) + $fetched[$arrPage['id']] = true; // fetched in this method } elseif (! isset($items->subItems[$arrPage['pid']])) { $items->subItems[$arrPage['pid']] = []; } } - $intLevel++; + $level++; } - return $arrFetched; + return $fetched; } From fed8aa5ffaa0d4e2e99235b739800c55a944dd04 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:19 +0200 Subject: [PATCH 19/75] Simplify hook handling. Only module configuration can handle it now --- src/FrontendModule/AbstractModuleNavigation.php | 4 ---- src/Renderer/NavigationRenderer.php | 16 ++++++---------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index 052ebb1..93e9eb3 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -41,10 +41,6 @@ */ abstract class AbstractModuleNavigation extends Module { - const HOOK_DISABLE = 0; - const HOOK_ENABLE = 1; - const HOOK_FORCE = 2; - public static $arrDefaultFields = [ 'id' => true, 'pid' => true, diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 252d19d..61a2226 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -204,8 +204,7 @@ public function compileTree(ModuleModel $moduleModel, PageItems $items): void $moduleModel, $items, $items->items[$intID], - $blnForwardResolution, - AbstractModuleNavigation::HOOK_ENABLE + $blnForwardResolution ); } } @@ -221,8 +220,7 @@ public function compileNavigationItem( ModuleModel $moduleModel, PageItems $items, array $arrPage, - $blnForwardResolution = true, - $intItemHook = AbstractModuleNavigation::HOOK_DISABLE + bool $forwardResolution = true ) { // fallback for dataset field collisions $arrPage['_title'] = $arrPage['title']; @@ -241,7 +239,7 @@ public function compileNavigationItem( switch ($arrPage['type']) { case 'forward': - if ($blnForwardResolution) { + if ($forwardResolution) { $redirectPage = $this->getRedirectPage($arrPage); if (! $redirectPage) { $arrPage['href'] = $this->generatePageUrl($arrPage); @@ -284,9 +282,7 @@ public function compileNavigationItem( break; } - if ($intItemHook != AbstractModuleNavigation::HOOK_DISABLE) { - $this->executeItemHook($moduleModel, $arrPage, $intItemHook == AbstractModuleNavigation::HOOK_FORCE); - } + $this->executeItemHook($moduleModel, $arrPage); return $arrPage; } @@ -320,9 +316,9 @@ public function encodeEmailURL(string $strHref): string return StringUtil::encodeEmail($strHref); } - protected function executeItemHook(ModuleModel $moduleModel, array &$arrPage, $blnForce = false): void + protected function executeItemHook(ModuleModel $moduleModel, array &$arrPage): void { - if (! $blnForce && ! $moduleModel->hofff_navigation_disableHooks) { + if (! $moduleModel->hofff_navigation_disableHooks) { return; } From 38c19613f23ae8672233be6f9fefe6e7d55a4cb8 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:20 +0200 Subject: [PATCH 20/75] Name improvements --- .../AbstractModuleNavigation.php | 2 +- src/QueryBuilder/PageQueryBuilder.php | 2 +- src/Renderer/NavigationRenderer.php | 68 +++++++++---------- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index 93e9eb3..fba0bf6 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -411,7 +411,7 @@ protected function getQuotedFieldsPart(array $fields): string * * @return string The wildcard HTML string */ - protected function generateBE($strBEType = 'NAVIGATION') + protected function generateBE($strBEType = 'NAVIGATION'): string { $objTemplate = new BackendTemplate('be_wildcard'); diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index c13563e..772e399 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -72,7 +72,7 @@ public function addErrorPagesCondition(QueryBuilder $queryBuilder, bool $showErr return $this; } - public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests): self + public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests = false): self { if ($showGuests) { return $this; diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 61a2226..f96c5b9 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -212,63 +212,63 @@ public function compileTree(ModuleModel $moduleModel, PageItems $items): void /** * Compiles a navigation item array from a page dataset with the given subnavi * - * @param array $arrPage The page dataset as an array + * @param array $page The page dataset as an array * * @return array The compiled navigation item array */ public function compileNavigationItem( ModuleModel $moduleModel, PageItems $items, - array $arrPage, + array $page, bool $forwardResolution = true ) { // fallback for dataset field collisions - $arrPage['_title'] = $arrPage['title']; - $arrPage['_pageTitle'] = $arrPage['pageTitle']; - $arrPage['_target'] = $arrPage['target']; - $arrPage['_description'] = $arrPage['description']; - - $arrPage['link'] = $arrPage['_title']; - $arrPage['class'] = $arrPage['cssClass'] . ' ' . $arrPage['type']; - $arrPage['title'] = StringUtil::specialchars($arrPage['_title'], true); - $arrPage['pageTitle'] = StringUtil::specialchars($arrPage['_pageTitle'], true); - $arrPage['target'] = ''; // overwrite DB value - $arrPage['nofollow'] = strncmp($arrPage['robots'], 'noindex', 7) === 0; - $arrPage['description'] = str_replace(["\n", "\r"], [' ', ''], $arrPage['_description']); - $arrPage['isInTrail'] = $items->isInTrail((int) $arrPage['id']); - - switch ($arrPage['type']) { + $page['_title'] = $page['title']; + $page['_pageTitle'] = $page['pageTitle']; + $page['_target'] = $page['target']; + $page['_description'] = $page['description']; + + $page['link'] = $page['_title']; + $page['class'] = $page['cssClass'] . ' ' . $page['type']; + $page['title'] = StringUtil::specialchars($page['_title'], true); + $page['pageTitle'] = StringUtil::specialchars($page['_pageTitle'], true); + $page['target'] = ''; // overwrite DB value + $page['nofollow'] = strncmp($page['robots'], 'noindex', 7) === 0; + $page['description'] = str_replace(["\n", "\r"], [' ', ''], $page['_description']); + $page['isInTrail'] = $items->isInTrail((int) $page['id']); + + switch ($page['type']) { case 'forward': if ($forwardResolution) { - $redirectPage = $this->getRedirectPage($arrPage); + $redirectPage = $this->getRedirectPage($page); if (! $redirectPage) { - $arrPage['href'] = $this->generatePageUrl($arrPage); + $page['href'] = $this->generatePageUrl($page); } elseif ($redirectPage['type'] === 'redirect') { - $arrPage['href'] = $this->encodeEmailURL($redirectPage['url']); - $arrPage['target'] = $redirectPage['target'] ? LINK_NEW_WINDOW : ''; + $page['href'] = $this->encodeEmailURL($redirectPage['url']); + $page['target'] = $redirectPage['target'] ? LINK_NEW_WINDOW : ''; } else { - $arrPage['tid'] = $redirectPage['id']; - $arrPage['href'] = $this->generatePageUrl($redirectPage); + $page['tid'] = $redirectPage['id']; + $page['href'] = $this->generatePageUrl($redirectPage); } } else { - $arrPage['tid'] = $arrPage['jumpTo']; - $arrPage['href'] = $this->generatePageUrl($arrPage); + $page['tid'] = $page['jumpTo']; + $page['href'] = $this->generatePageUrl($page); } break; case 'redirect': - $arrPage['href'] = $this->encodeEmailURL($arrPage['url']); - $arrPage['target'] = $arrPage['_target'] ? LINK_NEW_WINDOW : ''; + $page['href'] = $this->encodeEmailURL($page['url']); + $page['target'] = $page['_target'] ? LINK_NEW_WINDOW : ''; break; case 'root': - if (! $arrPage['dns'] - || preg_replace('/^www\./', '', $arrPage['dns']) == preg_replace( + if (! $page['dns'] + || preg_replace('/^www\./', '', $page['dns']) == preg_replace( '/^www\./', '', Environment::get('httpHost') )) { - $arrPage['href'] = Environment::get('base'); + $page['href'] = Environment::get('base'); break; // we only break on root pages; pages in different roots should be handled by DomainLink extension } // do not break @@ -278,13 +278,13 @@ public function compileNavigationItem( case 'error_401': case 'error_403': case 'error_404': - $arrPage['href'] = $this->generatePageUrl($arrPage); + $page['href'] = $this->generatePageUrl($page); break; } - $this->executeItemHook($moduleModel, $arrPage); + $this->executeItemHook($moduleModel, $page); - return $arrPage; + return $page; } private function generatePageUrl(array $arrPage): ?string @@ -335,8 +335,6 @@ protected function executeItemHook(ModuleModel $moduleModel, array &$arrPage): v * The callback receives the following parameters: * $this - This navigation module instance * - * @param array $arrRootIDs The root pages before hook execution - * * @return void */ protected function executeTreeHook(ModuleModel $moduleModel, PageItems $items, $blnForce = false): void From 99c4ece38df6a70eb1407de7a25458c6dde2bdb4 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:20 +0200 Subject: [PATCH 21/75] Move old hook settings --- src/FrontendModule/AbstractModuleNavigation.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php index fba0bf6..4d76ea4 100644 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ b/src/FrontendModule/AbstractModuleNavigation.php @@ -70,9 +70,6 @@ abstract class AbstractModuleNavigation extends Module public $varActiveID; // the id of the active page - protected $blnTreeHook = false; // execute tree hook? - protected $blnItemHook = false; // execute item hook? - public function __construct($objModule, $strColumn = 'main') { parent::__construct($objModule, $strColumn); @@ -114,11 +111,6 @@ public function __construct($objModule, $strColumn = 'main') } $this->objStmt = $this->Database->prepare('*'); - - if (! $this->hofff_navigation_disableHooks) { - $this->blnTreeHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_tree']); - $this->blnItemHook = is_array($GLOBALS['TL_HOOKS']['hofff_navigation_item']); - } } public function __get($strKey) From 72be3f51ae16564db75b168bfac986ee004204ab Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:20 +0200 Subject: [PATCH 22/75] Extract more from modules into sub codes --- composer.json | 4 - src/ContaoManager/Plugin.php | 2 +- .../Dca/NavigationDcaListener.php | 4 +- .../AbstractModuleNavigation.php | 418 ------------------ src/FrontendModule/ModuleNavigationMenu.php | 202 ++++++--- src/Items/PageItemsLoader.php | 349 +++++++++++---- src/Migration/BackboneNavigationMigration.php | 1 + src/QueryBuilder/PageQueryBuilder.php | 160 ++++++- src/Renderer/NavigationRenderer.php | 31 +- src/Resources/config/services.xml | 4 - .../contao/templates/nav_hofff.html5 | 2 +- 11 files changed, 577 insertions(+), 600 deletions(-) delete mode 100644 src/FrontendModule/AbstractModuleNavigation.php diff --git a/composer.json b/composer.json index 688cfb1..447bdbf 100644 --- a/composer.json +++ b/composer.json @@ -41,10 +41,6 @@ "doctrine/coding-standard": "^9.0.", "phpcq/runner-bootstrap": "1.x-dev" }, - "replace": { - "contao-legacy/backboneit_navigation": "self.version", - "backboneit/contao-navigation": "self.version" - }, "extra": { "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin", "branch-alias": { diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index cb366dc..6add8c4 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -18,7 +18,7 @@ public function getBundles(ParserInterface $parser): array return [ BundleConfig::create(HofffContaoNavigationBundle::class) ->setLoadAfter([ContaoCoreBundle::class]) - ->setReplace(['backboneit_navigation']), +// ->setReplace(['backboneit_navigation']), ]; } } diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index c7d45d6..77afa6f 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -5,7 +5,7 @@ use Contao\Controller; use Contao\CoreBundle\Framework\ContaoFramework; use Contao\CoreBundle\ServiceAnnotation\Callback; -use Hofff\Contao\Navigation\FrontendModule\AbstractModuleNavigation; +use Hofff\Contao\Navigation\FrontendModule\ModuleNavigationMenu; class NavigationDcaListener { @@ -30,7 +30,7 @@ public function getPageFields(): array $fields = []; foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) { - if (! isset(AbstractModuleNavigation::$arrDefaultFields[$strField])) { + if (! isset(ModuleNavigationMenu::$arrDefaultFields[$strField])) { $fields[$strField] = &$arrConfig['label'][0]; } } diff --git a/src/FrontendModule/AbstractModuleNavigation.php b/src/FrontendModule/AbstractModuleNavigation.php deleted file mode 100644 index 4d76ea4..0000000 --- a/src/FrontendModule/AbstractModuleNavigation.php +++ /dev/null @@ -1,418 +0,0 @@ - the ID of the current item (optional) - * isInTrail => whether this item is in the trail path - * class => CSS classes - * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities - * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities - * link => page name (with Insert-Tags and XML specialchars NOT replaced; as stored in the db) - * href => URL of target page - * nofollow => true, if nofollow should be set on rel attribute - * target => either ' onclick="window.open(this.href); return false;"' or empty string - * description => page description with line breaks (\r and \n) replaced by whitespaces - * - * Calculated while rendering: - * subitems => subnavigation as HTML string or empty string (rendered if subpages & items setup correctly) - * isActive => whether this item is the current active navigation item - * - * Following CSS classes are calculated while rendering: level_x, trail, sibling, submenu, first, last - * - * Additionally all page dataset values from the database are available unter their field name, - * if the field name does not collide with the listed keys. - * - * For the collisions of the Contao core page dataset fields the following keys are available: - * _type - * _title - * _pageTitle - * _target - * _description - * - * @author Oliver Hoff - */ -abstract class AbstractModuleNavigation extends Module -{ - public static $arrDefaultFields = [ - 'id' => true, - 'pid' => true, - 'sorting' => true, - 'tstamp' => true, - 'type' => true, - 'alias' => true, - 'title' => true, - 'protected' => true, - 'groups' => true, - 'jumpTo' => true, - 'pageTitle' => true, - 'target' => true, - 'description' => true, - 'url' => true, - 'robots' => true, - 'cssClass' => true, - 'accesskey' => true, - 'tabindex' => true, - ]; - - protected $arrFields = []; // the fields to use for navigation tpl - - protected $objStmt; // a reusable stmt object - - protected $arrGroups; // set of groups of the current user - - public $varActiveID; // the id of the active page - - public function __construct($objModule, $strColumn = 'main') - { - parent::__construct($objModule, $strColumn); - if (TL_MODE == 'BE') { - return; - } - - - $this->import('Database'); - - $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get('articles') - ? null - : (int) $GLOBALS['objPage']->id; - - if (FE_USER_LOGGED_IN) { - $this->import('FrontendUser', 'User'); - $this->User->groups && $this->arrGroups = $this->User->groups; - } - - if (! strlen($this->navigationTpl)) { - $this->navigationTpl = 'nav_default'; - } - - $arrFields = deserialize($this->hofff_navigation_addFields, true); - - if (count($arrFields) > 10) { - $this->arrFields[] = '*'; - } elseif ($arrFields) { - $arrFields = array_flip($arrFields); - foreach ($this->Database->listFields('tl_page') as $arrField) { - if (isset($arrFields[$arrField['name']])) { - $this->arrFields[$arrField['name']] = true; - } - } - - $this->arrFields = array_keys(array_merge($this->arrFields, self::$arrDefaultFields)); - } else { - $this->arrFields = array_keys(self::$arrDefaultFields); - } - - $this->objStmt = $this->Database->prepare('*'); - } - - public function __get($strKey) - { - switch ($strKey) { - case 'strJumpToFallbackQuery': - case 'strJumpToQuery': - case 'arrFields': - case 'arrGroups': - case 'arrTrail': - return $this->$strKey; - } - - return parent::__get($strKey); - } - - /** - * Filters the given array of page IDs in regard of publish state, - * required permissions (protected and guests only) and hidden state, according to - * this navigations settings. - * Maintains relative order of the input array. - * - * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages - * contains no hazardous code. - * - * @param array $arrPages An array of page IDs to filter - * - * @return array Filtered array of page IDs - */ - public function filterPages(array $arrPages, $strConditions = '') - { - if (! $arrPages) { - return $arrPages; - } - - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - $objPage = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' - FROM tl_page - WHERE id IN (' . implode(',', array_keys(array_flip($arrPages))) . ') - ' . $strConditions - ); - - if (! $this->isPermissionCheckRequired()) { - return array_intersect($arrPages, $objPage->fetchEach('id')); - } // restore order - - $arrPIDs = []; - $arrValid = []; - while ($arrPage = $objPage->fetchAssoc()) { - if ($this->isPermissionDenied($arrPage)) { - continue; - } - - $arrValid[] = $arrPage['id']; - /* - * do not remove the protected check! permission denied checks for - * more, but we need to know, if we must recurse to parent pages, - * for permission check, which must not be done, when this page - * defines access rights. - */ - if (! $arrPage['protected'] && $arrPage['pid'] != 0) { - $arrPIDs[$arrPage['pid']][] = $arrPage['id']; - } - } - - // exclude pages which are in a protected path - while (count($arrPIDs)) { - $arrIDs = $arrPIDs; - $arrPIDs = []; - - $objPage = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' - FROM tl_page - WHERE id IN (' . implode(',', array_keys($arrIDs)) . ')' - ); - - while ($arrPage = $objPage->fetchAssoc()) { - if (! $arrPage['protected']) { // do not remove, see above - if ($arrPage['pid'] != 0) { - $arrPIDs[$arrPage['pid']] = isset($arrPIDs[$arrPage['pid']]) - ? array_merge($arrPIDs[$arrPage['pid']], $arrIDs[$arrPage['id']]) - : $arrIDs[$arrPage['id']]; - } - } elseif ($this->isPermissionDenied($arrPage)) { - $arrValid = array_diff($arrValid, $arrIDs[$arrPage['id']]); - } - } - } - - return array_intersect($arrPages, $arrValid); - } - - /** - * Retrieves the subpages of the given array of page IDs in respect of the - * given conditions, which are added to the WHERE clause of the query. - * Maintains relative order of the input array. - * - * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages - * contains no hazardous code. - * - * @param array $arrPages An array of parent IDs - * - * @return array The child IDs - */ - public function getNextLevel(array $arrPages, $strConditions = '') - { - if (! $arrPages) { - return $arrPages; - } - - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - $objNext = $this->objStmt->query( - 'SELECT ' . $this->getQuotedFieldsPart(['id', 'pid', 'protected', 'groups']) . ' - FROM tl_page - WHERE pid IN (' . implode(',', array_keys(array_flip($arrPages))) . ') - ' . $strConditions . ' - ORDER BY sorting' - ); - - $arrNext = []; - if ($this->isPermissionCheckRequired()) { - while ($arrPage = $objNext->fetchAssoc()) { - if (! $this->isPermissionDenied($arrPage)) { - $arrNext[$arrPage['pid']][] = $arrPage['id']; - } - } - } else { - while ($arrPage = $objNext->fetchAssoc()) { - $arrNext[$arrPage['pid']][] = $arrPage['id']; - } - } - - $arrNextLevel = []; - foreach ($arrPages as $intID) { - if (isset($arrNext[$intID])) { - $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); - } - } - - return $arrNextLevel; - } - - /** - * Retrieves the parents of the given array of page IDs in respect of the - * given conditions, which are added to the WHERE clause of the query. - * Maintains relative order of the input array and merges subsequent parent - * IDs. - * - * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages - * contains no hazardous code. - * - * @param array $arrPages An array of child IDs - * - * @return array The parent IDs - */ - public function getPrevLevel(array $arrPages, $strConditions = '') - { - if (! $arrPages) { - return $arrPages; - } - - $strConditions && $strConditions = 'AND (' . $strConditions . ')'; - $objPrev = $this->objStmt->query( - 'SELECT id, pid - FROM tl_page - WHERE id IN (' . implode(',', array_keys(array_flip($arrPages))) . ') - ' . $strConditions - ); - - $arrPrev = []; - while ($objPrev->next()) { - $arrPrev[$objPrev->id] = $objPrev->pid; - } - - $arrPrevLevel = []; - $intPID = -1; - foreach ($arrPages as $intID) { - if (isset($arrPrev[$intID]) && $arrPrev[$intID] != $intPID) { - $arrPrevLevel[] = $intPID = $arrPrev[$intID]; - } - } - - return $arrPrevLevel; - } - - - public function isPermissionCheckRequired() - { - return ! BE_USER_LOGGED_IN && ! $this->hofff_navigation_showProtected; - } - - /** - * Utility method. - * - * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! - * - * Checks if the current user has no permission to view the page of the - * given page dataset, in regards to the permission requirements of the - * page. - * - * @param array $arrPage The page dataset of the current page, with at least - * groups and protected attributes set. - * - * @return boolean If the permission is denied true, otherwise false. - */ - public function isPermissionDenied($arrPage) - { - if (! $arrPage['protected']) // this page is not protected - { - return false; - } - - if (! $this->arrGroups) // the current user is not in any group - { - return true; - } - - // check if the current user is not in any group, which is allowed to access the current page - return ! array_intersect($this->arrGroups, deserialize($arrPage['groups'], true)); - } - - /** - * Returns the part of the where condition, checking for hidden state of a page. - * - * @return string The where condition - */ - public function getQueryPartHidden($blnShowHidden = false, $blnSitemap = false) - { - if ($blnShowHidden) { - return ''; - } elseif ($blnSitemap) { - return '(sitemap = \'map_always\' OR (hide != 1 AND sitemap != \'map_never\'))'; - } else { - return 'hide != 1'; - } - } - - /** - * Returns the part of the where condition, checking for guest visibility state of a page. - * - * @return string The where condition - */ - public function getQueryPartGuests() - { - if (FE_USER_LOGGED_IN && ! BE_USER_LOGGED_IN) { - return 'guests != 1'; - } else { - return ''; - } - } - - /** - * Returns the part of the where condition checking for publication state of a page. - * - * @return string The where condition - */ - public function getQueryPartPublish() - { - if (BE_USER_LOGGED_IN) { - return ''; - } else { - static $intTime; - if (! $intTime) { - $intTime = time(); - } - - return '(start = \'\' OR start < ' . $intTime . ') AND (stop = \'\' OR stop > ' . $intTime . ') AND published = 1'; - } - } - - public function getQueryPartErrorPages($blnShowErrorPages = false) - { - if ($blnShowErrorPages) { - return ''; - } else { - return 'type != \'error_401\' AND type != \'error_403\' AND type != \'error_404\''; - } - } - - protected function getQuotedFieldsPart(array $fields): string - { - return implode(', ', array_map([$this->Database, 'quoteIdentifier'], $fields)); - } - - /** - * A helper method to generate BE wildcard. - * - * @param string $strBEType (optional, defaults to "NAVIGATION") The type to be displayed in the wildcard - * - * @return string The wildcard HTML string - */ - protected function generateBE($strBEType = 'NAVIGATION'): string - { - $objTemplate = new BackendTemplate('be_wildcard'); - - $objTemplate->wildcard = '### ' . $strBEType . ' ###'; - $objTemplate->title = $this->headline; - $objTemplate->id = $this->id; - $objTemplate->link = $this->name; - $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; - - return $objTemplate->parse(); - } -} diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 2e3beab..abe3e7c 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -2,17 +2,89 @@ namespace Hofff\Contao\Navigation\FrontendModule; -use Contao\StringUtil; +use Contao\BackendTemplate; +use Contao\Module; use Contao\System; use Hofff\Contao\Navigation\Items\PageItemsLoader; use Hofff\Contao\Navigation\Renderer\NavigationRenderer; -final class ModuleNavigationMenu extends AbstractModuleNavigation +use function array_flip; +use function array_keys; +use function array_merge; +use function deserialize; +use function strlen; + +use const TL_MODE; + +/** + * Navigation modules + * + * Navigation item array layout: + * Before rendering: + * id => the ID of the current item (optional) + * isInTrail => whether this item is in the trail path + * class => CSS classes + * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities + * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities + * link => page name (with Insert-Tags and XML specialchars NOT replaced; as stored in the db) + * href => URL of target page + * nofollow => true, if nofollow should be set on rel attribute + * target => either ' onclick="window.open(this.href); return false;"' or empty string + * description => page description with line breaks (\r and \n) replaced by whitespaces + * + * Calculated while rendering: + * subitems => subnavigation as HTML string or empty string (rendered if subpages & items setup correctly) + * isActive => whether this item is the current active navigation item + * + * Following CSS classes are calculated while rendering: level_x, trail, sibling, submenu, first, last + * + * Additionally all page dataset values from the database are available unter their field name, + * if the field name does not collide with the listed keys. + * + * For the collisions of the Contao core page dataset fields the following keys are available: + * _type + * _title + * _pageTitle + * _target + * _description + * + * @author Oliver Hoff + */ +final class ModuleNavigationMenu extends Module { protected $strTemplate = 'mod_hofff_navigation_menu'; + public static $arrDefaultFields = [ + 'id' => true, + 'pid' => true, + 'sorting' => true, + 'tstamp' => true, + 'type' => true, + 'alias' => true, + 'title' => true, + 'protected' => true, + 'groups' => true, + 'jumpTo' => true, + 'pageTitle' => true, + 'target' => true, + 'description' => true, + 'url' => true, + 'robots' => true, + 'cssClass' => true, + 'accesskey' => true, + 'tabindex' => true, + ]; + protected string $strNavigation = ''; + protected $arrFields = []; // the fields to use for navigation tpl + + protected $objStmt; // a reusable stmt object + + protected $arrGroups; // set of groups of the current user + + public $varActiveID; // the id of the active page + private PageItemsLoader $loader; private NavigationRenderer $renderer; @@ -23,6 +95,44 @@ public function __construct($objModule, $strColumn = 'main') $this->loader = System::getContainer()->get(PageItemsLoader::class); $this->renderer = System::getContainer()->get(NavigationRenderer::class); + + if (TL_MODE === 'BE') { + return; + } + + $this->import('Database'); + + $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get('articles') + ? null + : (int) $GLOBALS['objPage']->id; + + if (FE_USER_LOGGED_IN) { + $this->import('FrontendUser', 'User'); + $this->User->groups && $this->arrGroups = $this->User->groups; + } + + if (! strlen($this->navigationTpl)) { + $this->navigationTpl = 'nav_default'; + } + + $arrFields = deserialize($this->hofff_navigation_addFields, true); + + if (count($arrFields) > 10) { + $this->arrFields[] = '*'; + } elseif ($arrFields) { + $arrFields = array_flip($arrFields); + foreach ($this->Database->listFields('tl_page') as $arrField) { + if (isset($arrFields[$arrField['name']])) { + $this->arrFields[$arrField['name']] = true; + } + } + + $this->arrFields = array_keys(array_merge($this->arrFields, self::$arrDefaultFields)); + } else { + $this->arrFields = array_keys(self::$arrDefaultFields); + } + + $this->objStmt = $this->Database->prepare('*'); } public function generate(): string @@ -33,14 +143,13 @@ public function generate(): string $stopLevels = $this->getStopLevels(); $hardLevel = $this->getHardLevel(); - $rootIds = $this->calculateRootIDs($stopLevels); - $items = $this->loader->load($this->objModel, $rootIds, $this->arrFields, $stopLevels, $hardLevel); + $items = $this->loader->load($this->objModel, $this->arrFields, $stopLevels, $hardLevel, $this->varActiveID); $this->strNavigation = $this->renderer->render( $this->objModel, $items, - $rootIds, + array_keys($items->roots), $stopLevels, $hardLevel, $this->varActiveID @@ -80,76 +189,23 @@ protected function compile(): void $this->hofff_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; } - protected function calculateRootIDs($arrStop = PHP_INT_MAX) + /** + * A helper method to generate BE wildcard. + * + * @param string $strBEType (optional, defaults to "NAVIGATION") The type to be displayed in the wildcard + * + * @return string The wildcard HTML string + */ + protected function generateBE($strBEType = 'NAVIGATION'): string { - $arrRootIDs = $this->hofff_navigation_defineRoots - ? $this->getRootIds() - : [$GLOBALS['objPage']->rootId]; - - $this->hofff_navigation_currentAsRoot && array_unshift($arrRootIDs, $GLOBALS['objPage']->id); - - $arrConditions = [ - $this->getQueryPartHidden( - ! $this->hofff_navigation_respectHidden, - $this->hofff_navigation_isSitemap - ), - ]; - $this->hofff_navigation_respectGuests && $arrConditions[] = $this->getQueryPartGuests(); - $this->hofff_navigation_respectPublish && $arrConditions[] = $this->getQueryPartPublish(); - $strConditions = implode(' AND ', array_filter($arrConditions, 'strlen')); - - if ($this->hofff_navigation_includeStart) { - $arrStartConditions = [ - $this->getQueryPartHidden( - $this->hofff_navigation_showHiddenStart, - $this->hofff_navigation_isSitemap - ), - $this->getQueryPartPublish(), - $this->getQueryPartErrorPages($this->hofff_navigation_showErrorPages), - ]; - ! $this->hofff_navigation_showGuests && $arrStartConditions[] = $this->getQueryPartGuests(); - $strStartConditions = implode(' AND ', array_filter($arrStartConditions, 'strlen')); - } else { - $strStartConditions = $strConditions; - } - - if ($this->hofff_navigation_start > 0) { - $arrRootIDs = $this->filterPages($arrRootIDs, $strConditions); - for ($i = 1, $n = $this->hofff_navigation_start; $i < $n; $i++) { - $arrRootIDs = $this->getNextLevel($arrRootIDs, $strConditions); - } - $arrRootIDs = $this->getNextLevel($arrRootIDs, $strStartConditions); - } elseif ($this->hofff_navigation_start < 0) { - for ($i = 0, $n = -$this->hofff_navigation_start; $i < $n; $i++) { - $arrRootIDs = $this->getPrevLevel($arrRootIDs); - } - $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); - } else { - $arrRootIDs = $this->filterPages($arrRootIDs, $strStartConditions); - } - - $arrStop = (array) $arrStop; - if ($arrStop[0] == 0) { // special case, keep only roots within the current path - $arrPath = $GLOBALS['objPage']->trail; - $arrPath[] = $this->varActiveID; - $arrRootIDs = array_intersect($arrRootIDs, $arrPath); - } + $objTemplate = new BackendTemplate('be_wildcard'); - return $arrRootIDs; - } + $objTemplate->wildcard = '### ' . $strBEType . ' ###'; + $objTemplate->title = $this->headline; + $objTemplate->id = $this->id; + $objTemplate->link = $this->name; + $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; - protected function getRootIds(): array - { - return array_map( - 'intval', - array_values( - array_unique( - array_merge( - StringUtil::deserialize($this->hofff_navigation_roots_order, true), - StringUtil::deserialize($this->hofff_navigation_roots, true) - ) - ) - ) - ); + return $objTemplate->parse(); } } diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index 332dad9..17f4a36 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -8,17 +8,22 @@ use Contao\ModuleModel; use Contao\StringUtil; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Query\QueryBuilder; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; use Symfony\Component\Security\Core\Security; +use function array_diff; use function array_flip; use function array_intersect; use function array_keys; use function array_map; +use function array_merge; use function array_shift; -use function implode; +use function array_unique; +use function array_unshift; +use function array_values; +use function in_array; use function max; -use function sprintf; use const PHP_INT_MAX; @@ -28,114 +33,93 @@ final class PageItemsLoader private Security $security; - private PageQueryBuilder $pageQueryBuilder; + private ?PageQueryBuilder $pageQueryBuilder; - public function __construct(Connection $connection, Security $security, PageQueryBuilder $pageQueryBuilder) + private PageItems $items; + + private ModuleModel $moduleModel; + + private array $stopLevels = [PHP_INT_MAX]; + + private int $hardLevel = PHP_INT_MAX; + + private ?int $activeId = null; + + public function __construct(Connection $connection, Security $security) { $this->connection = $connection; $this->security = $security; - $this->pageQueryBuilder = $pageQueryBuilder; } public function load( ModuleModel $moduleModel, - array $rootIds, array $fields, array $stopLevels = [PHP_INT_MAX], - int $hardLvel = PHP_INT_MAX + int $hardLevel = PHP_INT_MAX, + ?int $activeId = null ): PageItems { - $items = new PageItems(); - $items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); - if (! $rootIds) { - return $items; + $this->items = new PageItems(); + $this->items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); + + $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $moduleModel, $fields); + $this->moduleModel = $moduleModel; + $this->stopLevels = $stopLevels; + $this->hardLevel = $hardLevel; + $this->activeId = $activeId; + + $this->items->roots = array_flip($this->calculateRootIDs()); + if (! $this->items->roots) { + return $this->items; } - $rootIds = array_keys(array_flip($rootIds)); - foreach ($rootIds as $rootId) { - $items->items[$rootId] = $items->items[$rootId] ?? []; - } + $rootIds = array_keys($this->items->roots); if (! $moduleModel->hofff_navigation_includeStart) { - $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $stopLevels, $hardLvel); + $this->fetchItems($rootIds); - return $items; + return $this->items; } - $items->roots = $this->fetchItems($moduleModel, $items, $fields, $rootIds, $stopLevels, $hardLvel, 2); - - $result = $this->connection->executeQuery( - sprintf( - 'SELECT %s FROM tl_page WHERE id IN (:rootIds)', - $this->getQuotedFieldsPart($fields) - ), - ['rootIds' => $rootIds], - ['rootIds' => Connection::PARAM_STR_ARRAY] - ); + $this->fetchItems($rootIds, 2); + $result = $this->pageQueryBuilder->createRootInformationQuery($rootIds)->execute(); while ($row = $result->fetchAssociative()) { - $items->items[$row['id']] = $row; - $items->roots[$row['id']] = true; + $this->items->items[$row['id']] = $row; + $this->items->roots[$row['id']] = true; } - return $items; + return $this->items; } /** * Fetches page data for all navigation items below the given roots. * - * @param integer $parentIds The root pages of the navigation. - * @param integer $intStop (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $hardStop (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $level (optional, defaults to 1) The level of the PIDs. + * @param integer $level (optional, defaults to 1) The level of the PIDs. * * @return array */ - protected function fetchItems( - ModuleModel $moduleModel, - PageItems $items, - array $fields, - array $parentIds, - array $stopLevels, - int $hardStop = PHP_INT_MAX, - int $level = 1 - ): array { + protected function fetchItems(array $parentIds, int $level = 1): array + { $level = max(1, $level); // nothing todo // $level == $hardStop + 1 requires subitem detection for css class "submenu" calculation - if (! $parentIds || $level - 1 > $hardStop) { + if (! $parentIds || $level - 1 > $this->hardLevel) { return []; } - $queryBuilder = $this->connection->createQueryBuilder() - ->from('tl_page') - ->select(... $fields) - ->andWhere('type != :rootType') - ->setParameter('rootType', 'root') - ->andWhere('pid IN (:pids)') - ->orderBy('sorting'); - - $this->pageQueryBuilder - ->addHiddenCondition( - $queryBuilder, - (bool) $moduleModel->hofff_navigation_showHidden, - (bool) $moduleModel->hofff_navigation_isSitemap - ) - ->addPublishedCondition($queryBuilder) - ->addErrorPagesCondition($queryBuilder, (bool) $moduleModel->hofff_navigation_showErrorPages) - ->addGuestsQueryParts($queryBuilder, (bool) $moduleModel->backboneit_navigation_showGuests); - $fetched = []; + $stopLevels = $this->stopLevels; while ($parentIds) { // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop - if ($level > $hardStop) { + if ($level > $this->hardLevel) { $arrEndPIDs = $parentIds; } elseif ($level > $stopLevels[0]) { count($stopLevels) > 1 && array_shift($stopLevels); $arrEndPIDs = []; foreach ($parentIds as $intPID) { - if (!$items->isInTrail((int) $intPID)) { + if (!$this->items->isInTrail((int) $intPID)) { $arrEndPIDs[$intPID] = true; } } @@ -143,32 +127,31 @@ protected function fetchItems( $arrEndPIDs = []; } - $query = clone $queryBuilder; - $query->setParameter('pids', $parentIds, Connection::PARAM_INT_ARRAY); - - $result = $query->execute(); + $result = $this->pageQueryBuilder->createFetchItemsQuery($parentIds)->execute(); if ($result->rowCount() === 0) { break; } $parentIds = []; - while ($arrPage = $result->fetchAssociative()) { - if (isset($items->items[$arrPage['id']])) { + while ($page = $result->fetchAssociative()) { + if (isset($items->items[$page['id']])) { continue; } - if (! $this->isPermissionGranted($moduleModel, $arrPage)) { + if (! $this->isPermissionGranted($this->moduleModel, $page)) { continue; } - if (! isset($arrEndPIDs[$arrPage['pid']])) { - $items->subItems[(int) $arrPage['pid']][] = (int) $arrPage['id']; // for order of items - $items->items[(int) $arrPage['id']] = $arrPage; // item datasets - $parentIds[] = $arrPage['id']; // ids of current layer (for next layer pids) - $fetched[$arrPage['id']] = true; // fetched in this method + if (! isset($arrEndPIDs[$page['pid']])) { + if (! in_array((int) $page['id'], $this->items->subItems[(int) $page['pid']] ?? [])) { + $this->items->subItems[(int) $page['pid']][] = (int) $page['id']; // for order of items + } - } elseif (! isset($items->subItems[$arrPage['pid']])) { - $items->subItems[$arrPage['pid']] = []; + $this->items->items[(int) $page['id']] = $page; // item datasets + $parentIds[] = $page['id']; // ids of current layer (for next layer pids) + $fetched[$page['id']] = true; // fetched in this method + } elseif (! isset($items->subItems[(int) $page['pid']])) { + $this->items->subItems[(int) $page['pid']] = []; } } @@ -178,10 +161,41 @@ protected function fetchItems( return $fetched; } + protected function calculateRootIDs(): array + { + $rootIds = $this->getRootIds(); + if ($this->moduleModel->hofff_navigation_currentAsRoot) { + array_unshift($rootIds, $GLOBALS['objPage']->id); + } + + if ($this->moduleModel->hofff_navigation_start > 0) { + $rootIds = $this->filterPages($rootIds, $this->pageQueryBuilder->createRootIdsQuery()); + for ($i = 1, $n = $this->moduleModel->hofff_navigation_start; $i < $n; $i++) { + $rootIds = $this->getNextLevel($rootIds, $this->pageQueryBuilder->createRootIdsQuery()); + } + $rootIds = $this->getNextLevel($rootIds, $this->pageQueryBuilder->createStartRootIdsQuery()); + } elseif ($this->moduleModel->hofff_navigation_start < 0) { + for ($i = 0, $n = -$this->moduleModel->hofff_navigation_start; $i < $n; $i++) { + $rootIds = $this->getPrevLevel($rootIds); + } + $rootIds = $this->filterPages($rootIds, $this->pageQueryBuilder->createStartRootIdsQuery()); + } else { + $rootIds = $this->filterPages($rootIds, $this->pageQueryBuilder->createStartRootIdsQuery()); + } + + $stopLevels = $this->stopLevels; + if ($stopLevels[0] == 0) { // special case, keep only roots within the current path + $path = $GLOBALS['objPage']->trail; + $path[] = $this->activeId; + $rootIds = array_intersect($rootIds, $path); + } + + return $rootIds; + } - protected function getQuotedFieldsPart(array $fields): string + public function isPermissionCheckRequired(): bool { - return implode(', ', array_map([$this->connection, 'quoteIdentifier'], $fields)); + return ! BE_USER_LOGGED_IN && ! $this->moduleModel->hofff_navigation_showProtected; } /** @@ -248,6 +262,179 @@ public function isPermissionDenied(array $arrPage): bool } // check if the current user is not in any group, which is allowed to access the current page - return ! array_intersect((array) $user->groups, StringUtil::deserialize($arrPage['groups'], true)); + return ! array_intersect((array) $user->groups, StringUtil::deserialize($arrPage['groups'], true)); + } + + protected function getRootIds(): array + { + if (! $this->moduleModel->hofff_navigation_defineRoots) { + return [(int) $GLOBALS['objPage']->rootId]; + } + + return array_map( + 'intval', + array_values( + array_unique( + array_merge( + StringUtil::deserialize($this->moduleModel->hofff_navigation_roots_order, true), + StringUtil::deserialize($this->moduleModel->hofff_navigation_roots, true) + ) + ) + ) + ); + } + + /** + * Filters the given array of page IDs in regard of publish state, + * required permissions (protected and guests only) and hidden state, according to + * this navigations settings. + * Maintains relative order of the input array. + * + * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * contains no hazardous code. + * + * @param array $arrPages An array of page IDs to filter + * + * @return array Filtered array of page IDs + */ + public function filterPages(array $arrPages, QueryBuilder $queryBuilder) + { + if (! $arrPages) { + return $arrPages; + } + + $queryBuilder + ->andWhere('id IN (:ids)') + ->setParameter('ids', array_keys(array_flip($arrPages)), Connection::PARAM_STR_ARRAY); + $result = $queryBuilder->execute(); + + if (! $this->isPermissionCheckRequired()) { + return array_intersect( + $arrPages, + array_map(static fn(array $row): int => (int) $row['id'], $result->fetchAllAssociative()) + ); + } // restore order + + $arrPIDs = []; + $arrValid = []; + while ($arrPage = $result->fetchAssociative()) { + if ($this->isPermissionDenied($arrPage)) { + continue; + } + + $arrValid[] = $arrPage['id']; + /* + * do not remove the protected check! permission denied checks for + * more, but we need to know, if we must recurse to parent pages, + * for permission check, which must not be done, when this page + * defines access rights. + */ + if (! $arrPage['protected'] && $arrPage['pid'] != 0) { + $arrPIDs[$arrPage['pid']][] = $arrPage['id']; + } + } + + // exclude pages which are in a protected path + while (count($arrPIDs)) { + $arrIDs = $arrPIDs; + $arrPIDs = []; + + $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($arrIDs)); + $result = $query->execute(); + + while ($arrPage = $result->fetchAssociative()) { + if (! $arrPage['protected']) { // do not remove, see above + if ($arrPage['pid'] != 0) { + $arrPIDs[$arrPage['pid']] = isset($arrPIDs[$arrPage['pid']]) + ? array_merge($arrPIDs[$arrPage['pid']], $arrIDs[$arrPage['id']]) + : $arrIDs[$arrPage['id']]; + } + } elseif ($this->isPermissionDenied($arrPage)) { + $arrValid = array_diff($arrValid, $arrIDs[$arrPage['id']]); + } + } + } + + return array_intersect($arrPages, $arrValid); + } + + /** + * Retrieves the subpages of the given array of page IDs in respect of the + * given conditions, which are added to the WHERE clause of the query. + * Maintains relative order of the input array. + * + * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * contains no hazardous code. + * + * @param array $arrPages An array of parent IDs + * + * @return array The child IDs + */ + public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array + { + if (! $arrPages) { + return $arrPages; + } + + $queryBuilder->setParameter('ids', array_keys(array_flip($arrPages)), Connection::PARAM_STR_ARRAY); + $result = $queryBuilder->execute(); + + $arrNext = []; + if ($this->isPermissionCheckRequired()) { + while ($arrPage = $result->fetchAssociative()) { + if (! $this->isPermissionDenied($arrPage)) { + $arrNext[$arrPage['pid']][] = $arrPage['id']; + } + } + } else { + while ($arrPage = $result->fetchAssociative()) { + $arrNext[$arrPage['pid']][] = $arrPage['id']; + } + } + + $arrNextLevel = []; + foreach ($arrPages as $intID) { + if (isset($arrNext[$intID])) { + $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); + } + } + + return $arrNextLevel; + } + + /** + * Retrieves the parents of the given array of page IDs in respect of the + * given conditions, which are added to the WHERE clause of the query. + * Maintains relative order of the input array and merges subsequent parent + * IDs. + * + * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * contains no hazardous code. + * + * @param array $arrPages An array of child IDs + * + * @return array The parent IDs + */ + public function getPrevLevel(array $arrPages): array + { + if (! $arrPages) { + return $arrPages; + } + + $result = $this->pageQueryBuilder->createPreviousLevelQuery(array_keys(array_flip($arrPages)))->execute(); + $arrPrev = []; + while ($row = $result->fetchAssociative()) { + $arrPrev[$row['id']] = $row['pid']; + } + + $arrPrevLevel = []; + $intPID = -1; + foreach ($arrPages as $intID) { + if (isset($arrPrev[$intID]) && $arrPrev[$intID] != $intPID) { + $arrPrevLevel[] = $intPID = $arrPrev[$intID]; + } + } + + return $arrPrevLevel; } } diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 1ceefef..2fa0664 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -49,6 +49,7 @@ public function __construct(Connection $connection) public function shouldRun(): bool { + return false; if ($this->hasBackboneItNavigationModules()) { return true; } diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 772e399..fccb117 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -4,6 +4,7 @@ namespace Hofff\Contao\Navigation\QueryBuilder; +use Contao\ModuleModel; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; @@ -18,9 +19,164 @@ final class PageQueryBuilder 'error_410' ]; - public function addPublishedCondition(QueryBuilder $queryBuilder): self + private Connection $connection; + + private ModuleModel $moduleModel; + + private array $fields; + + /** @var array */ + private $queries = []; + + public function __construct(Connection $connection, ModuleModel $moduleModel, array $fields) + { + $this->connection = $connection; + $this->moduleModel = $moduleModel; + $this->fields = $fields; + } + + public function createFetchItemsQuery(array $parentIds): QueryBuilder + { + if (! isset($this->queries[__FUNCTION__])) { + $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder() + ->from('tl_page') + ->select(... $this->fields) + ->andWhere('type != :rootType') + ->setParameter('rootType', 'root') + ->andWhere('pid IN (:pids)') + ->orderBy('sorting'); + + $this + ->addHiddenCondition( + $this->queries[__FUNCTION__], + (bool) $this->moduleModel->hofff_navigation_showHidden, + (bool) $this->moduleModel->hofff_navigation_isSitemap + ) + ->addPublishedCondition($this->queries[__FUNCTION__]) + ->addErrorPagesCondition( + $this->queries[__FUNCTION__], + (bool) $this->moduleModel->hofff_navigation_showErrorPages + ) + ->addGuestsQueryParts( + $this->queries[__FUNCTION__], + (bool) $this->moduleModel->backboneit_navigation_showGuests + ); + } + + $query = clone $this->queries[__FUNCTION__]; + $query->setParameter('pids', $parentIds, Connection::PARAM_INT_ARRAY); + + return $query; + } + + public function createRootIdsQuery(): QueryBuilder + { + if (! isset($this->queries[__FUNCTION__])) { + $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); + $this->queries[__FUNCTION__] + ->select('id', 'pid', 'protected', 'groups') + ->from('tl_page'); + + $this + ->addHiddenCondition( + $this->queries[__FUNCTION__], + ! $this->moduleModel->hofff_navigation_respectHidden, + (bool) $this->moduleModel->hofff_navigation_isSitemap + ) + ->addGuestsQueryParts( + $this->queries[__FUNCTION__], + ! $this->moduleModel->hofff_navigation_respectGuests + ) + ->addPublishedCondition( + $this->queries[__FUNCTION__], + (bool) $this->moduleModel->hofff_navigation_respectPublish + ); + } + + return clone $this->queries[__FUNCTION__]; + } + + public function createStartRootIdsQuery(): QueryBuilder + { + if (! $this->moduleModel->hofff_navigation_includeStart) { + return $this->createRootIdsQuery(); + } + + if (! isset($this->queries[__FUNCTION__])) { + $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); + + $this->queries[__FUNCTION__] + ->select('id', 'pid', 'protected', 'groups') + ->from('tl_page'); + + $this + ->addHiddenCondition( + $this->queries[__FUNCTION__], + (bool) $this->moduleModel->hofff_navigation_showHiddenStart, + (bool) $this->moduleModel->hofff_navigation_isSitemap + ) + ->addPublishedCondition($this->queries[__FUNCTION__]) + ->addErrorPagesCondition( + $this->queries[__FUNCTION__], + (bool) $this->moduleModel->hofff_navigation_showErrorPages + ) + ->addGuestsQueryParts($this->queries[__FUNCTION__], (bool) $this->moduleModel->hofff_navigation_showGuests); + } + + return clone $this->queries[__FUNCTION__]; + } + + public function createPageInformationQuery(array $pageIds): QueryBuilder + { + if (! isset($this->queries[__FUNCTION__])) { + $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); + $this->queries[__FUNCTION__] + ->select('id', 'pid', 'protected', 'groups') + ->from('tl_page') + ->where('id IN (:ids)'); + } + + $query = clone $this->queries[__FUNCTION__]; + $query->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); + + return $query; + } + + public function createRootInformationQuery(array $rootIds): QueryBuilder + { + if (! isset($this->queries[__FUNCTION__])) { + $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); + $this->queries[__FUNCTION__] + ->select(... $this->fields) + ->from('tl_page') + ->where('id IN (:rootIds)'); + } + + $query = clone $this->queries[__FUNCTION__]; + $query->setParameter('rootIds', $rootIds, Connection::PARAM_STR_ARRAY); + + return $query; + } + + public function createPreviousLevelQuery(array $pageIds): QueryBuilder + { + if (! isset($this->queries[__FUNCTION__])) { + $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); + $this->queries[__FUNCTION__] + ->select('id', 'pid') + ->from('tl_page') + ->where('id IN (:ids)'); + } + + $query = clone $this->queries[__FUNCTION__]; + $query->setParameter('ids', $pageIds); + + return $query; + } + + public function addPublishedCondition(QueryBuilder $queryBuilder, bool $respectPublished = true): self { - if (BE_USER_LOGGED_IN) { + if (BE_USER_LOGGED_IN || ! $respectPublished) { return $this; } diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index f96c5b9..4867bd3 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -11,12 +11,12 @@ use Contao\StringUtil; use Contao\System; use Doctrine\DBAL\Connection; -use Hofff\Contao\Navigation\FrontendModule\AbstractModuleNavigation; use Hofff\Contao\Navigation\Items\PageItems; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; use function array_merge; use function array_shift; +use function dump; use function get_class; use function is_array; use function ltrim; @@ -33,12 +33,11 @@ final class NavigationRenderer { private Connection $connection; - private PageQueryBuilder $pageQueryBuilder; + private ?PageQueryBuilder $pageQueryBuilder; - public function __construct(Connection $connection, PageQueryBuilder $pageQueryBuilder) + public function __construct(Connection $connection) { - $this->connection = $connection; - $this->pageQueryBuilder = $pageQueryBuilder; + $this->connection = $connection; } /** @@ -69,11 +68,13 @@ public function render( $this->compileTree($moduleModel, $items); $this->executeTreeHook($moduleModel, $items); - $arrRootIDs = $this->executeMenuHook($moduleModel, $itemIds); - $arrFirstIDs = $this->getFirstNavigationLevel($moduleModel, $items, $arrRootIDs); + $itemIds = $this->executeMenuHook($moduleModel, $itemIds); + $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); + + \dump($firstIds); if ($moduleModel->hofff_navigation_hideSingleLevel) { - foreach ($arrFirstIDs as $id) { + foreach ($firstIds as $id) { if ($items->subItems[$id]) { $hasMultipleLevels = true; break; @@ -85,9 +86,11 @@ public function render( } } - $stopLimit[0] == 0 && array_shift($stopLimit); // special case renderNavigationTree cannot handle + if ($stopLimit[0] == 0) { + array_shift($stopLimit); // special case renderNavigationTree cannot handle + } - return trim($this->renderTree($moduleModel, $items, $arrFirstIDs, $stopLimit, $intHard, $currentLevel, $activeId)); + return trim($this->renderTree($moduleModel, $items, $firstIds, $stopLimit, $intHard, $currentLevel, $activeId)); } private function renderTree( @@ -195,15 +198,15 @@ private function renderTree( public function compileTree(ModuleModel $moduleModel, PageItems $items): void { $blnForwardResolution = ! $moduleModel->hofff_navigation_noForwardResolution; - foreach ($items->roots as $intID => $_) { - if (!isset($items->items[$intID])) { + foreach ($items->items as $itemId => $item) { + if ($item === []) { continue; } - $items->items[$intID] = $this->compileNavigationItem( + $items->items[$itemId] = $this->compileNavigationItem( $moduleModel, $items, - $items->items[$intID], + $items->items[$itemId], $blnForwardResolution ); } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 89ce909..d5ec72d 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -19,14 +19,10 @@ - - - - diff --git a/src/Resources/contao/templates/nav_hofff.html5 b/src/Resources/contao/templates/nav_hofff.html5 index ff1edc5..30ea2e2 100644 --- a/src/Resources/contao/templates/nav_hofff.html5 +++ b/src/Resources/contao/templates/nav_hofff.html5 @@ -13,4 +13,4 @@ > - \ No newline at end of file + From 24b2f20e5f5e4a8a58406e5663a9d833ecb9e991 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:20 +0200 Subject: [PATCH 23/75] Move default fields to the query builder --- .../Dca/NavigationDcaListener.php | 3 +- src/FrontendModule/ModuleNavigationMenu.php | 46 +------------- src/Items/PageItemsLoader.php | 3 +- src/QueryBuilder/PageQueryBuilder.php | 61 ++++++++++++++++++- 4 files changed, 62 insertions(+), 51 deletions(-) diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index 77afa6f..3da3dc6 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -6,6 +6,7 @@ use Contao\CoreBundle\Framework\ContaoFramework; use Contao\CoreBundle\ServiceAnnotation\Callback; use Hofff\Contao\Navigation\FrontendModule\ModuleNavigationMenu; +use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; class NavigationDcaListener { @@ -30,7 +31,7 @@ public function getPageFields(): array $fields = []; foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) { - if (! isset(ModuleNavigationMenu::$arrDefaultFields[$strField])) { + if (! isset(PageQueryBuilder::DEFAULT_FIELDS[$strField])) { $fields[$strField] = &$arrConfig['label'][0]; } } diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index abe3e7c..1602da2 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -54,33 +54,8 @@ final class ModuleNavigationMenu extends Module { protected $strTemplate = 'mod_hofff_navigation_menu'; - public static $arrDefaultFields = [ - 'id' => true, - 'pid' => true, - 'sorting' => true, - 'tstamp' => true, - 'type' => true, - 'alias' => true, - 'title' => true, - 'protected' => true, - 'groups' => true, - 'jumpTo' => true, - 'pageTitle' => true, - 'target' => true, - 'description' => true, - 'url' => true, - 'robots' => true, - 'cssClass' => true, - 'accesskey' => true, - 'tabindex' => true, - ]; - protected string $strNavigation = ''; - protected $arrFields = []; // the fields to use for navigation tpl - - protected $objStmt; // a reusable stmt object - protected $arrGroups; // set of groups of the current user public $varActiveID; // the id of the active page @@ -114,25 +89,6 @@ public function __construct($objModule, $strColumn = 'main') if (! strlen($this->navigationTpl)) { $this->navigationTpl = 'nav_default'; } - - $arrFields = deserialize($this->hofff_navigation_addFields, true); - - if (count($arrFields) > 10) { - $this->arrFields[] = '*'; - } elseif ($arrFields) { - $arrFields = array_flip($arrFields); - foreach ($this->Database->listFields('tl_page') as $arrField) { - if (isset($arrFields[$arrField['name']])) { - $this->arrFields[$arrField['name']] = true; - } - } - - $this->arrFields = array_keys(array_merge($this->arrFields, self::$arrDefaultFields)); - } else { - $this->arrFields = array_keys(self::$arrDefaultFields); - } - - $this->objStmt = $this->Database->prepare('*'); } public function generate(): string @@ -144,7 +100,7 @@ public function generate(): string $stopLevels = $this->getStopLevels(); $hardLevel = $this->getHardLevel(); - $items = $this->loader->load($this->objModel, $this->arrFields, $stopLevels, $hardLevel, $this->varActiveID); + $items = $this->loader->load($this->objModel, $stopLevels, $hardLevel, $this->varActiveID); $this->strNavigation = $this->renderer->render( $this->objModel, diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index 17f4a36..abfa980 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -53,7 +53,6 @@ public function __construct(Connection $connection, Security $security) public function load( ModuleModel $moduleModel, - array $fields, array $stopLevels = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, ?int $activeId = null @@ -61,7 +60,7 @@ public function load( $this->items = new PageItems(); $this->items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); - $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $moduleModel, $fields); + $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $moduleModel); $this->moduleModel = $moduleModel; $this->stopLevels = $stopLevels; $this->hardLevel = $hardLevel; diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index fccb117..8c8bed3 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -5,13 +5,38 @@ namespace Hofff\Contao\Navigation\QueryBuilder; use Contao\ModuleModel; +use Contao\StringUtil; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; +use function array_flip; +use function array_keys; +use function array_merge; use function time; final class PageQueryBuilder { + public const DEFAULT_FIELDS = [ + 'id' => true, + 'pid' => true, + 'sorting' => true, + 'tstamp' => true, + 'type' => true, + 'alias' => true, + 'title' => true, + 'protected' => true, + 'groups' => true, + 'jumpTo' => true, + 'pageTitle' => true, + 'target' => true, + 'description' => true, + 'url' => true, + 'robots' => true, + 'cssClass' => true, + 'accesskey' => true, + 'tabindex' => true, + ]; + private const ERROR_PAGE_TYPES = [ 'error_401', 'error_403', @@ -23,16 +48,17 @@ final class PageQueryBuilder private ModuleModel $moduleModel; - private array $fields; + private array $fields = []; /** @var array */ private $queries = []; - public function __construct(Connection $connection, ModuleModel $moduleModel, array $fields) + public function __construct(Connection $connection, ModuleModel $moduleModel) { $this->connection = $connection; $this->moduleModel = $moduleModel; - $this->fields = $fields; + + $this->determineFields(); } public function createFetchItemsQuery(array $parentIds): QueryBuilder @@ -240,4 +266,33 @@ public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests return $this; } + + private function determineFields(): void + { + $customFields = StringUtil::deserialize($this->moduleModel->hofff_navigation_addFields, true); + + if (count($customFields) > 10) { + $this->fields[] = '*'; + + return; + } + + if ($customFields === []) { + $this->fields = array_keys(self::DEFAULT_FIELDS); + + return; + } + + $customFields = array_flip($customFields); + $table = $this->connection->getSchemaManager()->listTableDetails('tl_page'); + $fields = []; + + foreach ($table->getColumns() as $column) { + if (isset($customFields[$column->getName()])) { + $fields[$column->getName()] = true; + } + } + + $this->fields = array_keys(array_merge($fields, self::DEFAULT_FIELDS)); + } } From 9c51170d78c18003351675688724ec91fdf30909 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:20 +0200 Subject: [PATCH 24/75] Define activeId as locale variable --- src/FrontendModule/ModuleNavigationMenu.php | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 1602da2..7dc2026 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -8,10 +8,7 @@ use Hofff\Contao\Navigation\Items\PageItemsLoader; use Hofff\Contao\Navigation\Renderer\NavigationRenderer; -use function array_flip; use function array_keys; -use function array_merge; -use function deserialize; use function strlen; use const TL_MODE; @@ -58,8 +55,6 @@ final class ModuleNavigationMenu extends Module protected $arrGroups; // set of groups of the current user - public $varActiveID; // the id of the active page - private PageItemsLoader $loader; private NavigationRenderer $renderer; @@ -77,10 +72,6 @@ public function __construct($objModule, $strColumn = 'main') $this->import('Database'); - $this->varActiveID = $this->hofff_navigation_isSitemap || $this->Input->get('articles') - ? null - : (int) $GLOBALS['objPage']->id; - if (FE_USER_LOGGED_IN) { $this->import('FrontendUser', 'User'); $this->User->groups && $this->arrGroups = $this->User->groups; @@ -99,8 +90,11 @@ public function generate(): string $stopLevels = $this->getStopLevels(); $hardLevel = $this->getHardLevel(); + $activeId = $this->hofff_navigation_isSitemap || $this->Input->get('articles') + ? null + : (int) $GLOBALS['objPage']->id; - $items = $this->loader->load($this->objModel, $stopLevels, $hardLevel, $this->varActiveID); + $items = $this->loader->load($this->objModel, $stopLevels, $hardLevel, $activeId); $this->strNavigation = $this->renderer->render( $this->objModel, @@ -108,7 +102,7 @@ public function generate(): string array_keys($items->roots), $stopLevels, $hardLevel, - $this->varActiveID + $activeId ); return $this->strNavigation ? parent::generate() : ''; From 860e26c803415fba3814fb1c289e221df91393ac Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:20 +0200 Subject: [PATCH 25/75] Remove unused code --- src/FrontendModule/ModuleNavigationMenu.php | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 7dc2026..0db897e 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -53,8 +53,6 @@ final class ModuleNavigationMenu extends Module protected string $strNavigation = ''; - protected $arrGroups; // set of groups of the current user - private PageItemsLoader $loader; private NavigationRenderer $renderer; @@ -70,13 +68,6 @@ public function __construct($objModule, $strColumn = 'main') return; } - $this->import('Database'); - - if (FE_USER_LOGGED_IN) { - $this->import('FrontendUser', 'User'); - $this->User->groups && $this->arrGroups = $this->User->groups; - } - if (! strlen($this->navigationTpl)) { $this->navigationTpl = 'nav_default'; } @@ -133,7 +124,7 @@ public function getHardLevel() protected function compile(): void { - $this->Template->request = $this->getIndexFreeRequest(true); + $this->Template->request = $this->getIndexFreeRequest(); $this->Template->skipId = 'skipNavigation' . $this->id; $this->Template->items = $this->strNavigation; $this->hofff_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; From d81d6169d7a71e824aebad54d57241764b7979e3 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 26/75] Refactor query builder --- src/QueryBuilder/PageQueryBuilder.php | 190 ++++++++++++++------------ 1 file changed, 99 insertions(+), 91 deletions(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 8c8bed3..cab6bb6 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -63,33 +63,34 @@ public function __construct(Connection $connection, ModuleModel $moduleModel) public function createFetchItemsQuery(array $parentIds): QueryBuilder { - if (! isset($this->queries[__FUNCTION__])) { - $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder() - ->from('tl_page') - ->select(... $this->fields) - ->andWhere('type != :rootType') - ->setParameter('rootType', 'root') - ->andWhere('pid IN (:pids)') - ->orderBy('sorting'); - - $this - ->addHiddenCondition( - $this->queries[__FUNCTION__], - (bool) $this->moduleModel->hofff_navigation_showHidden, - (bool) $this->moduleModel->hofff_navigation_isSitemap - ) - ->addPublishedCondition($this->queries[__FUNCTION__]) - ->addErrorPagesCondition( - $this->queries[__FUNCTION__], - (bool) $this->moduleModel->hofff_navigation_showErrorPages - ) - ->addGuestsQueryParts( - $this->queries[__FUNCTION__], - (bool) $this->moduleModel->backboneit_navigation_showGuests - ); - } + $query = $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder + ->select(... $this->fields) + ->andWhere('type != :rootType') + ->setParameter('rootType', 'root') + ->andWhere('pid IN (:pids)') + ->orderBy('sorting'); + + $this + ->addHiddenCondition( + $queryBuilder, + (bool) $this->moduleModel->hofff_navigation_showHidden, + (bool) $this->moduleModel->hofff_navigation_isSitemap + ) + ->addPublishedCondition($queryBuilder) + ->addErrorPagesCondition( + $queryBuilder, + (bool) $this->moduleModel->hofff_navigation_showErrorPages + ) + ->addGuestsQueryParts( + $queryBuilder, + (bool) $this->moduleModel->backboneit_navigation_showGuests + ); + } + ); - $query = clone $this->queries[__FUNCTION__]; $query->setParameter('pids', $parentIds, Connection::PARAM_INT_ARRAY); return $query; @@ -97,29 +98,28 @@ public function createFetchItemsQuery(array $parentIds): QueryBuilder public function createRootIdsQuery(): QueryBuilder { - if (! isset($this->queries[__FUNCTION__])) { - $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); - $this->queries[__FUNCTION__] - ->select('id', 'pid', 'protected', 'groups') - ->from('tl_page'); - - $this - ->addHiddenCondition( - $this->queries[__FUNCTION__], - ! $this->moduleModel->hofff_navigation_respectHidden, - (bool) $this->moduleModel->hofff_navigation_isSitemap - ) - ->addGuestsQueryParts( - $this->queries[__FUNCTION__], - ! $this->moduleModel->hofff_navigation_respectGuests - ) - ->addPublishedCondition( - $this->queries[__FUNCTION__], - (bool) $this->moduleModel->hofff_navigation_respectPublish - ); - } - - return clone $this->queries[__FUNCTION__]; + return $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder + ->select('id', 'pid', 'protected', 'groups'); + + $this + ->addHiddenCondition( + $queryBuilder, + ! $this->moduleModel->hofff_navigation_respectHidden, + (bool) $this->moduleModel->hofff_navigation_isSitemap + ) + ->addGuestsQueryParts( + $queryBuilder, + ! $this->moduleModel->hofff_navigation_respectGuests + ) + ->addPublishedCondition( + $queryBuilder, + (bool) $this->moduleModel->hofff_navigation_respectPublish + ); + } + ); } public function createStartRootIdsQuery(): QueryBuilder @@ -128,41 +128,39 @@ public function createStartRootIdsQuery(): QueryBuilder return $this->createRootIdsQuery(); } - if (! isset($this->queries[__FUNCTION__])) { - $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); - - $this->queries[__FUNCTION__] - ->select('id', 'pid', 'protected', 'groups') - ->from('tl_page'); - - $this - ->addHiddenCondition( - $this->queries[__FUNCTION__], - (bool) $this->moduleModel->hofff_navigation_showHiddenStart, - (bool) $this->moduleModel->hofff_navigation_isSitemap - ) - ->addPublishedCondition($this->queries[__FUNCTION__]) - ->addErrorPagesCondition( - $this->queries[__FUNCTION__], - (bool) $this->moduleModel->hofff_navigation_showErrorPages - ) - ->addGuestsQueryParts($this->queries[__FUNCTION__], (bool) $this->moduleModel->hofff_navigation_showGuests); - } - - return clone $this->queries[__FUNCTION__]; + return $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder + ->select('id', 'pid', 'protected', 'groups'); + + $this + ->addHiddenCondition( + $queryBuilder, + (bool) $this->moduleModel->hofff_navigation_showHiddenStart, + (bool) $this->moduleModel->hofff_navigation_isSitemap + ) + ->addPublishedCondition($queryBuilder) + ->addErrorPagesCondition( + $queryBuilder, + (bool) $this->moduleModel->hofff_navigation_showErrorPages + ) + ->addGuestsQueryParts($queryBuilder, (bool) $this->moduleModel->hofff_navigation_showGuests); + } + ); } public function createPageInformationQuery(array $pageIds): QueryBuilder { - if (! isset($this->queries[__FUNCTION__])) { - $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); - $this->queries[__FUNCTION__] - ->select('id', 'pid', 'protected', 'groups') - ->from('tl_page') - ->where('id IN (:ids)'); - } + $query = $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder + ->select('id', 'pid', 'protected', 'groups') + ->where('id IN (:ids)'); + } + ); - $query = clone $this->queries[__FUNCTION__]; $query->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); return $query; @@ -170,15 +168,15 @@ public function createPageInformationQuery(array $pageIds): QueryBuilder public function createRootInformationQuery(array $rootIds): QueryBuilder { - if (! isset($this->queries[__FUNCTION__])) { - $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); - $this->queries[__FUNCTION__] + $query = $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder ->select(... $this->fields) - ->from('tl_page') ->where('id IN (:rootIds)'); - } + } + ); - $query = clone $this->queries[__FUNCTION__]; $query->setParameter('rootIds', $rootIds, Connection::PARAM_STR_ARRAY); return $query; @@ -186,15 +184,15 @@ public function createRootInformationQuery(array $rootIds): QueryBuilder public function createPreviousLevelQuery(array $pageIds): QueryBuilder { - if (! isset($this->queries[__FUNCTION__])) { - $this->queries[__FUNCTION__] = $this->connection->createQueryBuilder(); - $this->queries[__FUNCTION__] + $query = $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder ->select('id', 'pid') - ->from('tl_page') ->where('id IN (:ids)'); - } + } + ); - $query = clone $this->queries[__FUNCTION__]; $query->setParameter('ids', $pageIds); return $query; @@ -267,6 +265,16 @@ public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests return $this; } + private function query(string $name, callable $builder): QueryBuilder + { + if (! isset ($this->queries[$name])) { + $this->queries[$name] = $this->connection->createQueryBuilder()->from('tl_page'); + $builder($this->queries[$name]); + } + + return clone $this->queries[$name]; + } + private function determineFields(): void { $customFields = StringUtil::deserialize($this->moduleModel->hofff_navigation_addFields, true); From 517b7998370428054e3b394bbded34f07cfc9dd0 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 27/75] Replace deprecated logged in constants --- src/Items/PageItemsLoader.php | 7 +++---- src/QueryBuilder/PageQueryBuilder.php | 10 +++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index abfa980..d9e5906 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -60,7 +60,7 @@ public function load( $this->items = new PageItems(); $this->items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); - $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $moduleModel); + $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $this->security, $moduleModel); $this->moduleModel = $moduleModel; $this->stopLevels = $stopLevels; $this->hardLevel = $hardLevel; @@ -194,7 +194,7 @@ protected function calculateRootIDs(): array public function isPermissionCheckRequired(): bool { - return ! BE_USER_LOGGED_IN && ! $this->moduleModel->hofff_navigation_showProtected; + return ! $this->security->isGranted('ROLE_USER') && ! $this->moduleModel->hofff_navigation_showProtected; } /** @@ -215,9 +215,8 @@ public function isPermissionCheckRequired(): bool */ public function isPermissionGranted(ModuleModel $model, array $arrPage): bool { - // TODO: Replace with non deprecated check // be users have access everywhere - if (BE_USER_LOGGED_IN) { + if ($this->security->isGranted('ROLE_USER')) { return true; } diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index cab6bb6..e4f24cd 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; +use Symfony\Component\Security\Core\Security; use function array_flip; use function array_keys; use function array_merge; @@ -46,6 +47,8 @@ final class PageQueryBuilder private Connection $connection; + private Security $security; + private ModuleModel $moduleModel; private array $fields = []; @@ -53,10 +56,11 @@ final class PageQueryBuilder /** @var array */ private $queries = []; - public function __construct(Connection $connection, ModuleModel $moduleModel) + public function __construct(Connection $connection, Security $security, ModuleModel $moduleModel) { $this->connection = $connection; $this->moduleModel = $moduleModel; + $this->security = $security; $this->determineFields(); } @@ -200,7 +204,7 @@ function (QueryBuilder $queryBuilder): void { public function addPublishedCondition(QueryBuilder $queryBuilder, bool $respectPublished = true): self { - if (BE_USER_LOGGED_IN || ! $respectPublished) { + if (! $respectPublished || $this->security->isGranted('ROLE_USER')) { return $this; } @@ -258,7 +262,7 @@ public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests return $this; } - if (FE_USER_LOGGED_IN && ! BE_USER_LOGGED_IN) { + if ($this->security->isGranted('ROLE_MEMBER') && ! $this->security->isGranted('ROLE_USER')) { $queryBuilder->andWhere('guests != 1'); } From 766fa6ab4fca968ba8d0a6e48bb6c77f90bb5266 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 28/75] Fix redirect page calculation --- src/QueryBuilder/BaseQueryBuilder.php | 68 +++++++++ src/QueryBuilder/PageQueryBuilder.php | 58 +------- src/QueryBuilder/RedirectPageQueryBuilder.php | 54 +++++++ src/Renderer/NavigationRenderer.php | 132 +++++++----------- src/Resources/config/services.xml | 6 + 5 files changed, 182 insertions(+), 136 deletions(-) create mode 100644 src/QueryBuilder/BaseQueryBuilder.php create mode 100644 src/QueryBuilder/RedirectPageQueryBuilder.php diff --git a/src/QueryBuilder/BaseQueryBuilder.php b/src/QueryBuilder/BaseQueryBuilder.php new file mode 100644 index 0000000..d182297 --- /dev/null +++ b/src/QueryBuilder/BaseQueryBuilder.php @@ -0,0 +1,68 @@ + */ + private $queries = []; + + public function __construct(Connection $connection, Security $security) + { + $this->connection = $connection; + $this->security = $security; + } + + protected function query(string $name, callable $builder): QueryBuilder + { + if (! isset ($this->queries[$name])) { + $this->queries[$name] = $this->connection->createQueryBuilder()->from('tl_page'); + $builder($this->queries[$name]); + } + + return clone $this->queries[$name]; + } + + protected function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests = false): self + { + if ($showGuests) { + return $this; + } + + if ($this->security->isGranted('ROLE_MEMBER') && ! $this->security->isGranted('ROLE_USER')) { + $queryBuilder->andWhere('guests != 1'); + } + + return $this; + } + + protected function addPublishedCondition(QueryBuilder $queryBuilder, bool $respectPublished = true): self + { + if (! $respectPublished || $this->security->isGranted('ROLE_USER')) { + return $this; + } + + static $time; + if (! $time) { + $time = time(); + } + + $queryBuilder + ->andWhere('(start = \'\' OR start < :time) AND (stop = \'\' OR stop > :time) AND published = 1') + ->setParameter('time', $time); + + return $this; + } +} diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index e4f24cd..4258237 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -8,14 +8,13 @@ use Contao\StringUtil; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; - use Symfony\Component\Security\Core\Security; + use function array_flip; use function array_keys; use function array_merge; -use function time; -final class PageQueryBuilder +final class PageQueryBuilder extends BaseQueryBuilder { public const DEFAULT_FIELDS = [ 'id' => true, @@ -45,23 +44,15 @@ final class PageQueryBuilder 'error_410' ]; - private Connection $connection; - - private Security $security; - private ModuleModel $moduleModel; private array $fields = []; - /** @var array */ - private $queries = []; - public function __construct(Connection $connection, Security $security, ModuleModel $moduleModel) { - $this->connection = $connection; - $this->moduleModel = $moduleModel; - $this->security = $security; + parent::__construct($connection, $security); + $this->moduleModel = $moduleModel; $this->determineFields(); } @@ -202,24 +193,6 @@ function (QueryBuilder $queryBuilder): void { return $query; } - public function addPublishedCondition(QueryBuilder $queryBuilder, bool $respectPublished = true): self - { - if (! $respectPublished || $this->security->isGranted('ROLE_USER')) { - return $this; - } - - static $time; - if (! $time) { - $time = time(); - } - - $queryBuilder - ->andWhere('(start = \'\' OR start < :time) AND (stop = \'\' OR stop > :time) AND published = 1') - ->setParameter('time', $time); - - return $this; - } - /** * Adds the or hidden state of a page. * @@ -256,29 +229,6 @@ public function addErrorPagesCondition(QueryBuilder $queryBuilder, bool $showErr return $this; } - public function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests = false): self - { - if ($showGuests) { - return $this; - } - - if ($this->security->isGranted('ROLE_MEMBER') && ! $this->security->isGranted('ROLE_USER')) { - $queryBuilder->andWhere('guests != 1'); - } - - return $this; - } - - private function query(string $name, callable $builder): QueryBuilder - { - if (! isset ($this->queries[$name])) { - $this->queries[$name] = $this->connection->createQueryBuilder()->from('tl_page'); - $builder($this->queries[$name]); - } - - return clone $this->queries[$name]; - } - private function determineFields(): void { $customFields = StringUtil::deserialize($this->moduleModel->hofff_navigation_addFields, true); diff --git a/src/QueryBuilder/RedirectPageQueryBuilder.php b/src/QueryBuilder/RedirectPageQueryBuilder.php new file mode 100644 index 0000000..e476786 --- /dev/null +++ b/src/QueryBuilder/RedirectPageQueryBuilder.php @@ -0,0 +1,54 @@ +query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder + ->select('*') + ->where('id=:id') + ->setMaxResults(1); + + $this + ->addGuestsQueryParts($queryBuilder) + ->addPublishedCondition($queryBuilder); + } + ); + + $query->setParameter('id', $jumpToId); + + return $query; + } + + public function createFallbackQuery(int $fallbackSearchId): QueryBuilder + { + $query = $this->query( + __FUNCTION__, + function (QueryBuilder $queryBuilder): void { + $queryBuilder + ->select('*') + ->where('type=:type') + ->andWhere('pid=:pid') + ->setParameter('type', 'regular') + ->orderBy('sorting') + ->setMaxResults(1); + + $this + ->addGuestsQueryParts($queryBuilder); + } + ); + + $query->setParameter('pid', $fallbackSearchId); + + return $query; + } +} diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 4867bd3..488e494 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -14,9 +14,9 @@ use Hofff\Contao\Navigation\Items\PageItems; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; +use Hofff\Contao\Navigation\QueryBuilder\RedirectPageQueryBuilder; use function array_merge; use function array_shift; -use function dump; use function get_class; use function is_array; use function ltrim; @@ -33,11 +33,12 @@ final class NavigationRenderer { private Connection $connection; - private ?PageQueryBuilder $pageQueryBuilder; + private RedirectPageQueryBuilder $redirectPageQueryBuilder; - public function __construct(Connection $connection) + public function __construct(Connection $connection, RedirectPageQueryBuilder $redirectPageQueryBuilder) { - $this->connection = $connection; + $this->connection = $connection; + $this->redirectPageQueryBuilder = $redirectPageQueryBuilder; } /** @@ -71,8 +72,6 @@ public function render( $itemIds = $this->executeMenuHook($moduleModel, $itemIds); $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); - \dump($firstIds); - if ($moduleModel->hofff_navigation_hideSingleLevel) { foreach ($firstIds as $id) { if ($items->subItems[$id]) { @@ -106,89 +105,89 @@ private function renderTree( return ''; } - $intStop = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; - $arrItems = []; + $intStop = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; + $renderedItems = []; - foreach ($itemIds as $varID) { - if (! isset($items->items[$varID])) { + foreach ($itemIds as $itemId) { + if (! isset($items->items[$itemId])) { continue; } - $arrItem = $items->items[$varID]; + $item = $items->items[$itemId]; - if ($varID == $activeId) { + if ($itemId == $activeId) { $blnContainsActive = true; - if ($arrItem['href'] === Environment::get('request')) { - $arrItem['isActive'] = true; // nothing else (active class is set in template) - $arrItem['isInTrail'] = false; + if ($item['href'] === Environment::get('request')) { + $item['isActive'] = true; // nothing else (active class is set in template) + $item['isInTrail'] = false; } else { - $arrItem['isActive'] = false; // nothing else (active class is set in template) - $arrItem['isInTrail'] = true; + $item['isActive'] = false; // nothing else (active class is set in template) + $item['isInTrail'] = true; } } else { // do not flatten if/else - if ($arrItem['tid'] == $activeId) { - if ($arrItem['href'] === Environment::get('request')) { - $arrItem['isActive'] = true; // nothing else (active class is set in template) - $arrItem['isInTrail'] = false; + if ($item['tid'] == $activeId) { + if ($item['href'] === Environment::get('request')) { + $item['isActive'] = true; // nothing else (active class is set in template) + $item['isInTrail'] = false; } else { - $arrItem['isActive'] = false; // nothing else (active class is set in template) - $arrItem['isInTrail'] = true; + $item['isActive'] = false; // nothing else (active class is set in template) + $item['isInTrail'] = true; } } } - if ($arrItem['isInTrail']) { - $arrItem['class'] .= ' trail'; + if ($item['isInTrail']) { + $item['class'] .= ' trail'; } - if (! isset($items->subItems[$varID])) { - $arrItem['class'] .= ' leaf'; + if (! isset($items->subItems[$itemId])) { + $item['class'] .= ' leaf'; } elseif ($currentLevel >= $intHard) { // we are at hard level, never draw submenu - $arrItem['class'] .= ' submenu leaf'; - } elseif ($currentLevel >= $intStop && ! $arrItem['isInTrail'] && $varID !== $activeId && $arrItem['tid'] != $activeId) { + $item['class'] .= ' submenu leaf'; + } elseif ($currentLevel >= $intStop && ! $item['isInTrail'] && $itemId !== $activeId && $item['tid'] != $activeId) { // we are at stop level and not trail and not active, never draw submenu - $arrItem['class'] .= ' submenu leaf'; - } elseif ($items->subItems[$varID]) { - $arrItem['class'] .= ' submenu inner'; - $arrItem['subitems'] = $this->renderTree( + $item['class'] .= ' submenu leaf'; + } elseif ($items->subItems[$itemId]) { + $item['class'] .= ' submenu inner'; + $item['subitems'] = $this->renderTree( $moduleModel, $items, - $items->subItems[$varID] ?? [], + $items->subItems[$itemId] ?? [], $stopLimit, $intHard, $currentLevel + 1 ); } else { // should never be reached, if no hooks are used - $arrItem['class'] .= ' leaf'; + $item['class'] .= ' leaf'; } - $arrItems[] = $arrItem; + $renderedItems[] = $item; } if ($blnContainsActive) { - foreach ($arrItems as &$arrItem) { - if (! $arrItem['isActive']) { - $arrItem['class'] .= ' sibling'; + foreach ($renderedItems as &$item) { + if (! $item['isActive']) { + $item['class'] .= ' sibling'; } } - unset($arrItem); + unset($item); } - $arrItems[0]['class'] .= ' first'; - $arrItems[count($arrItems) - 1]['class'] .= ' last'; + $renderedItems[0]['class'] .= ' first'; + $renderedItems[count($renderedItems) - 1]['class'] .= ' last'; - foreach ($arrItems as &$arrItem) { - $arrItem['class'] = ltrim($arrItem['class']); + foreach ($renderedItems as &$item) { + $item['class'] = ltrim($item['class']); } - unset($arrItem); + unset($item); $objTemplate = new FrontendTemplate($moduleModel->navigationTpl ?: 'nav_hofff'); $objTemplate->setData([ 'module' => $moduleModel->row(), 'level' => 'level_' . $currentLevel, - 'items' => $arrItems, + 'items' => $renderedItems, 'type' => get_class($this), ]); @@ -224,7 +223,7 @@ public function compileNavigationItem( PageItems $items, array $page, bool $forwardResolution = true - ) { + ): array { // fallback for dataset field collisions $page['_title'] = $page['title']; $page['_pageTitle'] = $page['pageTitle']; @@ -405,47 +404,17 @@ protected function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $ private function getRedirectPage(array $arrPage): array { - static $jumpToQuery = null; - static $jumpToFallbackQuery = null; - - if ($jumpToQuery === null) { - $jumpToQuery = $this->connection->createQueryBuilder() - ->select('*') - ->from('tl_page') - ->where('id=:id') - ->setMaxResults(1); - - $this->pageQueryBuilder - ->addGuestsQueryParts($jumpToQuery) - ->addPublishedCondition($jumpToQuery); - } - - if ($jumpToFallbackQuery === null) { - $jumpToFallbackQuery = $this->connection->createQueryBuilder() - ->select('*') - ->from('tl_page') - ->where('type=:type') - ->andWhere('pid=:pid') - ->setParameter('type', 'regular') - ->orderBy('sorting') - ->setMaxResults(1); - - $this->pageQueryBuilder - ->addGuestsQueryParts($jumpToFallbackQuery); - } - if ($arrPage['jumpTo']) { $intFallbackSearchID = $arrPage['id']; $intJumpToID = $arrPage['jumpTo']; do { - $query = clone $jumpToQuery; + $query = $this->redirectPageQueryBuilder->createJumpToQuery((int) $intJumpToID); $query->setParameter('id', $intJumpToID); $result = $query->execute(); $next = $result->fetchAssociative(); if (! $result->rowCount()) { - $query = clone $jumpToFallbackQuery; - $query->setParameter('pid', $intFallbackSearchID); + $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $intFallbackSearchID); $next = $query->execute()->fetchAssociative(); break; } @@ -454,9 +423,8 @@ private function getRedirectPage(array $arrPage): array $intJumpToID = $next['jumpTo'] ?? 0; } while ($next['type'] === 'forward'); } else { - $query = clone $jumpToFallbackQuery; - $query->setParameter('pid', $arrPage['id']); - $next = $query->execute()->fetchAssociative(); + $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $arrPage['id']); + $next = $query->execute()->fetchAssociative(); } return $next; diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index d5ec72d..ed7b0c1 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -23,6 +23,12 @@ + + + + + + From 7998a1da62ccf061a57454d02eb041f32d565444 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 29/75] Use events insteadof hooks --- src/Event/Event.php | 23 +++++++++++ src/Event/ItemEvent.php | 29 +++++++++++++ src/Event/MenuEvent.php | 29 +++++++++++++ src/Event/TreeEvent.php | 25 +++++++++++ src/Renderer/NavigationRenderer.php | 64 ++++++++++++----------------- src/Resources/config/services.xml | 2 +- 6 files changed, 133 insertions(+), 39 deletions(-) create mode 100644 src/Event/Event.php create mode 100644 src/Event/ItemEvent.php create mode 100644 src/Event/MenuEvent.php create mode 100644 src/Event/TreeEvent.php diff --git a/src/Event/Event.php b/src/Event/Event.php new file mode 100644 index 0000000..4cb1956 --- /dev/null +++ b/src/Event/Event.php @@ -0,0 +1,23 @@ +moduleModel = $moduleModel; + } + + public function moduleModel(): ModuleModel + { + return $this->moduleModel; + } +} diff --git a/src/Event/ItemEvent.php b/src/Event/ItemEvent.php new file mode 100644 index 0000000..fcaf931 --- /dev/null +++ b/src/Event/ItemEvent.php @@ -0,0 +1,29 @@ +item = $item; + } + + public function changeItem(array $item): void + { + $this->item = $item; + } + + public function item(): array + { + return $this->item; + } +} diff --git a/src/Event/MenuEvent.php b/src/Event/MenuEvent.php new file mode 100644 index 0000000..b9e7284 --- /dev/null +++ b/src/Event/MenuEvent.php @@ -0,0 +1,29 @@ +rootIds = $rootIds; + } + + public function changeRootIds(array $rootIds): void + { + $this->rootIds = $rootIds; + } + + public function rootIds(): array + { + return $this->rootIds; + } +} diff --git a/src/Event/TreeEvent.php b/src/Event/TreeEvent.php new file mode 100644 index 0000000..827a247 --- /dev/null +++ b/src/Event/TreeEvent.php @@ -0,0 +1,25 @@ +items = $items; + } + + public function items(): PageItems + { + return $this->items; + } +} diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 488e494..c517f3a 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -9,16 +9,17 @@ use Contao\ModuleModel; use Contao\PageModel; use Contao\StringUtil; -use Contao\System; use Doctrine\DBAL\Connection; +use Hofff\Contao\Navigation\Event\ItemEvent; +use Hofff\Contao\Navigation\Event\MenuEvent; +use Hofff\Contao\Navigation\Event\TreeEvent; use Hofff\Contao\Navigation\Items\PageItems; -use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; - use Hofff\Contao\Navigation\QueryBuilder\RedirectPageQueryBuilder; +use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; + use function array_merge; use function array_shift; use function get_class; -use function is_array; use function ltrim; use function preg_replace; use function str_replace; @@ -31,14 +32,16 @@ final class NavigationRenderer { - private Connection $connection; - private RedirectPageQueryBuilder $redirectPageQueryBuilder; - public function __construct(Connection $connection, RedirectPageQueryBuilder $redirectPageQueryBuilder) - { - $this->connection = $connection; + private EventDispatcherInterface $eventDispatcher; + + public function __construct( + EventDispatcherInterface $eventDispatcher, + RedirectPageQueryBuilder $redirectPageQueryBuilder + ) { $this->redirectPageQueryBuilder = $redirectPageQueryBuilder; + $this->eventDispatcher = $eventDispatcher; } /** @@ -69,7 +72,7 @@ public function render( $this->compileTree($moduleModel, $items); $this->executeTreeHook($moduleModel, $items); - $itemIds = $this->executeMenuHook($moduleModel, $itemIds); + $itemIds = $this->dispatchMenuEvent($moduleModel, $itemIds); $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); if ($moduleModel->hofff_navigation_hideSingleLevel) { @@ -284,9 +287,7 @@ public function compileNavigationItem( break; } - $this->executeItemHook($moduleModel, $page); - - return $page; + return $this->dispatchItemEvent($moduleModel, $page); } private function generatePageUrl(array $arrPage): ?string @@ -318,16 +319,16 @@ public function encodeEmailURL(string $strHref): string return StringUtil::encodeEmail($strHref); } - protected function executeItemHook(ModuleModel $moduleModel, array &$arrPage): void + protected function dispatchItemEvent(ModuleModel $moduleModel, array $arrPage): array { if (! $moduleModel->hofff_navigation_disableHooks) { - return; + return $arrPage; } - foreach ((array) ($GLOBALS['TL_HOOKS']['hofff_navigation_item'] ?? []) as $arrCallback) { - $arrCallback[0] = System::importStatic($arrCallback[0]); - $arrCallback[0]->{$arrCallback[1]}($moduleModel, $arrPage); - } + $event = new ItemEvent($moduleModel, $arrPage); + $this->eventDispatcher->dispatch($event); + + return $event->item(); } /** @@ -345,10 +346,7 @@ protected function executeTreeHook(ModuleModel $moduleModel, PageItems $items, $ return; } - foreach ((array) $GLOBALS['TL_HOOKS']['hofff_navigation_tree'] as $arrCallback) { - $arrCallback[0] = System::importStatic($arrCallback[0]); - $arrCallback[0]->{$arrCallback[1]}($moduleModel, $items); - } + $this->eventDispatcher->dispatch(new TreeEvent($moduleModel, $items)); } /** @@ -363,26 +361,16 @@ protected function executeTreeHook(ModuleModel $moduleModel, PageItems $items, $ * * @return array $arrRootIDs The root pages after hook execution */ - protected function executeMenuHook(ModuleModel $moduleModel, array $arrRootIDs, $blnForce = false) + protected function dispatchMenuEvent(ModuleModel $moduleModel, array $arrRootIDs): array { - if (! $blnForce && $moduleModel->hofff_navigation_disableHooks) { - return $arrRootIDs; - } - - if (! is_array($GLOBALS['TL_HOOKS']['hofff_navigation_menu'])) { + if ($moduleModel->hofff_navigation_disableHooks) { return $arrRootIDs; } - foreach ($GLOBALS['TL_HOOKS']['hofff_navigation_menu'] as $arrCallback) { - $arrCallback[0] = System::importStatic($arrCallback[0]); - $arrNewRoots = $this->{$arrCallback[0]}->{$arrCallback[1]}($moduleModel, $arrRootIDs); - - if ($arrNewRoots !== null) { - $arrRootIDs = $arrNewRoots; - } - } + $event = new MenuEvent($moduleModel, $arrRootIDs); + $this->eventDispatcher->dispatch($event); - return $arrRootIDs; + return $event->rootIds(); } protected function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $arrRootIDs): array diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index ed7b0c1..b34bd25 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -22,7 +22,7 @@ - + From 997e1eb5ce39a6e764936105c512af9bfc0ee4c3 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 30/75] Rewrite the navigation module as fragment --- src/FrontendModule/ModuleNavigationMenu.php | 127 ++++++++------------ src/Resources/config/services.xml | 5 + src/Resources/contao/config/config.php | 5 - 3 files changed, 53 insertions(+), 84 deletions(-) delete mode 100644 src/Resources/contao/config/config.php diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 0db897e..5f39d33 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -2,16 +2,19 @@ namespace Hofff\Contao\Navigation\FrontendModule; -use Contao\BackendTemplate; -use Contao\Module; -use Contao\System; +use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController; +use Contao\CoreBundle\ServiceAnnotation\FrontendModule; +use Contao\Environment; +use Contao\Input; +use Contao\ModuleModel; +use Contao\Template; use Hofff\Contao\Navigation\Items\PageItemsLoader; use Hofff\Contao\Navigation\Renderer\NavigationRenderer; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use function array_keys; -use function strlen; -use const TL_MODE; /** * Navigation modules @@ -19,23 +22,23 @@ * Navigation item array layout: * Before rendering: * id => the ID of the current item (optional) - * isInTrail => whether this item is in the trail path - * class => CSS classes - * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities - * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities - * link => page name (with Insert-Tags and XML specialchars NOT replaced; as stored in the db) - * href => URL of target page - * nofollow => true, if nofollow should be set on rel attribute + * isInTrail => whether this item is in the trail path + * class => CSS classes + * title => page name with Insert-Tags stripped and XML specialchars replaced by their entities + * pageTitle => page title with Insert-Tags stripped and XML specialchars replaced by their entities + * link => page name (with Insert-Tags and XML specialchars NOT replaced; as stored in the db) + * href => URL of target page + * nofollow => true, if nofollow should be set on rel attribute * target => either ' onclick="window.open(this.href); return false;"' or empty string - * description => page description with line breaks (\r and \n) replaced by whitespaces + * description => page description with line breaks (\r and \n) replaced by whitespaces * * Calculated while rendering: - * subitems => subnavigation as HTML string or empty string (rendered if subpages & items setup correctly) - * isActive => whether this item is the current active navigation item + * subitems => subnavigation as HTML string or empty string (rendered if subpages & items setup correctly) + * isActive => whether this item is the current active navigation item * * Following CSS classes are calculated while rendering: level_x, trail, sibling, submenu, first, last * - * Additionally all page dataset values from the database are available unter their field name, + * Additionally, all page dataset values from the database are available unter their field name, * if the field name does not collide with the listed keys. * * For the collisions of the Contao core page dataset fields the following keys are available: @@ -46,49 +49,33 @@ * _description * * @author Oliver Hoff + * + * @FrontendModule("hofff_navigation_menu", category="navigation") */ -final class ModuleNavigationMenu extends Module +final class ModuleNavigationMenu extends AbstractFrontendModuleController { - protected $strTemplate = 'mod_hofff_navigation_menu'; - - protected string $strNavigation = ''; - private PageItemsLoader $loader; private NavigationRenderer $renderer; - public function __construct($objModule, $strColumn = 'main') + public function __construct(PageItemsLoader $loader, NavigationRenderer $renderer) { - parent::__construct($objModule, $strColumn); - - $this->loader = System::getContainer()->get(PageItemsLoader::class); - $this->renderer = System::getContainer()->get(NavigationRenderer::class); - - if (TL_MODE === 'BE') { - return; - } - - if (! strlen($this->navigationTpl)) { - $this->navigationTpl = 'nav_default'; - } + $this->loader = $loader; + $this->renderer = $renderer; } - public function generate(): string + protected function getResponse(Template $template, ModuleModel $model, Request $request): ?Response { - if (TL_MODE === 'BE') { - return $this->generateBE('NAVIGATION MENU'); - } - - $stopLevels = $this->getStopLevels(); - $hardLevel = $this->getHardLevel(); - $activeId = $this->hofff_navigation_isSitemap || $this->Input->get('articles') + $stopLevels = $this->getStopLevels($model); + $hardLevel = $this->getHardLevel($model); + $activeId = $model->hofff_navigation_isSitemap || Input::get('articles') ? null : (int) $GLOBALS['objPage']->id; - $items = $this->loader->load($this->objModel, $stopLevels, $hardLevel, $activeId); + $items = $this->loader->load($model, $stopLevels, $hardLevel, $activeId); - $this->strNavigation = $this->renderer->render( - $this->objModel, + $navigation = $this->renderer->render( + $model, $items, array_keys($items->roots), $stopLevels, @@ -96,19 +83,29 @@ public function generate(): string $activeId ); - return $this->strNavigation ? parent::generate() : ''; + if ($navigation === '') { + return new Response(); + } + + $template->items = $navigation; + $template->request = Environment::get('indexFreeRequest'); + $template->skipId = 'skipNavigation' . $model->id; + $template->items = $navigation; + $template->legacyClass = $model->hofff_navigation_addLegacyCss ? ' mod_navigation' : ''; + + return $template->getResponse(); } - public function getStopLevels(): array + public function getStopLevels(ModuleModel $model): array { - if (! $this->hofff_navigation_defineStop) { + if (! $model->hofff_navigation_defineStop) { return [PHP_INT_MAX]; } $minLevel = -1; $stopLevel = []; - foreach (array_map('intval', explode(',', $this->hofff_navigation_stop)) as $level) { + foreach (array_map('intval', explode(',', $model->hofff_navigation_stop)) as $level) { if ($level > $minLevel) { $stopLevel[] = $minLevel = $level; } @@ -117,36 +114,8 @@ public function getStopLevels(): array return $stopLevel ?: [PHP_INT_MAX]; } - public function getHardLevel() - { - return $this->hofff_navigation_defineHard ? $this->hofff_navigation_hard : PHP_INT_MAX; - } - - protected function compile(): void + public function getHardLevel(ModuleModel $model): int { - $this->Template->request = $this->getIndexFreeRequest(); - $this->Template->skipId = 'skipNavigation' . $this->id; - $this->Template->items = $this->strNavigation; - $this->hofff_navigation_addLegacyCss && $this->Template->legacyClass = ' mod_navigation'; - } - - /** - * A helper method to generate BE wildcard. - * - * @param string $strBEType (optional, defaults to "NAVIGATION") The type to be displayed in the wildcard - * - * @return string The wildcard HTML string - */ - protected function generateBE($strBEType = 'NAVIGATION'): string - { - $objTemplate = new BackendTemplate('be_wildcard'); - - $objTemplate->wildcard = '### ' . $strBEType . ' ###'; - $objTemplate->title = $this->headline; - $objTemplate->id = $this->id; - $objTemplate->link = $this->name; - $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; - - return $objTemplate->parse(); + return $model->hofff_navigation_defineHard ? (int) $model->hofff_navigation_hard : PHP_INT_MAX; } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index b34bd25..8277f5c 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -30,5 +30,10 @@ + + + + + diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php deleted file mode 100644 index b5ac27d..0000000 --- a/src/Resources/contao/config/config.php +++ /dev/null @@ -1,5 +0,0 @@ - Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 31/75] Enable replacement and migration again --- composer.json | 4 ++++ src/ContaoManager/Plugin.php | 2 +- src/Migration/BackboneNavigationMigration.php | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 447bdbf..5e7268a 100644 --- a/composer.json +++ b/composer.json @@ -48,6 +48,10 @@ "dev-develop": "2.0.x" } }, + "replace": { + "contao-legacy/backboneit_navigation": "self.version", + "backboneit/contao-navigation": "self.version" + }, "autoload": { "psr-4": { "Hofff\\Contao\\Navigation\\": "src/" diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 6add8c4..cb366dc 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -18,7 +18,7 @@ public function getBundles(ParserInterface $parser): array return [ BundleConfig::create(HofffContaoNavigationBundle::class) ->setLoadAfter([ContaoCoreBundle::class]) -// ->setReplace(['backboneit_navigation']), + ->setReplace(['backboneit_navigation']), ]; } } diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 2fa0664..1ceefef 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -49,7 +49,6 @@ public function __construct(Connection $connection) public function shouldRun(): bool { - return false; if ($this->hasBackboneItNavigationModules()) { return true; } From 6b928d8d1231a682231a4f128d884084263b7581 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:21 +0200 Subject: [PATCH 32/75] Restrict method visibility --- src/QueryBuilder/PageQueryBuilder.php | 5 ++--- src/Renderer/NavigationRenderer.php | 18 +++++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 4258237..d7226fb 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -41,7 +41,6 @@ final class PageQueryBuilder extends BaseQueryBuilder 'error_401', 'error_403', 'error_404', - 'error_410' ]; private ModuleModel $moduleModel; @@ -198,7 +197,7 @@ function (QueryBuilder $queryBuilder): void { * * @return self */ - public function addHiddenCondition( + private function addHiddenCondition( QueryBuilder $queryBuilder, bool $showHidden = false, bool $sitemap = false @@ -218,7 +217,7 @@ public function addHiddenCondition( return $this; } - public function addErrorPagesCondition(QueryBuilder $queryBuilder, bool $showErrorPages): self + private function addErrorPagesCondition(QueryBuilder $queryBuilder, bool $showErrorPages): self { if (! $showErrorPages) { $queryBuilder diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index c517f3a..551d298 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -70,7 +70,7 @@ public function render( } $this->compileTree($moduleModel, $items); - $this->executeTreeHook($moduleModel, $items); + $this->dispatchTreeEvent($moduleModel, $items); $itemIds = $this->dispatchMenuEvent($moduleModel, $itemIds); $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); @@ -197,7 +197,7 @@ private function renderTree( return $objTemplate->parse(); } - public function compileTree(ModuleModel $moduleModel, PageItems $items): void + private function compileTree(ModuleModel $moduleModel, PageItems $items): void { $blnForwardResolution = ! $moduleModel->hofff_navigation_noForwardResolution; foreach ($items->items as $itemId => $item) { @@ -221,7 +221,7 @@ public function compileTree(ModuleModel $moduleModel, PageItems $items): void * * @return array The compiled navigation item array */ - public function compileNavigationItem( + private function compileNavigationItem( ModuleModel $moduleModel, PageItems $items, array $page, @@ -310,7 +310,7 @@ private function generatePageUrl(array $arrPage): ?string * * @return string The modified URL */ - public function encodeEmailURL(string $strHref): string + private function encodeEmailURL(string $strHref): string { if (strncasecmp($strHref, 'mailto:', 7) !== 0) { return $strHref; @@ -319,7 +319,7 @@ public function encodeEmailURL(string $strHref): string return StringUtil::encodeEmail($strHref); } - protected function dispatchItemEvent(ModuleModel $moduleModel, array $arrPage): array + private function dispatchItemEvent(ModuleModel $moduleModel, array $arrPage): array { if (! $moduleModel->hofff_navigation_disableHooks) { return $arrPage; @@ -340,9 +340,9 @@ protected function dispatchItemEvent(ModuleModel $moduleModel, array $arrPage): * * @return void */ - protected function executeTreeHook(ModuleModel $moduleModel, PageItems $items, $blnForce = false): void + private function dispatchTreeEvent(ModuleModel $moduleModel, PageItems $items): void { - if (! $blnForce && ! $moduleModel->hofff_navigation_disableHooks) { + if (! $moduleModel->hofff_navigation_disableHooks) { return; } @@ -361,7 +361,7 @@ protected function executeTreeHook(ModuleModel $moduleModel, PageItems $items, $ * * @return array $arrRootIDs The root pages after hook execution */ - protected function dispatchMenuEvent(ModuleModel $moduleModel, array $arrRootIDs): array + private function dispatchMenuEvent(ModuleModel $moduleModel, array $arrRootIDs): array { if ($moduleModel->hofff_navigation_disableHooks) { return $arrRootIDs; @@ -373,7 +373,7 @@ protected function dispatchMenuEvent(ModuleModel $moduleModel, array $arrRootIDs return $event->rootIds(); } - protected function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $arrRootIDs): array + private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $arrRootIDs): array { if ($moduleModel->hofff_navigation_includeStart) { return $arrRootIDs; From 094c352b1773b34343a8a0b617e0668fa18978c1 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:22 +0200 Subject: [PATCH 33/75] Use nav_default as default template and modernize mod_hofff_navigation_menu template --- src/Renderer/NavigationRenderer.php | 73 ++++++++++--------- .../templates/mod_hofff_navigation_menu.html5 | 13 +--- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 551d298..a82d1a3 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -9,7 +9,6 @@ use Contao\ModuleModel; use Contao\PageModel; use Contao\StringUtil; -use Doctrine\DBAL\Connection; use Hofff\Contao\Navigation\Event\ItemEvent; use Hofff\Contao\Navigation\Event\MenuEvent; use Hofff\Contao\Navigation\Event\TreeEvent; @@ -108,8 +107,9 @@ private function renderTree( return ''; } - $intStop = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; - $renderedItems = []; + $intStop = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; + $renderedItems = []; + $containsActive = false; foreach ($itemIds as $itemId) { if (! isset($items->items[$itemId])) { @@ -119,7 +119,7 @@ private function renderTree( $item = $items->items[$itemId]; if ($itemId == $activeId) { - $blnContainsActive = true; + $containsActive = true; if ($item['href'] === Environment::get('request')) { $item['isActive'] = true; // nothing else (active class is set in template) @@ -169,7 +169,7 @@ private function renderTree( $renderedItems[] = $item; } - if ($blnContainsActive) { + if ($containsActive) { foreach ($renderedItems as &$item) { if (! $item['isActive']) { $item['class'] .= ' sibling'; @@ -186,7 +186,7 @@ private function renderTree( } unset($item); - $objTemplate = new FrontendTemplate($moduleModel->navigationTpl ?: 'nav_hofff'); + $objTemplate = new FrontendTemplate($moduleModel->navigationTpl ?: 'nav_default'); $objTemplate->setData([ 'module' => $moduleModel->row(), 'level' => 'level_' . $currentLevel, @@ -306,26 +306,26 @@ private function generatePageUrl(array $arrPage): ?string * If the given URL starts with "mailto:", the E-Mail is encoded, * otherwise nothing is done. * - * @param string $strHref The URL to check and possibly encode + * @param string $href The URL to check and possibly encode * * @return string The modified URL */ - private function encodeEmailURL(string $strHref): string + private function encodeEmailURL(string $href): string { - if (strncasecmp($strHref, 'mailto:', 7) !== 0) { - return $strHref; + if (strncasecmp($href, 'mailto:', 7) !== 0) { + return $href; } - return StringUtil::encodeEmail($strHref); + return StringUtil::encodeEmail($href); } - private function dispatchItemEvent(ModuleModel $moduleModel, array $arrPage): array + private function dispatchItemEvent(ModuleModel $moduleModel, array $page): array { if (! $moduleModel->hofff_navigation_disableHooks) { - return $arrPage; + return $page; } - $event = new ItemEvent($moduleModel, $arrPage); + $event = new ItemEvent($moduleModel, $page); $this->eventDispatcher->dispatch($event); return $event->item(); @@ -383,38 +383,39 @@ private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $it $arrFirstIDs = []; foreach ($arrRootIDs as $varRootID) { if (isset($items->subItems[$varRootID])) { - $arrFirstIDs = array_merge($arrFirstIDs, $items->subItems[$varRootID]); + $arrFirstIDs[] = $items->subItems[$varRootID]; } } - return $arrFirstIDs; + return array_merge(... $arrFirstIDs); } private function getRedirectPage(array $arrPage): array { - if ($arrPage['jumpTo']) { - $intFallbackSearchID = $arrPage['id']; - $intJumpToID = $arrPage['jumpTo']; - do { - $query = $this->redirectPageQueryBuilder->createJumpToQuery((int) $intJumpToID); - $query->setParameter('id', $intJumpToID); - $result = $query->execute(); - $next = $result->fetchAssociative(); - - if (! $result->rowCount()) { - $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $intFallbackSearchID); - $next = $query->execute()->fetchAssociative(); - break; - } - - $intFallbackSearchID = $intJumpToID; - $intJumpToID = $next['jumpTo'] ?? 0; - } while ($next['type'] === 'forward'); - } else { + if (! $arrPage['jumpTo']) { $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $arrPage['id']); - $next = $query->execute()->fetchAssociative(); + + return $query->execute()->fetchAssociative(); } + $intFallbackSearchID = $arrPage['id']; + $intJumpToID = $arrPage['jumpTo']; + do { + $query = $this->redirectPageQueryBuilder->createJumpToQuery((int) $intJumpToID); + $query->setParameter('id', $intJumpToID); + $result = $query->execute(); + $next = $result->fetchAssociative(); + + if (! $result->rowCount()) { + $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $intFallbackSearchID); + $next = $query->execute()->fetchAssociative(); + break; + } + + $intFallbackSearchID = $intJumpToID; + $intJumpToID = $next['jumpTo'] ?? 0; + } while ($next['type'] === 'forward'); + return $next; } } diff --git a/src/Resources/contao/templates/mod_hofff_navigation_menu.html5 b/src/Resources/contao/templates/mod_hofff_navigation_menu.html5 index a18196a..bde1033 100644 --- a/src/Resources/contao/templates/mod_hofff_navigation_menu.html5 +++ b/src/Resources/contao/templates/mod_hofff_navigation_menu.html5 @@ -1,13 +1,8 @@ - -

- From 6fa505bf3038106b243bcebce8fa139d1b49f57a Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:22 +0200 Subject: [PATCH 34/75] Improve field labels Include field name as well --- .../Dca/NavigationDcaListener.php | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index 3da3dc6..3852e9e 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -5,7 +5,6 @@ use Contao\Controller; use Contao\CoreBundle\Framework\ContaoFramework; use Contao\CoreBundle\ServiceAnnotation\Callback; -use Hofff\Contao\Navigation\FrontendModule\ModuleNavigationMenu; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; class NavigationDcaListener @@ -30,9 +29,9 @@ public function getPageFields(): array $fields = []; - foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $strField => $arrConfig) { - if (! isset(PageQueryBuilder::DEFAULT_FIELDS[$strField])) { - $fields[$strField] = &$arrConfig['label'][0]; + foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $fieldName => &$config) { + if (! isset(PageQueryBuilder::DEFAULT_FIELDS[$fieldName])) { + $fields[$fieldName] = sprintf('%s [%s]', $config['label'][0], $fieldName); } } @@ -40,18 +39,16 @@ public function getPageFields(): array } /** - * @param mixed $value - * * @Callback(table="tl_module", target="fields.hofff_navigation_stop.save") */ - public function saveStop($value): string + public function saveStop(string $value): string { - $intMin = -1; - $stop = []; + $minimum = -1; + $stop = []; foreach (array_map('intval', explode(',', (string) $value)) as $intLevel) { - if ($intLevel > $intMin) { - $stop[] = $intMin = $intLevel; + if ($intLevel > $minimum) { + $stop[] = $minimum = $intLevel; } } From 6c5be1a95235ef57302cea52f62e99f736b4fab1 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 35/75] Rename disableHooks to disableEvents --- src/Migration/BackboneNavigationMigration.php | 30 +++++++++++-------- src/Resources/contao/dca/tl_module.php | 4 +-- .../contao/languages/de/tl_module.php | 6 ++-- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 1ceefef..2494108 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -7,6 +7,7 @@ use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; +use function is_int; final class BackboneNavigationMigration extends AbstractMigration { @@ -16,6 +17,7 @@ final class BackboneNavigationMigration extends AbstractMigration private const NEW_PREFIX = 'hofff_navigation_'; + /** @var array */ private const FIELDS = [ 'roots_order', 'start', @@ -30,7 +32,7 @@ final class BackboneNavigationMigration extends AbstractMigration 'addFields', 'noForwardResolution', 'showErrorPages', - 'disableHooks', + 'disableHooks' => 'disableEvents', 'currentAsRoot', 'defineRoots', 'defineStop', @@ -53,9 +55,7 @@ public function shouldRun(): bool return true; } - $affectedFields = $this->determineAffectedFields(); - - return $affectedFields !== []; + return $this->determineAffectedFields() !== []; } public function run(): MigrationResult @@ -63,8 +63,8 @@ public function run(): MigrationResult $this->renameNavigationModules(); $affectedFields = $this->determineAffectedFields(); - foreach ($affectedFields as $field) { - $this->renameField($field); + foreach ($affectedFields as $oldName => $newName) { + $this->renameField($oldName, $newName); } return $this->createResult(true); @@ -89,32 +89,36 @@ private function renameNavigationModules(): void ); } - /** @return list */ + /** @return array */ private function determineAffectedFields(): array { $table = $this->connection->getSchemaManager()->listTableDetails('tl_module'); $fields = []; - foreach (self::FIELDS as $field) { - if (! $table->hasColumn(self::OLD_PREFIX . $field) || $table->hasColumn(self::NEW_PREFIX . $field)) { + foreach (self::FIELDS as $oldName => $newName) { + if (is_int($oldName)) { + $oldName = $newName; + } + + if (! $table->hasColumn(self::OLD_PREFIX . $oldName) || $table->hasColumn(self::NEW_PREFIX . $newName)) { continue; } - $fields[] = $field; + $fields[$oldName] = $newName; } return $fields; } - private function renameField(string $field): void + private function renameField(string $oldName, string $newName): void { $this->connection->executeStatement( sprintf( 'ALTER TABLE tl_module RENAME COLUMN %s%s TO %s%s', self::OLD_PREFIX, - $field, + $oldName, self::NEW_PREFIX, - $field, + $newName, ) ); } diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 3ed7ac5..a8b37da 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -26,7 +26,7 @@ . 'hofff_navigation_addFields;' . '{protected_legend:hide},protected;' . '{expert_legend:hide},hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages,' - . 'hofff_navigation_disableHooks,guests,cssID,space'; + . 'hofff_navigation_disableEvents,guests,cssID,space'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['hofff_navigation_defineRoots'] = 'hofff_navigation_roots'; @@ -222,7 +222,7 @@ ], ]; -$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_disableHooks'] = [ +$GLOBALS['TL_DCA']['tl_module']['fields']['hofff_navigation_disableEvents'] = [ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ diff --git a/src/Resources/contao/languages/de/tl_module.php b/src/Resources/contao/languages/de/tl_module.php index cbf1a1e..3ceb75c 100644 --- a/src/Resources/contao/languages/de/tl_module.php +++ b/src/Resources/contao/languages/de/tl_module.php @@ -89,8 +89,8 @@ ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_showErrorPages'] = ['Fehlerseiten anzeigen', 'Fehlerseiten vom Typ "403" und "404" werden in der Navigation angezeigt.']; -$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_disableHooks'] +$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_disableEvents'] = [ - 'Hooks deaktivieren', - 'Deaktiviert das Ausführen der Navigations-Hooks. Kann zu einer besseren Performance führen, wenn Hooks für diese Navigation nicht notwendig sind.', + 'Events deaktivieren', + 'Deaktiviert das Ausführen der Navigations-Events. Kann zu einer besseren Performance führen, wenn Events für diese Navigation nicht notwendig sind.', ]; From dee6fbf6bd66ae6095aabe3fb0b109208d935d3f Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 36/75] Optimize config fields --- src/Resources/contao/dca/tl_module.php | 40 +++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index a8b37da..6092d15 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -10,23 +10,23 @@ $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineDepth'; $GLOBALS['TL_DCA']['tl_module']['palettes']['hofff_navigation_menu'] - = '{title_legend},name,headline,type;' - . '{hofff_navigation_root_legend},' - . 'hofff_navigation_currentAsRoot,hofff_navigation_defineRoots,' - . 'hofff_navigation_start,hofff_navigation_respectHidden,' - . 'hofff_navigation_respectPublish,hofff_navigation_respectGuests;' - . '{hofff_navigation_legend},' - . 'hofff_navigation_includeStart,' - . 'hofff_navigation_defineStop,' - . 'hofff_navigation_defineHard,' - . 'hofff_navigation_showHidden,hofff_navigation_showProtected,' - . 'hofff_navigation_showGuests,hofff_navigation_isSitemap,' - . 'hofff_navigation_hideSingleLevel;' - . '{template_legend:hide},navigationTpl,hofff_navigation_addLegacyCss,' - . 'hofff_navigation_addFields;' - . '{protected_legend:hide},protected;' - . '{expert_legend:hide},hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages,' - . 'hofff_navigation_disableEvents,guests,cssID,space'; + = ';{title_legend},name,headline,type' + . ';{hofff_navigation_root_legend}' + . ',hofff_navigation_currentAsRoot,hofff_navigation_defineRoots' + . ',hofff_navigation_start,hofff_navigation_respectHidden' + . ',hofff_navigation_respectPublish,hofff_navigation_respectGuests' + . ';{hofff_navigation_legend}' + . ',hofff_navigation_includeStart' + . ',hofff_navigation_defineStop' + . ',hofff_navigation_defineHard' + . ',hofff_navigation_showHidden,hofff_navigation_showProtected' + . ',hofff_navigation_showGuests,hofff_navigation_isSitemap' + . ',hofff_navigation_hideSingleLevel' + . ';{template_legend:hide},navigationTpl,hofff_navigation_addLegacyCss' + . ',hofff_navigation_addFields' + . ';{protected_legend:hide},protected,guests' + . ';{expert_legend:hide},cssID,hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages' + . ',hofff_navigation_disableEvents'; $GLOBALS['TL_DCA']['tl_module']['subpalettes']['hofff_navigation_defineRoots'] = 'hofff_navigation_roots'; @@ -200,7 +200,7 @@ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ - 'tl_class' => 'clr w50 cbx m12', + 'tl_class' => 'm12 w50', ], 'sql' => [ 'type' => Types::STRING, @@ -213,7 +213,7 @@ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ - 'tl_class' => 'clr w50 cbx m12', + 'tl_class' => 'w50', ], 'sql' => [ 'type' => Types::STRING, @@ -226,7 +226,7 @@ 'exclude' => true, 'inputType' => 'checkbox', 'eval' => [ - 'tl_class' => 'w50 cbx m12', + 'tl_class' => 'w50', ], 'sql' => [ 'type' => Types::STRING, From 48ed6baf1b6322ef23ee0c9360b4179ff4c1a2a0 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 37/75] Enable code style check --- .github/workflows/diagnostics.yml | 75 +++++++++ .gitignore | 6 + .phpcq.lock | 1 + .phpcq.yaml.dist | 104 ++++++++++++ composer.json | 138 ++++++++-------- phpcs.xml.dist | 38 +++++ phpunit.xml.dist | 24 +++ psalm.xml | 16 ++ publish/changelog.txt | 68 -------- publish/license_php.txt | 30 ---- publish/releasenotes_de.txt | 55 ------- src/Event/ItemEvent.php | 4 + src/Event/MenuEvent.php | 4 + .../Dca/NavigationDcaListener.php | 24 ++- src/FrontendModule/ModuleNavigationMenu.php | 18 ++- src/HofffContaoNavigationBundle.php | 1 - src/Items/PageItemsLoader.php | 116 +++++++++----- src/Migration/BackboneNavigationMigration.php | 4 +- src/QueryBuilder/BaseQueryBuilder.php | 4 +- src/QueryBuilder/PageQueryBuilder.php | 26 +-- src/Renderer/NavigationRenderer.php | 149 +++++++++++------- src/Resources/contao/dca/tl_module.php | 17 +- src/Resources/contao/languages/de/modules.php | 11 +- .../contao/languages/de/tl_module.php | 107 +++++++------ 24 files changed, 639 insertions(+), 401 deletions(-) create mode 100644 .github/workflows/diagnostics.yml create mode 100644 .phpcq.lock create mode 100644 .phpcq.yaml.dist create mode 100644 phpcs.xml.dist create mode 100644 phpunit.xml.dist create mode 100644 psalm.xml delete mode 100644 publish/changelog.txt delete mode 100644 publish/license_php.txt delete mode 100644 publish/releasenotes_de.txt diff --git a/.github/workflows/diagnostics.yml b/.github/workflows/diagnostics.yml new file mode 100644 index 0000000..23471a3 --- /dev/null +++ b/.github/workflows/diagnostics.yml @@ -0,0 +1,75 @@ +name: Code Quality Diagnostics + +on: + pull_request: + push: + branches: + - master + - develop + +jobs: + build: + runs-on: ubuntu-latest + + name: PHP ${{ matrix.php }} + + strategy: + fail-fast: false + matrix: + include: + - php: '7.4' + phpcq_install: 'install' + phpcq_flags: '' + - php: '8.0' + phpcq_install: 'update' + phpcq_flags: '' + - php: '8.1' + phpcq_install: 'update' + phpcq_flags: '' + + steps: + - name: Pull source + uses: actions/checkout@v2 + + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: xdebug2 + + - name: Cache composer cache directory + uses: actions/cache@v1 + env: + cache-name: composer-cache-dir-${{ matrix.php }} + with: + path: ~/.cache/composer + key: ${{ runner.os }}-build-${{ env.cache-name }} + + - name: Install composer dependencies + run: composer install + + - name: Cache vendor directory of phpcq tool runner + uses: actions/cache@v1 + env: + cache-name: vendor-${{ matrix.php }} + with: + path: $GITHUB_WORKSPACE/vendor + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + + - name: Update phpcq + run: $GITHUB_WORKSPACE/vendor/bin/phpcq self-update --unsigned + + - name: Install phpcq toolchain + run: $GITHUB_WORKSPACE/vendor/bin/phpcq ${{ matrix.phpcq_install }} -v + + - name: Run tests + run: $GITHUB_WORKSPACE/vendor/bin/phpcq run -o github-action -o default ${{ matrix.phpcq_flags }} -v + + - name: Upload build directory to artifact + uses: actions/upload-artifact@v2 + if: ${{ success() }} || ${{ failure() }} + with: + name: phpcq-builds-php-${{ matrix.php }} + path: .phpcq/build/ diff --git a/.gitignore b/.gitignore index feb1d99..0000e3b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,9 @@ !/README.md !/composer.json !/src +!/.phpcq.yaml.dist +!/.phpcq.lock +!/phpcs.xml.dist +!/phpunit.xml.dist +!/psalm.xml +!/.github diff --git a/.phpcq.lock b/.phpcq.lock new file mode 100644 index 0000000..483ad85 --- /dev/null +++ b/.phpcq.lock @@ -0,0 +1 @@ +{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/psalm-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"4.23.0","url":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar","requirements":{"php":{"php":"^7.1|^8","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar.asc"}}},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-require-checker-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"5b0fd8cd5e0f5761c53b9d5375b6f6ba50f148468896248f823cc2a48361adfd872556066764b1b544ff51ffd5de60d6f9a75050db00b257d807976ac761bc3a"},"tools":{"composer-require-checker":{"version":"4.0.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.0.0/composer-require-checker.phar","requirements":{"php":{"php":"^8.0","ext-json":"*","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.0.0/composer-require-checker.phar.asc"}}},"phpmd":{"api-version":"1.0.0","version":"1.0.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpmd-1.0.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"88e267b9c36b2edc85e924717606b626e005ac8d97b1f65f5331e2a3b3894dec2cf124f6187541bf759d026477b6d94daacc5d5c81bb09714a68ffabe5698dc5"},"tools":{"phpmd":{"version":"2.12.0","url":"https://github.com/phpmd/phpmd/releases/download/2.12.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":null}}},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}}},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}}},"phpcs":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcs-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar.asc"},"phpcbf":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar.asc"}}},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.26.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.26.0/composer-normalize.phar","requirements":{"php":{"php":"^7.4 || ^8.0"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.26.0/composer-normalize.phar.asc"}}},"phpunit":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpunit-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0"},"tool":{"phpunit":"^6.0 || ^7.0 || ^8.0 || ^9.0"}},"checksum":{"type":"sha-512","value":"c73f15658e3ba62665f09492ec91c3a6a715760bfaa88473a987538439fff442540148e086e46a6aa18ce55a3ea2fbf76caaa581384cb84a38859fcc609ae7e4"},"tools":{"phpunit":{"version":"9.5.20","url":"https://phar.phpunit.de/phpunit-9.5.20.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-xml":"*","ext-xmlwriter":"*"}},"checksum":{"type":"sha-256","value":"6becad2da5c37f5ad101cc665ef05a2f1a6a45d2427c8edcc74f72c92fb1e05a"},"signature":"https://phar.phpunit.de/phpunit-9.5.20.phar.asc"}}}},"tools":[]} \ No newline at end of file diff --git a/.phpcq.yaml.dist b/.phpcq.yaml.dist new file mode 100644 index 0000000..c3b76bb --- /dev/null +++ b/.phpcq.yaml.dist @@ -0,0 +1,104 @@ +phpcq: + repositories: + - https://phpcq.github.io/repository/repository.json + directories: + - src + - tests + artifact: .phpcq/build + + plugins: + psalm: + version: ^1.0 + signed: false + composer-require-checker: + version: ^1.0 + signed: false + phpmd: + version: ^1.0 + signed: false + requirements: + phpmd: + signed: false + phpcpd: + version: ^1.1 + signed: false + phploc: + version: ^1.0 + signed: false + phpcs: + version: ^1.0 + signed: false + composer-normalize: + version: ^1.0 + signed: false + phpunit: + version: ^1.0 + signed: false + trusted-keys: + # composer-require-checker + - 033E5F8D801A2F8D + # sb@sebastian-bergmann.de + - 4AA394086372C20A + # psalm + - 8A03EA3B385DBAA1 + - 12CE0F1D262429A5 + # magl@magll.net + - D2CCAC42F6295E7D + # PHP_CodeSniffer + - 31C7E470E2138192 + # Composer normalize + - C00543248C87FB13 + # phpmd + - 0F9684B8B16B7AB0 + +tasks: + fix: + - composer-normalize-fix + - phpcbf + + verify: + - composer-require-checker + - composer-normalize + + analyze: + - phploc + - phpcpd + - phpmd + - phpcs + # - psalm + - phpunit + + default: + - verify + - analyze + + phpmd: + config: + ruleset: + - codesize + - controversial + - design + - naming + - unusedcode + + composer-require-checker: + config: + config_file: '.composer-require-checker.json' + + phpcs: + config: &phpcs-config + standard: ~ + standard_paths: + - ./vendor/slevomat/coding-standard + - ./vendor/doctrine/coding-standard/lib + + phpcbf: + plugin: phpcs + config: + <<: *phpcs-config + fix: true + + composer-normalize-fix: + plugin: composer-normalize + config: + dry_run: false diff --git a/composer.json b/composer.json index 5e7268a..e6c46fd 100644 --- a/composer.json +++ b/composer.json @@ -1,67 +1,75 @@ { - "name": "hofff/contao-navigation", - "description": "Advanced navigation module for Contao CMS", - "keywords": [ "navigation", "module", "page", "contao" ], - "type": "contao-bundle", - "license": "LGPL-3.0-or-later", - "authors": [ - { - "name": "Oliver Hoff", - "email": "oliver@hofff.com", - "homepage": "https://www.hofff.com/", - "role": "Developer" - }, - { - "name": "Nicky Hoff", - "email": "nick@hofff.com", - "homepage": "https://www.hofff.com/", - "role": "Maintainer" - }, - { - "name": "David Molineus", - "email": "david@hofff.com", - "homepage": "https://www.hofff.com/", - "role": "Maintainer" - } - ], - "support": { - "issues": "https://github.com/hofff/contao-navigation/issues", - "source": "https://github.com/hofff/contao-navigation" - }, - "require": { - "php": "^7.4 || ^8.0", - "contao/core-bundle": "^4.9", - "doctrine/dbal": "^2.11 || ^3.0", - "symfony/config": "^4.4 || ^5.0", - "symfony/dependency-injection": "^4.4 || ^5.0", - "symfony/http-kernel": "^4.4 || ^5.0" - }, - "require-dev": { - "contao/manager-plugin": "^2.0", - "doctrine/coding-standard": "^9.0.", - "phpcq/runner-bootstrap": "1.x-dev" - }, - "extra": { - "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin", - "branch-alias": { - "dev-master": "1.9.x", - "dev-develop": "2.0.x" - } - }, - "replace": { - "contao-legacy/backboneit_navigation": "self.version", - "backboneit/contao-navigation": "self.version" - }, - "autoload": { - "psr-4": { - "Hofff\\Contao\\Navigation\\": "src/" - } - }, - "config": { - "allow-plugins": { - "contao-components/installer": false, - "contao/manager-plugin": true, - "dealerdirect/phpcodesniffer-composer-installer": true - } - } + "name": "hofff/contao-navigation", + "description": "Advanced navigation module for Contao CMS", + "license": "LGPL-3.0-or-later", + "type": "contao-bundle", + "keywords": [ + "navigation", + "module", + "page", + "contao" + ], + "authors": [ + { + "name": "Oliver Hoff", + "email": "oliver@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Developer" + }, + { + "name": "Nicky Hoff", + "email": "nick@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Maintainer" + }, + { + "name": "David Molineus", + "email": "david@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Maintainer" + } + ], + "support": { + "issues": "https://github.com/hofff/contao-navigation/issues", + "source": "https://github.com/hofff/contao-navigation" + }, + "require": { + "php": "^7.4 || ^8.0", + "contao/core-bundle": "^4.9", + "doctrine/dbal": "^2.11 || ^3.0", + "symfony/config": "^4.4 || ^5.0", + "symfony/dependency-injection": "^4.4 || ^5.0", + "symfony/event-dispatcher-contracts": "^1.1 || ^2.0 || ^3.0", + "symfony/http-foundation": "^4.4 || ^5.0", + "symfony/http-kernel": "^4.4 || ^5.0", + "symfony/security-core": "^4.4 || ^5.0" + }, + "require-dev": { + "contao/manager-plugin": "^2.0", + "doctrine/coding-standard": "^9.0.", + "phpcq/runner-bootstrap": "1.x-dev" + }, + "replace": { + "backboneit/contao-navigation": "self.version", + "contao-legacy/backboneit_navigation": "self.version" + }, + "autoload": { + "psr-4": { + "Hofff\\Contao\\Navigation\\": "src/" + } + }, + "config": { + "allow-plugins": { + "contao-components/installer": false, + "contao/manager-plugin": true, + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "extra": { + "branch-alias": { + "dev-develop": "2.0.x", + "dev-master": "1.9.x" + }, + "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin" + } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..f638e54 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,38 @@ + + + + + + + + + + vendor/autoload.php + + + + + + src + + + + + + + + + + + + + + + + + + + + languages/* + + diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..b603254 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,24 @@ + + + + + + ./src + + + + + ./tests + + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..5722456 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/publish/changelog.txt b/publish/changelog.txt deleted file mode 100644 index c4cd068..0000000 --- a/publish/changelog.txt +++ /dev/null @@ -1,68 +0,0 @@ -h1. Changelog - -h2. 1.5.1 stable - -* 1 *Feature*: Add option to display error pages within the navigation - -h2. 1.5.0 stable - -* 1 Always create subitem arrays for root ids, for easier hook integration - -h2. 1.5.0 rc1 - -* 1 Add Contao 3 support - -h2. 1.4.0 stable - -* 1 *Feature*: Allow multiple stop levels - -h2. 1.3.0 stable - -* 1 *Feature*: Possibility to overwrite navigation template for a single level in its parent item -* 1 *Feature*: Added a compile navigation item hook "bbit_navi_item" -* 1 *Change*: Always add page type token to css classes -* 1 *Fix*: Conditions where not applied when including start level - -h2. 1.2.1 stable - -* 1 *Fix*: Fixed "target" DB value getting raw into the template -* 1 *Fix*: Fixed some variable name confusions - -h2. 1.2.0 beta1 - -* 1 *Feature*: Added a generic tree hook "backboneit_navigation_tree" to AbstractModuleNavigation, which allows to modify the navigation tree for tree-based navigation. -* 1 *Change*: The "backboneit_navigation_menu" hook should only be used to modify the root pages of the navigation menu module and overwrite different settings. Though tree modifications are still supported, it is recommended to use the new "backboneit_navigation_tree" hook. -* 1 *Change*: Lot of performance optimizations -* 1 *Fix*: Subsequent identical parent pages are canonicalized, if start level is negative -* 1 *Fix*: Removed many brainlag bugs - -h2. 1.1.0 stable - -*Note: If you update from a previous version, please check the module settings for stop and hard limit!* - -* 3 *Fix*: It is actually called "leaf", not "leave" -* 1 *Feature*: New CSS classes "forward", "redirect", "root", "inner" (all nodes with a *rendered* submenu) and "leave" (all nodes without a *rendered* submenu) -* 1 *Feature*: Option to disable forward resolution, for greater performance -* 1 *Feature*: Option to add "mod_navigation" CSS class to the modules div container -* 1 *Change*: Improved hook handling a lot -* 1 *Change*: The property "arrSubpages" is deprecated, use property "arrSubitems" now -* 1 *Fix*: CSS class "submenu" behaves now exactly like the core navigation menu uses it -* 1 *Fix*: Alot of fixes for many configurations - -h2. 1.0.0 stable - -* 5 *Feature*: CSS classes are now calculated while rendering the templates, so navigation items hooked in receive the correct css -* 5 *Change*: The amount of levels displayed is now additionally checked while rendering the templates, to apply the limits on navigation items hooked in -* 5 *Change*: Moved the hook before the calculation of the first navigation level (clearer usage, but $arrRoots are now the reference "pages" and not the first navigation level) -* 5 *Fix*: Fixed "sibling" CSS class -* 5 *Fix*: Fixed a bug which caused an additional navigation level to be rendered, when root level is displayed a soft stop limit is set -* 4 *Change*: Changed the hidden condition flag for including start level from showHidden to respectHidden, which results in a more consistent behavior -* 4 *Fix*: Fixed an error message in backend, when module is rendered in articles for preview -* 4 Tagged as stable - -h2. 1.0.0 rc1 - -* 3 *Feature*: Added a hook before rendering the navigation -* 3 *Change*: Some refactoring from protected to public to make the hook more useful -* 3 *Change*: Some clean-up -* 2 Initial release diff --git a/publish/license_php.txt b/publish/license_php.txt deleted file mode 100644 index 38fb549..0000000 --- a/publish/license_php.txt +++ /dev/null @@ -1,30 +0,0 @@ -. - * - * backboneit_navigation - * Various navigation modules for Contao CMS - * - * PHP version 5 - * @copyright backboneIT | Oliver Hoff 2011-2012 - * @author Oliver Hoff - * @license http://opensource.org/licenses/lgpl-3.0.html - */ diff --git a/publish/releasenotes_de.txt b/publish/releasenotes_de.txt deleted file mode 100644 index d496a37..0000000 --- a/publish/releasenotes_de.txt +++ /dev/null @@ -1,55 +0,0 @@ -=== Titel -Navigationselemente - - -=== Suchbegriffe -navigation,seitenstruktur,seiten,menü, - - -=== Teaser -Verschiedene Navigationselemente (vorerst "nur" ein Navigationsmenü mit vielen neuen Möglichkeiten) - - -=== Beschreibung -

Anmerkungen zum Bestimmen der Sichtbarkeit einer Seite:

-
    -
  • Der Veröffentlichungsstatus gilt ausschließlich für eine Seite selbst. Das heißt zum Beispiel, -dass eine Navigation durchaus dargestellt wird, selbst wenn die Referenzseite nicht veröffentlicht ist.
  • -
  • Der Seitenschutz für bestimmte Mitgliedergruppen vererbt sich auf alle Unterseiten, -außer denjenigen die selbst explizit einen Seitenschutz für Mitgliedergruppen definieren und derren Unterseiten.
  • -
  • Die Einstellung "Nur Gästen anzeigen" gilt nur für die Seite selbst. Tatsächlich ist die Seite für -angemeldete Benutzer auch noch verfügbar, soll nur in keiner Navigation angezeigt werden. (Anders als zum Beispiel Artikel, -die nur Gästen angezeigt werden. Diese werden gar nicht mehr gerendert.)
  • -
  • "Im Menü verstecken" gilt nur für die Seite selbst.
  • -
- -

Navigationsmenü:

-

Ein Multitalent: Es ist alles möglich was mit einem Navigationsmenü oder -einer Individuellen Navigation möglich ist, Kombinationen aus beiden und -noch einiges mehr. Einfach ausprobieren.

-

Funktionen:

-
    -
  • Vollständig kompatibel zu den Templates für das Standard-Navigationsmenü (ab Version 1.1.0)
  • -
  • Zusätzliche CSS-Klassen "forward", "redirect", "root", "inner" (Innerer Knoten) und "leaf" (Blatt)
  • -
  • Mehrere Referenzseiten (Wurzeln der Navigation)
  • -
  • Aktuelle Seite als Referenzseite
  • -
  • Startebene wird relativ zu den Referenzseiten berechnet (negative Startebene möglich)
  • -
  • Hardlimit ("Maximal angezeigte Ebenen") flexibel (Anmerkung: Stoplimit und Hardlimit -beziehen sich relativ zur Startebene – dies sollte auch durch die geänderten Labels der Moduleinstellungen hervorgehen.
  • -
  • Versteckte und geschützte Seiten anzeigen
  • -
  • Als Sitemap verwendbar
  • -
  • Optimierte Algorithmen: Zum Beispiel wird pro Navigationsebene nur noch -eine Datenbankabfrage durchgeführt, was vorallem bei einer sehr verzweigten -Navigation Vorteile bringen sollte
  • -
  • Dynamisch Erweiterbar durch Hook
  • -
- - -=== Freigabe-Notizen und Änderungs-Log -

siehe Handbuch-Link

-

Wenn Sie von einer älteren Version auf die Version 1.1.0 oder höher updaten, -überprüfen Sie bitte die Einstellungen für "Angezeigte Ebenen" und "Maximal angezeigte Ebenen".

- - -=== Handbuch-Link -http://contao-forge.org/projects/backboneitnavigation/wiki diff --git a/src/Event/ItemEvent.php b/src/Event/ItemEvent.php index fcaf931..be9f1b0 100644 --- a/src/Event/ItemEvent.php +++ b/src/Event/ItemEvent.php @@ -8,8 +8,10 @@ final class ItemEvent extends Event { + /** @var array */ private array $item; + /** @param array $item */ public function __construct(ModuleModel $moduleModel, array $item) { parent::__construct($moduleModel); @@ -17,11 +19,13 @@ public function __construct(ModuleModel $moduleModel, array $item) $this->item = $item; } + /** @param array $item */ public function changeItem(array $item): void { $this->item = $item; } + /** @return array */ public function item(): array { return $this->item; diff --git a/src/Event/MenuEvent.php b/src/Event/MenuEvent.php index b9e7284..277272b 100644 --- a/src/Event/MenuEvent.php +++ b/src/Event/MenuEvent.php @@ -8,8 +8,10 @@ final class MenuEvent extends Event { + /** @var list */ private array $rootIds; + /** @param list $rootIds */ public function __construct(ModuleModel $moduleModel, array $rootIds) { parent::__construct($moduleModel); @@ -17,11 +19,13 @@ public function __construct(ModuleModel $moduleModel, array $rootIds) $this->rootIds = $rootIds; } + /** @param list $rootIds */ public function changeRootIds(array $rootIds): void { $this->rootIds = $rootIds; } + /** @return list */ public function rootIds(): array { return $this->rootIds; diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index 3852e9e..df4b2d4 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -1,5 +1,7 @@ + * + * @Callback(table="tl_module", target="fields.hofff_navigation_addFields.options") + * @SuppressWarnings(PHPMD.Superglobals) */ public function getPageFields(): array { @@ -30,9 +38,11 @@ public function getPageFields(): array $fields = []; foreach ($GLOBALS['TL_DCA']['tl_page']['fields'] as $fieldName => &$config) { - if (! isset(PageQueryBuilder::DEFAULT_FIELDS[$fieldName])) { - $fields[$fieldName] = sprintf('%s [%s]', $config['label'][0], $fieldName); + if (isset(PageQueryBuilder::DEFAULT_FIELDS[$fieldName])) { + continue; } + + $fields[$fieldName] = sprintf('%s [%s]', $config['label'][0], $fieldName); } return $fields; @@ -47,9 +57,11 @@ public function saveStop(string $value): string $stop = []; foreach (array_map('intval', explode(',', (string) $value)) as $intLevel) { - if ($intLevel > $minimum) { - $stop[] = $minimum = $intLevel; + if ($intLevel <= $minimum) { + continue; } + + $stop[] = $minimum = $intLevel; } return implode(',', $stop); diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 5f39d33..7086774 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -1,5 +1,7 @@ - * * @FrontendModule("hofff_navigation_menu", category="navigation") */ final class ModuleNavigationMenu extends AbstractFrontendModuleController @@ -64,6 +67,10 @@ public function __construct(PageItemsLoader $loader, NavigationRenderer $rendere $this->renderer = $renderer; } + /** + * @SuppressWarnings(PHPMD.Superglobals) + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ protected function getResponse(Template $template, ModuleModel $model, Request $request): ?Response { $stopLevels = $this->getStopLevels($model); @@ -96,6 +103,7 @@ protected function getResponse(Template $template, ModuleModel $model, Request $ return $template->getResponse(); } + /** @return list */ public function getStopLevels(ModuleModel $model): array { if (! $model->hofff_navigation_defineStop) { @@ -106,9 +114,11 @@ public function getStopLevels(ModuleModel $model): array $stopLevel = []; foreach (array_map('intval', explode(',', $model->hofff_navigation_stop)) as $level) { - if ($level > $minLevel) { - $stopLevel[] = $minLevel = $level; + if ($level <= $minLevel) { + continue; } + + $stopLevel[] = $minLevel = $level; } return $stopLevel ?: [PHP_INT_MAX]; diff --git a/src/HofffContaoNavigationBundle.php b/src/HofffContaoNavigationBundle.php index 99e9a22..f68f77a 100644 --- a/src/HofffContaoNavigationBundle.php +++ b/src/HofffContaoNavigationBundle.php @@ -8,5 +8,4 @@ final class HofffContaoNavigationBundle extends Bundle { - } diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index d9e5906..6291834 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -22,11 +22,13 @@ use function array_unique; use function array_unshift; use function array_values; +use function count; use function in_array; use function max; use const PHP_INT_MAX; +/** @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ final class PageItemsLoader { private Connection $connection; @@ -39,6 +41,7 @@ final class PageItemsLoader private ModuleModel $moduleModel; + /** @var list */ private array $stopLevels = [PHP_INT_MAX]; private int $hardLevel = PHP_INT_MAX; @@ -47,17 +50,22 @@ final class PageItemsLoader public function __construct(Connection $connection, Security $security) { - $this->connection = $connection; - $this->security = $security; + $this->connection = $connection; + $this->security = $security; } + /** + * @param list $stopLevels + * + * @SuppressWarnings(PHPMD.Superglobals) + */ public function load( ModuleModel $moduleModel, array $stopLevels = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, ?int $activeId = null ): PageItems { - $this->items = new PageItems(); + $this->items = new PageItems(); $this->items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $this->security, $moduleModel); @@ -93,9 +101,13 @@ public function load( /** * Fetches page data for all navigation items below the given roots. * - * @param integer $level (optional, defaults to 1) The level of the PIDs. + * @param list $parentIds + * @param int $level (optional, defaults to 1) The level of the PIDs. * * @return array + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function fetchItems(array $parentIds, int $level = 1): array { @@ -107,7 +119,7 @@ protected function fetchItems(array $parentIds, int $level = 1): array return []; } - $fetched = []; + $fetched = []; $stopLevels = $this->stopLevels; while ($parentIds) { @@ -118,9 +130,11 @@ protected function fetchItems(array $parentIds, int $level = 1): array count($stopLevels) > 1 && array_shift($stopLevels); $arrEndPIDs = []; foreach ($parentIds as $intPID) { - if (!$this->items->isInTrail((int) $intPID)) { - $arrEndPIDs[$intPID] = true; + if ($this->items->isInTrail((int) $intPID)) { + continue; } + + $arrEndPIDs[$intPID] = true; } } else { $arrEndPIDs = []; @@ -146,9 +160,9 @@ protected function fetchItems(array $parentIds, int $level = 1): array $this->items->subItems[(int) $page['pid']][] = (int) $page['id']; // for order of items } - $this->items->items[(int) $page['id']] = $page; // item datasets - $parentIds[] = $page['id']; // ids of current layer (for next layer pids) - $fetched[$page['id']] = true; // fetched in this method + $this->items->items[(int) $page['id']] = $page; // item datasets + $parentIds[] = $page['id']; // ids of current layer (for next layer pids) + $fetched[$page['id']] = true; // fetched in this method } elseif (! isset($items->subItems[(int) $page['pid']])) { $this->items->subItems[(int) $page['pid']] = []; } @@ -160,6 +174,11 @@ protected function fetchItems(array $parentIds, int $level = 1): array return $fetched; } + /** + * @return list + * + * @SuppressWarnings(PHPMD.Superglobals) + */ protected function calculateRootIDs(): array { $rootIds = $this->getRootIds(); @@ -172,18 +191,20 @@ protected function calculateRootIDs(): array for ($i = 1, $n = $this->moduleModel->hofff_navigation_start; $i < $n; $i++) { $rootIds = $this->getNextLevel($rootIds, $this->pageQueryBuilder->createRootIdsQuery()); } + $rootIds = $this->getNextLevel($rootIds, $this->pageQueryBuilder->createStartRootIdsQuery()); } elseif ($this->moduleModel->hofff_navigation_start < 0) { for ($i = 0, $n = -$this->moduleModel->hofff_navigation_start; $i < $n; $i++) { $rootIds = $this->getPrevLevel($rootIds); } + $rootIds = $this->filterPages($rootIds, $this->pageQueryBuilder->createStartRootIdsQuery()); } else { $rootIds = $this->filterPages($rootIds, $this->pageQueryBuilder->createStartRootIdsQuery()); } $stopLevels = $this->stopLevels; - if ($stopLevels[0] == 0) { // special case, keep only roots within the current path + if ($stopLevels[0] === 0) { // special case, keep only roots within the current path $path = $GLOBALS['objPage']->trail; $path[] = $this->activeId; $rootIds = array_intersect($rootIds, $path); @@ -208,12 +229,12 @@ public function isPermissionCheckRequired(): bool * * Context property: hofff_navigation_showProtected * - * @param array $arrPage The page dataset of the current page, with at least - * groups and protected attributes set. + * @param array $page The page dataset of the current page, with at least + * groups and protected attributes set. * - * @return boolean If the permission is granted true, otherwise false. + * @return bool If the permission is granted true, otherwise false. */ - public function isPermissionGranted(ModuleModel $model, array $arrPage): bool + public function isPermissionGranted(ModuleModel $model, array $page): bool { // be users have access everywhere if ($this->security->isGranted('ROLE_USER')) { @@ -225,7 +246,7 @@ public function isPermissionGranted(ModuleModel $model, array $arrPage): bool return true; } - return ! $this->isPermissionDenied($arrPage); + return ! $this->isPermissionDenied($page); } /** @@ -237,15 +258,15 @@ public function isPermissionGranted(ModuleModel $model, array $arrPage): bool * given page dataset, in regards to the permission requirements of the * page. * - * @param array $arrPage The page dataset of the current page, with at least - * groups and protected attributes set. + * @param array $page The page dataset of the current page, with at least + * groups and protected attributes set. * - * @return boolean If the permission is denied true, otherwise false. + * @return bool If the permission is denied true, otherwise false. */ - public function isPermissionDenied(array $arrPage): bool + public function isPermissionDenied(array $page): bool { // this page is not protected - if (! $arrPage['protected']) { + if (! $page['protected']) { return false; } @@ -260,9 +281,14 @@ public function isPermissionDenied(array $arrPage): bool } // check if the current user is not in any group, which is allowed to access the current page - return ! array_intersect((array) $user->groups, StringUtil::deserialize($arrPage['groups'], true)); + return ! array_intersect((array) $user->groups, StringUtil::deserialize($page['groups'], true)); } + /** + * @return list + * + * @SuppressWarnings(PHPMD.Superglobals) + */ protected function getRootIds(): array { if (! $this->moduleModel->hofff_navigation_defineRoots) { @@ -291,11 +317,13 @@ protected function getRootIds(): array * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * - * @param array $arrPages An array of page IDs to filter + * @param list $arrPages An array of page IDs to filter + * + * @return list Filtered array of page IDs * - * @return array Filtered array of page IDs + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function filterPages(array $arrPages, QueryBuilder $queryBuilder) + public function filterPages(array $arrPages, QueryBuilder $queryBuilder): array { if (! $arrPages) { return $arrPages; @@ -309,7 +337,7 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder) if (! $this->isPermissionCheckRequired()) { return array_intersect( $arrPages, - array_map(static fn(array $row): int => (int) $row['id'], $result->fetchAllAssociative()) + array_map(static fn (array $row): int => (int) $row['id'], $result->fetchAllAssociative()) ); } // restore order @@ -327,9 +355,11 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder) * for permission check, which must not be done, when this page * defines access rights. */ - if (! $arrPage['protected'] && $arrPage['pid'] != 0) { - $arrPIDs[$arrPage['pid']][] = $arrPage['id']; + if ($arrPage['protected'] || $arrPage['pid'] === 0) { + continue; } + + $arrPIDs[$arrPage['pid']][] = $arrPage['id']; } // exclude pages which are in a protected path @@ -342,7 +372,7 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder) while ($arrPage = $result->fetchAssociative()) { if (! $arrPage['protected']) { // do not remove, see above - if ($arrPage['pid'] != 0) { + if ($arrPage['pid'] !== 0) { $arrPIDs[$arrPage['pid']] = isset($arrPIDs[$arrPage['pid']]) ? array_merge($arrPIDs[$arrPage['pid']], $arrIDs[$arrPage['id']]) : $arrIDs[$arrPage['id']]; @@ -364,9 +394,9 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder) * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * - * @param array $arrPages An array of parent IDs + * @param list $arrPages An array of parent IDs * - * @return array The child IDs + * @return list The child IDs */ public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array { @@ -380,9 +410,11 @@ public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array $arrNext = []; if ($this->isPermissionCheckRequired()) { while ($arrPage = $result->fetchAssociative()) { - if (! $this->isPermissionDenied($arrPage)) { - $arrNext[$arrPage['pid']][] = $arrPage['id']; + if ($this->isPermissionDenied($arrPage)) { + continue; } + + $arrNext[$arrPage['pid']][] = $arrPage['id']; } } else { while ($arrPage = $result->fetchAssociative()) { @@ -392,9 +424,11 @@ public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array $arrNextLevel = []; foreach ($arrPages as $intID) { - if (isset($arrNext[$intID])) { - $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); + if (! isset($arrNext[$intID])) { + continue; } + + $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); } return $arrNextLevel; @@ -409,9 +443,9 @@ public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * - * @param array $arrPages An array of child IDs + * @param list $arrPages An array of child IDs * - * @return array The parent IDs + * @return list The parent IDs */ public function getPrevLevel(array $arrPages): array { @@ -419,7 +453,7 @@ public function getPrevLevel(array $arrPages): array return $arrPages; } - $result = $this->pageQueryBuilder->createPreviousLevelQuery(array_keys(array_flip($arrPages)))->execute(); + $result = $this->pageQueryBuilder->createPreviousLevelQuery(array_keys(array_flip($arrPages)))->execute(); $arrPrev = []; while ($row = $result->fetchAssociative()) { $arrPrev[$row['id']] = $row['pid']; @@ -428,9 +462,11 @@ public function getPrevLevel(array $arrPages): array $arrPrevLevel = []; $intPID = -1; foreach ($arrPages as $intID) { - if (isset($arrPrev[$intID]) && $arrPrev[$intID] != $intPID) { - $arrPrevLevel[] = $intPID = $arrPrev[$intID]; + if (! isset($arrPrev[$intID]) || $arrPrev[$intID] === $intPID) { + continue; } + + $arrPrevLevel[] = $intPID = $arrPrev[$intID]; } return $arrPrevLevel; diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 2494108..2ab92e9 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -7,7 +7,9 @@ use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; + use function is_int; +use function sprintf; final class BackboneNavigationMigration extends AbstractMigration { @@ -17,7 +19,6 @@ final class BackboneNavigationMigration extends AbstractMigration private const NEW_PREFIX = 'hofff_navigation_'; - /** @var array */ private const FIELDS = [ 'roots_order', 'start', @@ -32,6 +33,7 @@ final class BackboneNavigationMigration extends AbstractMigration 'addFields', 'noForwardResolution', 'showErrorPages', + // phpcs:ignore Squiz.Arrays.ArrayDeclaration.KeySpecified 'disableHooks' => 'disableEvents', 'currentAsRoot', 'defineRoots', diff --git a/src/QueryBuilder/BaseQueryBuilder.php b/src/QueryBuilder/BaseQueryBuilder.php index d182297..59645ce 100644 --- a/src/QueryBuilder/BaseQueryBuilder.php +++ b/src/QueryBuilder/BaseQueryBuilder.php @@ -17,7 +17,7 @@ abstract class BaseQueryBuilder protected Connection $connection; /** @var array */ - private $queries = []; + private array $queries = []; public function __construct(Connection $connection, Security $security) { @@ -27,7 +27,7 @@ public function __construct(Connection $connection, Security $security) protected function query(string $name, callable $builder): QueryBuilder { - if (! isset ($this->queries[$name])) { + if (! isset($this->queries[$name])) { $this->queries[$name] = $this->connection->createQueryBuilder()->from('tl_page'); $builder($this->queries[$name]); } diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index d7226fb..4eac122 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -13,6 +13,7 @@ use function array_flip; use function array_keys; use function array_merge; +use function count; final class PageQueryBuilder extends BaseQueryBuilder { @@ -44,9 +45,10 @@ final class PageQueryBuilder extends BaseQueryBuilder ]; private ModuleModel $moduleModel; - + + /** @var list */ private array $fields = []; - + public function __construct(Connection $connection, Security $security, ModuleModel $moduleModel) { parent::__construct($connection, $security); @@ -55,13 +57,14 @@ public function __construct(Connection $connection, Security $security, ModuleMo $this->determineFields(); } + /** @param list $parentIds */ public function createFetchItemsQuery(array $parentIds): QueryBuilder { $query = $this->query( __FUNCTION__, function (QueryBuilder $queryBuilder): void { $queryBuilder - ->select(... $this->fields) + ->select(...$this->fields) ->andWhere('type != :rootType') ->setParameter('rootType', 'root') ->andWhere('pid IN (:pids)') @@ -144,11 +147,12 @@ function (QueryBuilder $queryBuilder): void { ); } + /** @param list $pageIds */ public function createPageInformationQuery(array $pageIds): QueryBuilder { $query = $this->query( __FUNCTION__, - function (QueryBuilder $queryBuilder): void { + static function (QueryBuilder $queryBuilder): void { $queryBuilder ->select('id', 'pid', 'protected', 'groups') ->where('id IN (:ids)'); @@ -160,13 +164,14 @@ function (QueryBuilder $queryBuilder): void { return $query; } + /** @param list $rootIds */ public function createRootInformationQuery(array $rootIds): QueryBuilder { $query = $this->query( __FUNCTION__, function (QueryBuilder $queryBuilder): void { $queryBuilder - ->select(... $this->fields) + ->select(...$this->fields) ->where('id IN (:rootIds)'); } ); @@ -176,11 +181,12 @@ function (QueryBuilder $queryBuilder): void { return $query; } + /** @param list $pageIds */ public function createPreviousLevelQuery(array $pageIds): QueryBuilder { $query = $this->query( __FUNCTION__, - function (QueryBuilder $queryBuilder): void { + static function (QueryBuilder $queryBuilder): void { $queryBuilder ->select('id', 'pid') ->where('id IN (:ids)'); @@ -194,8 +200,6 @@ function (QueryBuilder $queryBuilder): void { /** * Adds the or hidden state of a page. - * - * @return self */ private function addHiddenCondition( QueryBuilder $queryBuilder, @@ -249,9 +253,11 @@ private function determineFields(): void $fields = []; foreach ($table->getColumns() as $column) { - if (isset($customFields[$column->getName()])) { - $fields[$column->getName()] = true; + if (! isset($customFields[$column->getName()])) { + continue; } + + $fields[$column->getName()] = true; } $this->fields = array_keys(array_merge($fields, self::DEFAULT_FIELDS)); diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index a82d1a3..210f2b3 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -18,7 +18,7 @@ use function array_merge; use function array_shift; -use function get_class; +use function count; use function ltrim; use function preg_replace; use function str_replace; @@ -26,21 +26,23 @@ use function strncmp; use function trim; -use const LINK_NEW_WINDOW; use const PHP_INT_MAX; +/** + * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) + */ final class NavigationRenderer { - private RedirectPageQueryBuilder $redirectPageQueryBuilder; + private RedirectPageQueryBuilder $redirectQueryBuilder; private EventDispatcherInterface $eventDispatcher; public function __construct( EventDispatcherInterface $eventDispatcher, - RedirectPageQueryBuilder $redirectPageQueryBuilder + RedirectPageQueryBuilder $redirectQueryBuilder ) { - $this->redirectPageQueryBuilder = $redirectPageQueryBuilder; - $this->eventDispatcher = $eventDispatcher; + $this->redirectQueryBuilder = $redirectQueryBuilder; + $this->eventDispatcher = $eventDispatcher; } /** @@ -48,10 +50,10 @@ public function __construct( * Adds CSS classes "first" and "last" to the appropriate navigation item arrays. * If the given array is empty, the empty string is returned. * - * @param array $arrIDs The navigation items arrays - * @param array $stopLimit (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param integer $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param integer $currentLevel (optional, defaults to 1) The current level of this navigation layer + * @param list $itemIds The navigation items arrays + * @param list $stopLimit (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param int $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param int $currentLevel (optional, defaults to 1) The current level of this navigation layer * * @return string The parsed navigation template, could be empty string. */ @@ -71,7 +73,7 @@ public function render( $this->compileTree($moduleModel, $items); $this->dispatchTreeEvent($moduleModel, $items); - $itemIds = $this->dispatchMenuEvent($moduleModel, $itemIds); + $itemIds = $this->dispatchMenuEvent($moduleModel, $itemIds); $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); if ($moduleModel->hofff_navigation_hideSingleLevel) { @@ -87,13 +89,21 @@ public function render( } } - if ($stopLimit[0] == 0) { + if ($stopLimit[0] === 0) { array_shift($stopLimit); // special case renderNavigationTree cannot handle } return trim($this->renderTree($moduleModel, $items, $firstIds, $stopLimit, $intHard, $currentLevel, $activeId)); } + /** + * @param list $itemIds + * @param list $stopLimit + * + * @SuppressWarnings(PHPMD.NPathComplexity) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + */ private function renderTree( ModuleModel $moduleModel, PageItems $items, @@ -118,24 +128,24 @@ private function renderTree( $item = $items->items[$itemId]; - if ($itemId == $activeId) { + if ($itemId === $activeId) { $containsActive = true; if ($item['href'] === Environment::get('request')) { - $item['isActive'] = true; // nothing else (active class is set in template) - $item['isInTrail'] = false; + $item['isActive'] = true; // nothing else (active class is set in template) + $item['isInTrail'] = false; } else { - $item['isActive'] = false; // nothing else (active class is set in template) - $item['isInTrail'] = true; + $item['isActive'] = false; // nothing else (active class is set in template) + $item['isInTrail'] = true; } } else { // do not flatten if/else - if ($item['tid'] == $activeId) { + if ($item['tid'] === $activeId) { if ($item['href'] === Environment::get('request')) { - $item['isActive'] = true; // nothing else (active class is set in template) - $item['isInTrail'] = false; + $item['isActive'] = true; // nothing else (active class is set in template) + $item['isInTrail'] = false; } else { - $item['isActive'] = false; // nothing else (active class is set in template) - $item['isInTrail'] = true; + $item['isActive'] = false; // nothing else (active class is set in template) + $item['isInTrail'] = true; } } } @@ -149,11 +159,15 @@ private function renderTree( } elseif ($currentLevel >= $intHard) { // we are at hard level, never draw submenu $item['class'] .= ' submenu leaf'; - } elseif ($currentLevel >= $intStop && ! $item['isInTrail'] && $itemId !== $activeId && $item['tid'] != $activeId) { + } elseif ( + $currentLevel >= $intStop + && ! $item['isInTrail'] && $itemId !== $activeId + && $item['tid'] !== $activeId + ) { // we are at stop level and not trail and not active, never draw submenu $item['class'] .= ' submenu leaf'; } elseif ($items->subItems[$itemId]) { - $item['class'] .= ' submenu inner'; + $item['class'] .= ' submenu inner'; $item['subitems'] = $this->renderTree( $moduleModel, $items, @@ -171,19 +185,23 @@ private function renderTree( if ($containsActive) { foreach ($renderedItems as &$item) { - if (! $item['isActive']) { - $item['class'] .= ' sibling'; + if ($item['isActive']) { + continue; } + + $item['class'] .= ' sibling'; } + unset($item); } - $renderedItems[0]['class'] .= ' first'; + $renderedItems[0]['class'] .= ' first'; $renderedItems[count($renderedItems) - 1]['class'] .= ' last'; foreach ($renderedItems as &$item) { $item['class'] = ltrim($item['class']); } + unset($item); $objTemplate = new FrontendTemplate($moduleModel->navigationTpl ?: 'nav_default'); @@ -191,7 +209,7 @@ private function renderTree( 'module' => $moduleModel->row(), 'level' => 'level_' . $currentLevel, 'items' => $renderedItems, - 'type' => get_class($this), + 'type' => static::class, ]); return $objTemplate->parse(); @@ -217,9 +235,11 @@ private function compileTree(ModuleModel $moduleModel, PageItems $items): void /** * Compiles a navigation item array from a page dataset with the given subnavi * - * @param array $page The page dataset as an array + * @param array $page The page dataset as an array * - * @return array The compiled navigation item array + * @return array The compiled navigation item array + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function compileNavigationItem( ModuleModel $moduleModel, @@ -250,7 +270,7 @@ private function compileNavigationItem( $page['href'] = $this->generatePageUrl($page); } elseif ($redirectPage['type'] === 'redirect') { $page['href'] = $this->encodeEmailURL($redirectPage['url']); - $page['target'] = $redirectPage['target'] ? LINK_NEW_WINDOW : ''; + $page['target'] = $redirectPage['target'] ? 'target="_blank"' : ''; } else { $page['tid'] = $redirectPage['id']; $page['href'] = $this->generatePageUrl($redirectPage); @@ -259,25 +279,28 @@ private function compileNavigationItem( $page['tid'] = $page['jumpTo']; $page['href'] = $this->generatePageUrl($page); } + break; case 'redirect': $page['href'] = $this->encodeEmailURL($page['url']); - $page['target'] = $page['_target'] ? LINK_NEW_WINDOW : ''; + $page['target'] = $page['_target'] ? 'target="_blank"' : ''; break; case 'root': - if (! $page['dns'] - || preg_replace('/^www\./', '', $page['dns']) == preg_replace( + if ( + ! $page['dns'] + || preg_replace('/^www\./', '', $page['dns']) === preg_replace( '/^www\./', '', Environment::get('httpHost') - )) { + ) + ) { $page['href'] = Environment::get('base'); - break; // we only break on root pages; pages in different roots should be handled by DomainLink extension + // we only break on root pages; pages in different roots should be handled by DomainLink extension + break; } // do not break - default: case 'regular': case 'error_401': @@ -290,9 +313,10 @@ private function compileNavigationItem( return $this->dispatchItemEvent($moduleModel, $page); } - private function generatePageUrl(array $arrPage): ?string + /** @param array $page */ + private function generatePageUrl(array $page): ?string { - $pageModel = PageModel::findByPk($arrPage['id']); + $pageModel = PageModel::findByPk($page['id']); if ($pageModel) { return $pageModel->getFrontendUrl(); } @@ -319,6 +343,11 @@ private function encodeEmailURL(string $href): string return StringUtil::encodeEmail($href); } + /** + * @param array $page + * + * @return array + */ private function dispatchItemEvent(ModuleModel $moduleModel, array $page): array { if (! $moduleModel->hofff_navigation_disableHooks) { @@ -337,8 +366,6 @@ private function dispatchItemEvent(ModuleModel $moduleModel, array $page): array * * The callback receives the following parameters: * $this - This navigation module instance - * - * @return void */ private function dispatchTreeEvent(ModuleModel $moduleModel, PageItems $items): void { @@ -357,43 +384,55 @@ private function dispatchTreeEvent(ModuleModel $moduleModel, PageItems $items): * * And should return a new root array or null * - * @param array $arrRootIDs The root pages before hook execution + * @param list $rootIds The root pages before hook execution * - * @return array $arrRootIDs The root pages after hook execution + * @return list $arrRootIDs The root pages after hook execution */ - private function dispatchMenuEvent(ModuleModel $moduleModel, array $arrRootIDs): array + private function dispatchMenuEvent(ModuleModel $moduleModel, array $rootIds): array { if ($moduleModel->hofff_navigation_disableHooks) { - return $arrRootIDs; + return $rootIds; } - $event = new MenuEvent($moduleModel, $arrRootIDs); + $event = new MenuEvent($moduleModel, $rootIds); $this->eventDispatcher->dispatch($event); return $event->rootIds(); } - private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $arrRootIDs): array + /** + * @param list $rootIds + * + * @return array + */ + private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $rootIds): array { if ($moduleModel->hofff_navigation_includeStart) { - return $arrRootIDs; + return $rootIds; } // if we do not want to show the root level $arrFirstIDs = []; - foreach ($arrRootIDs as $varRootID) { - if (isset($items->subItems[$varRootID])) { - $arrFirstIDs[] = $items->subItems[$varRootID]; + foreach ($rootIds as $varRootID) { + if (! isset($items->subItems[$varRootID])) { + continue; } + + $arrFirstIDs[] = $items->subItems[$varRootID]; } - return array_merge(... $arrFirstIDs); + return array_merge(...$arrFirstIDs); } + /** + * @param array $arrPage + * + * @return array + */ private function getRedirectPage(array $arrPage): array { if (! $arrPage['jumpTo']) { - $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $arrPage['id']); + $query = $this->redirectQueryBuilder->createFallbackQuery((int) $arrPage['id']); return $query->execute()->fetchAssociative(); } @@ -401,13 +440,13 @@ private function getRedirectPage(array $arrPage): array $intFallbackSearchID = $arrPage['id']; $intJumpToID = $arrPage['jumpTo']; do { - $query = $this->redirectPageQueryBuilder->createJumpToQuery((int) $intJumpToID); + $query = $this->redirectQueryBuilder->createJumpToQuery((int) $intJumpToID); $query->setParameter('id', $intJumpToID); $result = $query->execute(); $next = $result->fetchAssociative(); if (! $result->rowCount()) { - $query = $this->redirectPageQueryBuilder->createFallbackQuery((int) $intFallbackSearchID); + $query = $this->redirectQueryBuilder->createFallbackQuery((int) $intFallbackSearchID); $next = $query->execute()->fetchAssociative(); break; } diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 6092d15..82bbb69 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -1,5 +1,7 @@ verkettete
Weiterleitungen, welche die aktuelle Seite als Weiterleitungsendziel besitzen nicht mehr als aktiv gekennzeichnet werden (kein "isActive" mehr im Template und keine "active" CSS-Klasse).', ]; -$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_showErrorPages'] - = ['Fehlerseiten anzeigen', 'Fehlerseiten vom Typ "403" und "404" werden in der Navigation angezeigt.']; -$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_disableEvents'] - = [ +$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_showErrorPages'] = [ + 'Fehlerseiten anzeigen', + 'Fehlerseiten vom Typ "403" und "404" werden in der Navigation angezeigt.', +]; +$GLOBALS['TL_LANG']['tl_module']['hofff_navigation_disableEvents'] = [ 'Events deaktivieren', 'Deaktiviert das Ausführen der Navigations-Events. Kann zu einer besseren Performance führen, wenn Events für diese Navigation nicht notwendig sind.', ]; From 452ffe3fa73150a555445e3c6f75aa8aae767955 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 38/75] Enable psalm type checks --- .phpcq.yaml.dist | 2 +- psalm.xml | 29 ++++- src/Event/MenuEvent.php | 8 +- .../Dca/NavigationDcaListener.php | 5 +- src/FrontendModule/ModuleNavigationMenu.php | 1 + src/Items/PageItems.php | 4 +- src/Items/PageItemsLoader.php | 118 ++++++++++-------- src/QueryBuilder/BaseQueryBuilder.php | 2 + src/Renderer/NavigationRenderer.php | 66 +++++----- src/Security/PagePermissionGuard.php | 9 ++ 10 files changed, 153 insertions(+), 91 deletions(-) create mode 100644 src/Security/PagePermissionGuard.php diff --git a/.phpcq.yaml.dist b/.phpcq.yaml.dist index c3b76bb..56699b1 100644 --- a/.phpcq.yaml.dist +++ b/.phpcq.yaml.dist @@ -65,7 +65,7 @@ tasks: - phpcpd - phpmd - phpcs - # - psalm + - psalm - phpunit default: diff --git a/psalm.xml b/psalm.xml index 5722456..6c23f41 100644 --- a/psalm.xml +++ b/psalm.xml @@ -1,6 +1,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Event/MenuEvent.php b/src/Event/MenuEvent.php index 277272b..fc47200 100644 --- a/src/Event/MenuEvent.php +++ b/src/Event/MenuEvent.php @@ -8,10 +8,10 @@ final class MenuEvent extends Event { - /** @var list */ + /** @var list */ private array $rootIds; - /** @param list $rootIds */ + /** @param list $rootIds */ public function __construct(ModuleModel $moduleModel, array $rootIds) { parent::__construct($moduleModel); @@ -19,13 +19,13 @@ public function __construct(ModuleModel $moduleModel, array $rootIds) $this->rootIds = $rootIds; } - /** @param list $rootIds */ + /** @param list $rootIds */ public function changeRootIds(array $rootIds): void { $this->rootIds = $rootIds; } - /** @return list */ + /** @return list */ public function rootIds(): array { return $this->rootIds; diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index df4b2d4..a89481d 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -14,7 +14,8 @@ use function implode; use function sprintf; -class NavigationDcaListener +/** @psalm-suppress PropertyNotSetInConstructor */ +final class NavigationDcaListener { private ContaoFramework $framework; @@ -56,7 +57,7 @@ public function saveStop(string $value): string $minimum = -1; $stop = []; - foreach (array_map('intval', explode(',', (string) $value)) as $intLevel) { + foreach (array_map('intval', explode(',', $value)) as $intLevel) { if ($intLevel <= $minimum) { continue; } diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 7086774..e2b0fd3 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -54,6 +54,7 @@ * _description * * @FrontendModule("hofff_navigation_menu", category="navigation") + * @psalm-suppress PropertyNotSetInConstructor */ final class ModuleNavigationMenu extends AbstractFrontendModuleController { diff --git a/src/Items/PageItems.php b/src/Items/PageItems.php index 30060c3..33807bd 100644 --- a/src/Items/PageItems.php +++ b/src/Items/PageItems.php @@ -11,13 +11,13 @@ final class PageItems /** @var array */ public array $roots = []; - /** @var array */ + /** @var array> */ public array $items = []; /** @var array> */ public array $subItems = []; - /** @var array */ + /** @var list */ public array $trail = []; public function isInTrail(int $pageId): bool diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index 6291834..ca14135 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -9,10 +9,12 @@ use Contao\StringUtil; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; +use Doctrine\DBAL\Result; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; use Symfony\Component\Security\Core\Security; use function array_diff; +use function array_fill_keys; use function array_flip; use function array_intersect; use function array_keys; @@ -35,10 +37,13 @@ final class PageItemsLoader private Security $security; - private ?PageQueryBuilder $pageQueryBuilder; + /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ + private PageQueryBuilder $pageQueryBuilder; + /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ private PageItems $items; + /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ private ModuleModel $moduleModel; /** @var list */ @@ -74,7 +79,7 @@ public function load( $this->hardLevel = $hardLevel; $this->activeId = $activeId; - $this->items->roots = array_flip($this->calculateRootIDs()); + $this->items->roots = array_fill_keys(array_flip($this->calculateRootIDs()), true); if (! $this->items->roots) { return $this->items; } @@ -89,6 +94,7 @@ public function load( $this->fetchItems($rootIds, 2); + /** @psalm-var Result $result */ $result = $this->pageQueryBuilder->createRootInformationQuery($rootIds)->execute(); while ($row = $result->fetchAssociative()) { $this->items->items[$row['id']] = $row; @@ -140,14 +146,16 @@ protected function fetchItems(array $parentIds, int $level = 1): array $arrEndPIDs = []; } + /** @psalm-var Result $result */ $result = $this->pageQueryBuilder->createFetchItemsQuery($parentIds)->execute(); if ($result->rowCount() === 0) { break; } $parentIds = []; + /** @psalm-var Result $result */ while ($page = $result->fetchAssociative()) { - if (isset($items->items[$page['id']])) { + if (isset($this->items->items[$page['id']])) { continue; } @@ -163,7 +171,7 @@ protected function fetchItems(array $parentIds, int $level = 1): array $this->items->items[(int) $page['id']] = $page; // item datasets $parentIds[] = $page['id']; // ids of current layer (for next layer pids) $fetched[$page['id']] = true; // fetched in this method - } elseif (! isset($items->subItems[(int) $page['pid']])) { + } elseif (! isset($this->items->subItems[(int) $page['pid']])) { $this->items->subItems[(int) $page['pid']] = []; } } @@ -175,15 +183,15 @@ protected function fetchItems(array $parentIds, int $level = 1): array } /** - * @return list + * @return list * * @SuppressWarnings(PHPMD.Superglobals) */ - protected function calculateRootIDs(): array + private function calculateRootIDs(): array { $rootIds = $this->getRootIds(); if ($this->moduleModel->hofff_navigation_currentAsRoot) { - array_unshift($rootIds, $GLOBALS['objPage']->id); + array_unshift($rootIds, (int) $GLOBALS['objPage']->id); } if ($this->moduleModel->hofff_navigation_start > 0) { @@ -205,9 +213,9 @@ protected function calculateRootIDs(): array $stopLevels = $this->stopLevels; if ($stopLevels[0] === 0) { // special case, keep only roots within the current path - $path = $GLOBALS['objPage']->trail; + $path = array_map('intval', $GLOBALS['objPage']->trail); $path[] = $this->activeId; - $rootIds = array_intersect($rootIds, $path); + $rootIds = array_values(array_intersect($rootIds, $path)); } return $rootIds; @@ -289,7 +297,7 @@ public function isPermissionDenied(array $page): bool * * @SuppressWarnings(PHPMD.Superglobals) */ - protected function getRootIds(): array + private function getRootIds(): array { if (! $this->moduleModel->hofff_navigation_defineRoots) { return [(int) $GLOBALS['objPage']->rootId]; @@ -317,27 +325,30 @@ protected function getRootIds(): array * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * - * @param list $arrPages An array of page IDs to filter + * @param list $pageIds An array of page IDs to filter * - * @return list Filtered array of page IDs + * @return list Filtered array of page IDs * * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - public function filterPages(array $arrPages, QueryBuilder $queryBuilder): array + private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array { - if (! $arrPages) { - return $arrPages; + if (! $pageIds) { + return $pageIds; } $queryBuilder ->andWhere('id IN (:ids)') - ->setParameter('ids', array_keys(array_flip($arrPages)), Connection::PARAM_STR_ARRAY); + ->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); + /** @psalm-var Result $result */ $result = $queryBuilder->execute(); if (! $this->isPermissionCheckRequired()) { - return array_intersect( - $arrPages, - array_map(static fn (array $row): int => (int) $row['id'], $result->fetchAllAssociative()) + return array_values( + array_intersect( + $pageIds, + array_map(static fn (array $row): int => (int) $row['id'], $result->fetchAllAssociative()) + ) ); } // restore order @@ -367,7 +378,8 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder): array $arrIDs = $arrPIDs; $arrPIDs = []; - $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($arrIDs)); + $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($arrIDs)); + /** @psalm-var Result $result */ $result = $query->execute(); while ($arrPage = $result->fetchAssociative()) { @@ -383,7 +395,7 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder): array } } - return array_intersect($arrPages, $arrValid); + return array_values(array_intersect($pageIds, $arrValid)); } /** @@ -394,44 +406,45 @@ public function filterPages(array $arrPages, QueryBuilder $queryBuilder): array * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * - * @param list $arrPages An array of parent IDs + * @param list $pageIds An array of parent IDs * - * @return list The child IDs + * @return list The child IDs */ - public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array + public function getNextLevel(array $pageIds, QueryBuilder $queryBuilder): array { - if (! $arrPages) { - return $arrPages; + if (! $pageIds) { + return $pageIds; } - $queryBuilder->setParameter('ids', array_keys(array_flip($arrPages)), Connection::PARAM_STR_ARRAY); + $queryBuilder->setParameter('ids', array_keys(array_flip($pageIds)), Connection::PARAM_STR_ARRAY); + /** @psalm-var Result */ $result = $queryBuilder->execute(); - $arrNext = []; + $next = []; if ($this->isPermissionCheckRequired()) { - while ($arrPage = $result->fetchAssociative()) { - if ($this->isPermissionDenied($arrPage)) { + while ($page = $result->fetchAssociative()) { + if ($this->isPermissionDenied($page)) { continue; } - $arrNext[$arrPage['pid']][] = $arrPage['id']; + $next[(int) $page['pid']][] = (int) $page['id']; } } else { - while ($arrPage = $result->fetchAssociative()) { - $arrNext[$arrPage['pid']][] = $arrPage['id']; + while ($page = $result->fetchAssociative()) { + $next[(int) $page['pid']][] = (int) $page['id']; } } - $arrNextLevel = []; - foreach ($arrPages as $intID) { - if (! isset($arrNext[$intID])) { + $nextLevel = []; + foreach ($pageIds as $intID) { + if (! isset($next[$intID])) { continue; } - $arrNextLevel = array_merge($arrNextLevel, $arrNext[$intID]); + $nextLevel = array_merge($nextLevel, $next[$intID]); } - return $arrNextLevel; + return $nextLevel; } /** @@ -443,32 +456,33 @@ public function getNextLevel(array $arrPages, QueryBuilder $queryBuilder): array * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages * contains no hazardous code. * - * @param list $arrPages An array of child IDs + * @param list $pageIds An array of child IDs * - * @return list The parent IDs + * @return list The parent IDs */ - public function getPrevLevel(array $arrPages): array + private function getPrevLevel(array $pageIds): array { - if (! $arrPages) { - return $arrPages; + if (! $pageIds) { + return $pageIds; } - $result = $this->pageQueryBuilder->createPreviousLevelQuery(array_keys(array_flip($arrPages)))->execute(); - $arrPrev = []; + /** @psalm-var Result $result */ + $result = $this->pageQueryBuilder->createPreviousLevelQuery($pageIds)->execute(); + $previous = []; while ($row = $result->fetchAssociative()) { - $arrPrev[$row['id']] = $row['pid']; + $previous[(int) $row['id']] = (int) $row['pid']; } - $arrPrevLevel = []; - $intPID = -1; - foreach ($arrPages as $intID) { - if (! isset($arrPrev[$intID]) || $arrPrev[$intID] === $intPID) { + $prevLevel = []; + $parentId = -1; + foreach ($pageIds as $pageId) { + if (! isset($previous[$pageId]) || $previous[$pageId] === $parentId) { continue; } - $arrPrevLevel[] = $intPID = $arrPrev[$intID]; + $prevLevel[] = $parentId = $previous[$pageId]; } - return $arrPrevLevel; + return $prevLevel; } } diff --git a/src/QueryBuilder/BaseQueryBuilder.php b/src/QueryBuilder/BaseQueryBuilder.php index 59645ce..99382f2 100644 --- a/src/QueryBuilder/BaseQueryBuilder.php +++ b/src/QueryBuilder/BaseQueryBuilder.php @@ -35,6 +35,7 @@ protected function query(string $name, callable $builder): QueryBuilder return clone $this->queries[$name]; } + /** @return static */ protected function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGuests = false): self { if ($showGuests) { @@ -48,6 +49,7 @@ protected function addGuestsQueryParts(QueryBuilder $queryBuilder, bool $showGue return $this; } + /** @return static */ protected function addPublishedCondition(QueryBuilder $queryBuilder, bool $respectPublished = true): self { if (! $respectPublished || $this->security->isGranted('ROLE_USER')) { diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 210f2b3..18493d1 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -9,6 +9,7 @@ use Contao\ModuleModel; use Contao\PageModel; use Contao\StringUtil; +use Doctrine\DBAL\Result; use Hofff\Contao\Navigation\Event\ItemEvent; use Hofff\Contao\Navigation\Event\MenuEvent; use Hofff\Contao\Navigation\Event\TreeEvent; @@ -50,10 +51,10 @@ public function __construct( * Adds CSS classes "first" and "last" to the appropriate navigation item arrays. * If the given array is empty, the empty string is returned. * - * @param list $itemIds The navigation items arrays - * @param list $stopLimit (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param int $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. - * @param int $currentLevel (optional, defaults to 1) The current level of this navigation layer + * @param list $itemIds The navigation items arrays + * @param list $stopLimit (optional, defaults to PHP_INT_MAX) The soft limit of depth. + * @param int $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param int $currentLevel (optional, defaults to 1) The current level of this navigation layer * * @return string The parsed navigation template, could be empty string. */ @@ -63,8 +64,8 @@ public function render( array $itemIds, array $stopLimit = [PHP_INT_MAX], int $intHard = PHP_INT_MAX, - int $currentLevel = 1, - ?int $activeId = null + ?int $activeId = null, + int $currentLevel = 1 ): string { if ($stopLimit === []) { $stopLimit = [PHP_INT_MAX]; @@ -77,6 +78,8 @@ public function render( $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); if ($moduleModel->hofff_navigation_hideSingleLevel) { + $hasMultipleLevels = false; + foreach ($firstIds as $id) { if ($items->subItems[$id]) { $hasMultipleLevels = true; @@ -384,9 +387,9 @@ private function dispatchTreeEvent(ModuleModel $moduleModel, PageItems $items): * * And should return a new root array or null * - * @param list $rootIds The root pages before hook execution + * @param list $rootIds The root pages before hook execution * - * @return list $arrRootIDs The root pages after hook execution + * @return list $arrRootIDs The root pages after hook execution */ private function dispatchMenuEvent(ModuleModel $moduleModel, array $rootIds): array { @@ -401,9 +404,9 @@ private function dispatchMenuEvent(ModuleModel $moduleModel, array $rootIds): ar } /** - * @param list $rootIds + * @param list $rootIds * - * @return array + * @return list */ private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $rootIds): array { @@ -412,47 +415,52 @@ private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $it } // if we do not want to show the root level - $arrFirstIDs = []; - foreach ($rootIds as $varRootID) { - if (! isset($items->subItems[$varRootID])) { + $firstIds = []; + foreach ($rootIds as $rootId) { + if (! isset($items->subItems[$rootId])) { continue; } - $arrFirstIDs[] = $items->subItems[$varRootID]; + $firstIds[] = $items->subItems[$rootId]; } - return array_merge(...$arrFirstIDs); + return array_merge(...$firstIds); } /** - * @param array $arrPage + * @param array $page * * @return array */ - private function getRedirectPage(array $arrPage): array + private function getRedirectPage(array $page): array { - if (! $arrPage['jumpTo']) { - $query = $this->redirectQueryBuilder->createFallbackQuery((int) $arrPage['id']); + if (! $page['jumpTo']) { + $query = $this->redirectQueryBuilder->createFallbackQuery((int) $page['id']); + /** @psalm-var Result $result */ + $result = $query->execute(); - return $query->execute()->fetchAssociative(); + return $result->fetchAssociative() ?: []; } - $intFallbackSearchID = $arrPage['id']; - $intJumpToID = $arrPage['jumpTo']; + $fallbackSearchId = $page['id']; + $jumpToId = $page['jumpTo']; do { - $query = $this->redirectQueryBuilder->createJumpToQuery((int) $intJumpToID); - $query->setParameter('id', $intJumpToID); + $query = $this->redirectQueryBuilder->createJumpToQuery((int) $jumpToId); + $query->setParameter('id', $jumpToId); + /** @psalm-var Result $result */ $result = $query->execute(); - $next = $result->fetchAssociative(); + $next = $result->fetchAssociative() ?: []; if (! $result->rowCount()) { - $query = $this->redirectQueryBuilder->createFallbackQuery((int) $intFallbackSearchID); - $next = $query->execute()->fetchAssociative(); + $query = $this->redirectQueryBuilder->createFallbackQuery((int) $fallbackSearchId); + /** @psalm-var Result $result */ + $result = $query->execute(); + $next = $result->fetchAssociative() ?: []; break; } - $intFallbackSearchID = $intJumpToID; - $intJumpToID = $next['jumpTo'] ?? 0; + $fallbackSearchId = $jumpToId; + $jumpToId = $next['jumpTo'] ?? 0; } while ($next['type'] === 'forward'); return $next; diff --git a/src/Security/PagePermissionGuard.php b/src/Security/PagePermissionGuard.php new file mode 100644 index 0000000..9a30c4e --- /dev/null +++ b/src/Security/PagePermissionGuard.php @@ -0,0 +1,9 @@ + Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 39/75] Change naming --- .../Dca/NavigationDcaListener.php | 6 +- src/Items/PageItemsLoader.php | 68 +++++++++---------- src/Renderer/NavigationRenderer.php | 26 +++---- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index a89481d..d43909f 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -57,12 +57,12 @@ public function saveStop(string $value): string $minimum = -1; $stop = []; - foreach (array_map('intval', explode(',', $value)) as $intLevel) { - if ($intLevel <= $minimum) { + foreach (array_map('intval', explode(',', $value)) as $level) { + if ($level <= $minimum) { continue; } - $stop[] = $minimum = $intLevel; + $stop[] = $minimum = $level; } return implode(',', $stop); diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index ca14135..510fd30 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -129,21 +129,21 @@ protected function fetchItems(array $parentIds, int $level = 1): array $stopLevels = $this->stopLevels; while ($parentIds) { - // if $arrEndPIDs == $arrPIDs the next $arrPIDs will be empty -> leave loop + // if $endParentIds == $parentIds the next $parentIds will be empty -> leave loop if ($level > $this->hardLevel) { - $arrEndPIDs = $parentIds; + $endParentIds = $parentIds; } elseif ($level > $stopLevels[0]) { count($stopLevels) > 1 && array_shift($stopLevels); - $arrEndPIDs = []; - foreach ($parentIds as $intPID) { - if ($this->items->isInTrail((int) $intPID)) { + $endParentIds = []; + foreach ($parentIds as $parentId) { + if ($this->items->isInTrail((int) $parentId)) { continue; } - $arrEndPIDs[$intPID] = true; + $endParentIds[$parentId] = true; } } else { - $arrEndPIDs = []; + $endParentIds = []; } /** @psalm-var Result $result */ @@ -163,7 +163,7 @@ protected function fetchItems(array $parentIds, int $level = 1): array continue; } - if (! isset($arrEndPIDs[$page['pid']])) { + if (! isset($endParentIds[$page['pid']])) { if (! in_array((int) $page['id'], $this->items->subItems[(int) $page['pid']] ?? [])) { $this->items->subItems[(int) $page['pid']][] = (int) $page['id']; // for order of items } @@ -322,7 +322,7 @@ private function getRootIds(): array * this navigations settings. * Maintains relative order of the input array. * - * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * For performance reason $pageIds is NOT "intval"ed. Make sure $pageIds * contains no hazardous code. * * @param list $pageIds An array of page IDs to filter @@ -352,50 +352,50 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array ); } // restore order - $arrPIDs = []; - $arrValid = []; - while ($arrPage = $result->fetchAssociative()) { - if ($this->isPermissionDenied($arrPage)) { + $parentIds = []; + $valid = []; + while ($page = $result->fetchAssociative()) { + if ($this->isPermissionDenied($page)) { continue; } - $arrValid[] = $arrPage['id']; + $valid[] = $page['id']; /* * do not remove the protected check! permission denied checks for * more, but we need to know, if we must recurse to parent pages, * for permission check, which must not be done, when this page * defines access rights. */ - if ($arrPage['protected'] || $arrPage['pid'] === 0) { + if ($page['protected'] || $page['pid'] === 0) { continue; } - $arrPIDs[$arrPage['pid']][] = $arrPage['id']; + $parentIds[$page['pid']][] = $page['id']; } // exclude pages which are in a protected path - while (count($arrPIDs)) { - $arrIDs = $arrPIDs; - $arrPIDs = []; + while (count($parentIds)) { + $currentIds = $parentIds; + $parentIds = []; - $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($arrIDs)); + $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($currentIds)); /** @psalm-var Result $result */ $result = $query->execute(); - while ($arrPage = $result->fetchAssociative()) { - if (! $arrPage['protected']) { // do not remove, see above - if ($arrPage['pid'] !== 0) { - $arrPIDs[$arrPage['pid']] = isset($arrPIDs[$arrPage['pid']]) - ? array_merge($arrPIDs[$arrPage['pid']], $arrIDs[$arrPage['id']]) - : $arrIDs[$arrPage['id']]; + while ($page = $result->fetchAssociative()) { + if (! $page['protected']) { // do not remove, see above + if ($page['pid'] !== 0) { + $parentIds[$page['pid']] = isset($parentIds[$page['pid']]) + ? array_merge($parentIds[$page['pid']], $currentIds[$page['id']]) + : $currentIds[$page['id']]; } - } elseif ($this->isPermissionDenied($arrPage)) { - $arrValid = array_diff($arrValid, $arrIDs[$arrPage['id']]); + } elseif ($this->isPermissionDenied($page)) { + $valid = array_diff($valid, $currentIds[$page['id']]); } } } - return array_values(array_intersect($pageIds, $arrValid)); + return array_values(array_intersect($pageIds, $valid)); } /** @@ -403,7 +403,7 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array * given conditions, which are added to the WHERE clause of the query. * Maintains relative order of the input array. * - * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * For performance reason $pageIds is NOT "intval"ed. Make sure $pageIds * contains no hazardous code. * * @param list $pageIds An array of parent IDs @@ -436,12 +436,12 @@ public function getNextLevel(array $pageIds, QueryBuilder $queryBuilder): array } $nextLevel = []; - foreach ($pageIds as $intID) { - if (! isset($next[$intID])) { + foreach ($pageIds as $pageId) { + if (! isset($next[$pageId])) { continue; } - $nextLevel = array_merge($nextLevel, $next[$intID]); + $nextLevel = array_merge($nextLevel, $next[$pageId]); } return $nextLevel; @@ -453,7 +453,7 @@ public function getNextLevel(array $pageIds, QueryBuilder $queryBuilder): array * Maintains relative order of the input array and merges subsequent parent * IDs. * - * For performance reason $arrPages is NOT "intval"ed. Make sure $arrPages + * For performance reason $pageIds is NOT "intval"ed. Make sure $pageIds * contains no hazardous code. * * @param list $pageIds An array of child IDs diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 18493d1..3c92cff 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -53,7 +53,7 @@ public function __construct( * * @param list $itemIds The navigation items arrays * @param list $stopLimit (optional, defaults to PHP_INT_MAX) The soft limit of depth. - * @param int $intHard (optional, defaults to PHP_INT_MAX) The hard limit of depth. + * @param int $hardLevel (optional, defaults to PHP_INT_MAX) The hard limit of depth. * @param int $currentLevel (optional, defaults to 1) The current level of this navigation layer * * @return string The parsed navigation template, could be empty string. @@ -63,7 +63,7 @@ public function render( PageItems $items, array $itemIds, array $stopLimit = [PHP_INT_MAX], - int $intHard = PHP_INT_MAX, + int $hardLevel = PHP_INT_MAX, ?int $activeId = null, int $currentLevel = 1 ): string { @@ -96,7 +96,9 @@ public function render( array_shift($stopLimit); // special case renderNavigationTree cannot handle } - return trim($this->renderTree($moduleModel, $items, $firstIds, $stopLimit, $intHard, $currentLevel, $activeId)); + return trim( + $this->renderTree($moduleModel, $items, $firstIds, $stopLimit, $hardLevel, $currentLevel, $activeId) + ); } /** @@ -112,7 +114,7 @@ private function renderTree( PageItems $items, array $itemIds, array $stopLimit = [PHP_INT_MAX], - int $intHard = PHP_INT_MAX, + int $hardLevel = PHP_INT_MAX, int $currentLevel = 1, ?int $activeId = null ): string { @@ -120,7 +122,7 @@ private function renderTree( return ''; } - $intStop = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; + $stopLevel = $currentLevel >= $stopLimit[0] ? array_shift($stopLimit) : $stopLimit[0]; $renderedItems = []; $containsActive = false; @@ -159,11 +161,11 @@ private function renderTree( if (! isset($items->subItems[$itemId])) { $item['class'] .= ' leaf'; - } elseif ($currentLevel >= $intHard) { + } elseif ($currentLevel >= $hardLevel) { // we are at hard level, never draw submenu $item['class'] .= ' submenu leaf'; } elseif ( - $currentLevel >= $intStop + $currentLevel >= $stopLevel && ! $item['isInTrail'] && $itemId !== $activeId && $item['tid'] !== $activeId ) { @@ -176,7 +178,7 @@ private function renderTree( $items, $items->subItems[$itemId] ?? [], $stopLimit, - $intHard, + $hardLevel, $currentLevel + 1 ); } else { // should never be reached, if no hooks are used @@ -220,7 +222,7 @@ private function renderTree( private function compileTree(ModuleModel $moduleModel, PageItems $items): void { - $blnForwardResolution = ! $moduleModel->hofff_navigation_noForwardResolution; + $forwardResolution = ! $moduleModel->hofff_navigation_noForwardResolution; foreach ($items->items as $itemId => $item) { if ($item === []) { continue; @@ -230,7 +232,7 @@ private function compileTree(ModuleModel $moduleModel, PageItems $items): void $moduleModel, $items, $items->items[$itemId], - $blnForwardResolution + $forwardResolution ); } } @@ -383,13 +385,13 @@ private function dispatchTreeEvent(ModuleModel $moduleModel, PageItems $items): * Executes the navigation hook. * The callback receives the following parameters: * $this - This navigation module instance - * $arrRootIDs - The IDs of the first navigation level + * $rootIds - The IDs of the first navigation level * * And should return a new root array or null * * @param list $rootIds The root pages before hook execution * - * @return list $arrRootIDs The root pages after hook execution + * @return list $rootIds The root pages after hook execution */ private function dispatchMenuEvent(ModuleModel $moduleModel, array $rootIds): array { From fc3dd26ad785c7d3fdc557bddd99c86bbeea1451 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 40/75] Do not use global $objPage in the page items loader --- src/FrontendModule/ModuleNavigationMenu.php | 2 +- src/Items/PageItems.php | 21 +++++++++++++++++++-- src/Items/PageItemsLoader.php | 19 +++++++------------ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index e2b0fd3..a2b2329 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -80,7 +80,7 @@ protected function getResponse(Template $template, ModuleModel $model, Request $ ? null : (int) $GLOBALS['objPage']->id; - $items = $this->loader->load($model, $stopLevels, $hardLevel, $activeId); + $items = $this->loader->load($model, $GLOBALS['objPage'], $stopLevels, $hardLevel, $activeId); $navigation = $this->renderer->render( $model, diff --git a/src/Items/PageItems.php b/src/Items/PageItems.php index 33807bd..7ce3fb9 100644 --- a/src/Items/PageItems.php +++ b/src/Items/PageItems.php @@ -4,10 +4,17 @@ namespace Hofff\Contao\Navigation\Items; +use Contao\PageModel; + +use function array_flip; use function array_key_exists; +use function array_map; final class PageItems { + /** @psalm-readonly */ + public PageModel $currentPage; + /** @var array */ public array $roots = []; @@ -17,8 +24,18 @@ final class PageItems /** @var array> */ public array $subItems = []; - /** @var list */ - public array $trail = []; + /** + * Page trail as flipped array + * + * @var array + */ + private array $trail = []; + + public function __construct(PageModel $currentPage) + { + $this->currentPage = $currentPage; + $this->trail = array_flip(array_map('intval', $currentPage->trail)); + } public function isInTrail(int $pageId): bool { diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index 510fd30..3f06bda 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -6,6 +6,7 @@ use Contao\FrontendUser; use Contao\ModuleModel; +use Contao\PageModel; use Contao\StringUtil; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; @@ -61,18 +62,15 @@ public function __construct(Connection $connection, Security $security) /** * @param list $stopLevels - * - * @SuppressWarnings(PHPMD.Superglobals) */ public function load( ModuleModel $moduleModel, + PageModel $currentPage, array $stopLevels = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, ?int $activeId = null ): PageItems { - $this->items = new PageItems(); - $this->items->trail = array_flip(isset($GLOBALS['objPage']) ? $GLOBALS['objPage']->trail : []); - + $this->items = new PageItems($currentPage); $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $this->security, $moduleModel); $this->moduleModel = $moduleModel; $this->stopLevels = $stopLevels; @@ -184,14 +182,12 @@ protected function fetchItems(array $parentIds, int $level = 1): array /** * @return list - * - * @SuppressWarnings(PHPMD.Superglobals) */ private function calculateRootIDs(): array { $rootIds = $this->getRootIds(); if ($this->moduleModel->hofff_navigation_currentAsRoot) { - array_unshift($rootIds, (int) $GLOBALS['objPage']->id); + array_unshift($rootIds, (int) $this->items->currentPage->id); } if ($this->moduleModel->hofff_navigation_start > 0) { @@ -213,7 +209,7 @@ private function calculateRootIDs(): array $stopLevels = $this->stopLevels; if ($stopLevels[0] === 0) { // special case, keep only roots within the current path - $path = array_map('intval', $GLOBALS['objPage']->trail); + $path = array_map('intval', $this->items->currentPage->trail); $path[] = $this->activeId; $rootIds = array_values(array_intersect($rootIds, $path)); } @@ -294,13 +290,12 @@ public function isPermissionDenied(array $page): bool /** * @return list - * - * @SuppressWarnings(PHPMD.Superglobals) */ private function getRootIds(): array { if (! $this->moduleModel->hofff_navigation_defineRoots) { - return [(int) $GLOBALS['objPage']->rootId]; + /** @psalm-suppress RedundantCastGivenDocblockType */ + return [(int) $this->items->currentPage->rootId]; } return array_map( From 20582e5375f85bc28fe25b9f57acbb83bee23dfa Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 41/75] Extract permission check into separate service --- src/Items/PageItemsLoader.php | 90 ++++------------------------ src/Resources/config/services.xml | 5 ++ src/Security/PagePermissionGuard.php | 84 ++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 79 deletions(-) diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index 3f06bda..6d17b17 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -4,7 +4,6 @@ namespace Hofff\Contao\Navigation\Items; -use Contao\FrontendUser; use Contao\ModuleModel; use Contao\PageModel; use Contao\StringUtil; @@ -12,6 +11,7 @@ use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Result; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; +use Hofff\Contao\Navigation\Security\PagePermissionGuard; use Symfony\Component\Security\Core\Security; use function array_diff; @@ -38,6 +38,8 @@ final class PageItemsLoader private Security $security; + private PagePermissionGuard $guard; + /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ private PageQueryBuilder $pageQueryBuilder; @@ -54,10 +56,11 @@ final class PageItemsLoader private ?int $activeId = null; - public function __construct(Connection $connection, Security $security) + public function __construct(Connection $connection, Security $security, PagePermissionGuard $guard) { $this->connection = $connection; $this->security = $security; + $this->guard = $guard; } /** @@ -157,7 +160,7 @@ protected function fetchItems(array $parentIds, int $level = 1): array continue; } - if (! $this->isPermissionGranted($this->moduleModel, $page)) { + if (! $this->guard->isPermissionGranted($this->moduleModel, $page)) { continue; } @@ -217,77 +220,6 @@ private function calculateRootIDs(): array return $rootIds; } - public function isPermissionCheckRequired(): bool - { - return ! $this->security->isGranted('ROLE_USER') && ! $this->moduleModel->hofff_navigation_showProtected; - } - - /** - * Utility method. - * - * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! - * - * Checks if the current user has permission to view the page of the given - * page dataset, in regards to the current navigation settings and the - * permission requirements of the page. - * - * Context property: hofff_navigation_showProtected - * - * @param array $page The page dataset of the current page, with at least - * groups and protected attributes set. - * - * @return bool If the permission is granted true, otherwise false. - */ - public function isPermissionGranted(ModuleModel $model, array $page): bool - { - // be users have access everywhere - if ($this->security->isGranted('ROLE_USER')) { - return true; - } - - // protection is ignored - if ($model->hofff_navigation_showProtected) { - return true; - } - - return ! $this->isPermissionDenied($page); - } - - /** - * Utility method. - * - * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! - * - * Checks if the current user has no permission to view the page of the - * given page dataset, in regards to the permission requirements of the - * page. - * - * @param array $page The page dataset of the current page, with at least - * groups and protected attributes set. - * - * @return bool If the permission is denied true, otherwise false. - */ - public function isPermissionDenied(array $page): bool - { - // this page is not protected - if (! $page['protected']) { - return false; - } - - $user = $this->security->getUser(); - if (! $user instanceof FrontendUser) { - return true; - } - - // the current user is not in any group - if (! $user->groups) { - return true; - } - - // check if the current user is not in any group, which is allowed to access the current page - return ! array_intersect((array) $user->groups, StringUtil::deserialize($page['groups'], true)); - } - /** * @return list */ @@ -338,7 +270,7 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array /** @psalm-var Result $result */ $result = $queryBuilder->execute(); - if (! $this->isPermissionCheckRequired()) { + if (! $this->guard->isPermissionCheckRequired($this->moduleModel)) { return array_values( array_intersect( $pageIds, @@ -350,7 +282,7 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array $parentIds = []; $valid = []; while ($page = $result->fetchAssociative()) { - if ($this->isPermissionDenied($page)) { + if ($this->guard->isPermissionDenied($page)) { continue; } @@ -384,7 +316,7 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array ? array_merge($parentIds[$page['pid']], $currentIds[$page['id']]) : $currentIds[$page['id']]; } - } elseif ($this->isPermissionDenied($page)) { + } elseif ($this->guard->isPermissionDenied($page)) { $valid = array_diff($valid, $currentIds[$page['id']]); } } @@ -416,9 +348,9 @@ public function getNextLevel(array $pageIds, QueryBuilder $queryBuilder): array $result = $queryBuilder->execute(); $next = []; - if ($this->isPermissionCheckRequired()) { + if ($this->guard->isPermissionCheckRequired($this->moduleModel)) { while ($page = $result->fetchAssociative()) { - if ($this->isPermissionDenied($page)) { + if ($this->guard->isPermissionDenied($page)) { continue; } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 8277f5c..7883638 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -19,6 +19,7 @@ + @@ -35,5 +36,9 @@ + + + + diff --git a/src/Security/PagePermissionGuard.php b/src/Security/PagePermissionGuard.php index 9a30c4e..c237f71 100644 --- a/src/Security/PagePermissionGuard.php +++ b/src/Security/PagePermissionGuard.php @@ -4,6 +4,90 @@ namespace Hofff\Contao\Navigation\Security; +use Contao\FrontendUser; +use Contao\ModuleModel; +use Contao\StringUtil; +use Symfony\Component\Security\Core\Security; + +use function array_intersect; + final class PagePermissionGuard { + private Security $security; + + public function __construct(Security $security) + { + $this->security = $security; + } + + public function isPermissionCheckRequired(ModuleModel $model): bool + { + return ! $this->security->isGranted('ROLE_USER') && ! $model->hofff_navigation_showProtected; + } + + /** + * Utility method. + * + * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! + * + * Checks if the current user has permission to view the page of the given + * page dataset, in regards to the current navigation settings and the + * permission requirements of the page. + * + * Context property: hofff_navigation_showProtected + * + * @param array $page The page dataset of the current page, with at least + * groups and protected attributes set. + * + * @return bool If the permission is granted true, otherwise false. + */ + public function isPermissionGranted(ModuleModel $model, array $page): bool + { + // be users have access everywhere + if ($this->security->isGranted('ROLE_USER')) { + return true; + } + + // protection is ignored + if ($model->hofff_navigation_showProtected) { + return true; + } + + return ! $this->isPermissionDenied($page); + } + + /** + * Utility method. + * + * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! + * + * Checks if the current user has no permission to view the page of the + * given page dataset, in regards to the permission requirements of the + * page. + * + * @param array $page The page dataset of the current page, with at least + * groups and protected attributes set. + * + * @return bool If the permission is denied true, otherwise false. + */ + public function isPermissionDenied(array $page): bool + { + // this page is not protected + if (! $page['protected']) { + return false; + } + + $user = $this->security->getUser(); + if (! $user instanceof FrontendUser) { + return true; + } + + // the current user is not in any group + if (! $user->groups) { + return true; + } + + // check if the current user is not in any group, which is allowed to access the current page + return ! array_intersect((array) $user->groups, StringUtil::deserialize($page['groups'], true)); + } } From 73c60b8e3a8f51611d90a846e2ed25976e1dcfd0 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 42/75] Reduce complexity --- src/Renderer/NavigationRenderer.php | 143 ++++++++++------------------ 1 file changed, 50 insertions(+), 93 deletions(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 3c92cff..19d2ba8 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -15,6 +15,7 @@ use Hofff\Contao\Navigation\Event\TreeEvent; use Hofff\Contao\Navigation\Items\PageItems; use Hofff\Contao\Navigation\QueryBuilder\RedirectPageQueryBuilder; +use Symfony\Contracts\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use function array_merge; @@ -38,6 +39,12 @@ final class NavigationRenderer private EventDispatcherInterface $eventDispatcher; + /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ + private PageItems $items; + + /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ + private ModuleModel $moduleModel; + public function __construct( EventDispatcherInterface $eventDispatcher, RedirectPageQueryBuilder $redirectQueryBuilder @@ -67,15 +74,20 @@ public function render( ?int $activeId = null, int $currentLevel = 1 ): string { + $this->moduleModel = $moduleModel; + $this->items = $items; + if ($stopLimit === []) { $stopLimit = [PHP_INT_MAX]; } - $this->compileTree($moduleModel, $items); - $this->dispatchTreeEvent($moduleModel, $items); + $this->compileTree(); + $this->dispatchEvent(new TreeEvent($moduleModel, $items)); - $itemIds = $this->dispatchMenuEvent($moduleModel, $itemIds); - $firstIds = $this->getFirstNavigationLevel($moduleModel, $items, $itemIds); + $event = new MenuEvent($moduleModel, $itemIds); + $this->dispatchEvent($event); + $itemIds = $event->rootIds(); + $firstIds = $this->getFirstNavigationLevel($itemIds); if ($moduleModel->hofff_navigation_hideSingleLevel) { $hasMultipleLevels = false; @@ -97,7 +109,7 @@ public function render( } return trim( - $this->renderTree($moduleModel, $items, $firstIds, $stopLimit, $hardLevel, $currentLevel, $activeId) + $this->renderTree($firstIds, $stopLimit, $hardLevel, $currentLevel, $activeId) ); } @@ -110,8 +122,6 @@ public function render( * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ private function renderTree( - ModuleModel $moduleModel, - PageItems $items, array $itemIds, array $stopLimit = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, @@ -127,11 +137,11 @@ private function renderTree( $containsActive = false; foreach ($itemIds as $itemId) { - if (! isset($items->items[$itemId])) { + if (! isset($this->items->items[$itemId])) { continue; } - $item = $items->items[$itemId]; + $item = $this->items->items[$itemId]; if ($itemId === $activeId) { $containsActive = true; @@ -159,7 +169,7 @@ private function renderTree( $item['class'] .= ' trail'; } - if (! isset($items->subItems[$itemId])) { + if (! isset($this->items->subItems[$itemId])) { $item['class'] .= ' leaf'; } elseif ($currentLevel >= $hardLevel) { // we are at hard level, never draw submenu @@ -171,12 +181,10 @@ private function renderTree( ) { // we are at stop level and not trail and not active, never draw submenu $item['class'] .= ' submenu leaf'; - } elseif ($items->subItems[$itemId]) { + } elseif ($this->items->subItems[$itemId]) { $item['class'] .= ' submenu inner'; $item['subitems'] = $this->renderTree( - $moduleModel, - $items, - $items->subItems[$itemId] ?? [], + $this->items->subItems[$itemId] ?? [], $stopLimit, $hardLevel, $currentLevel + 1 @@ -209,29 +217,27 @@ private function renderTree( unset($item); - $objTemplate = new FrontendTemplate($moduleModel->navigationTpl ?: 'nav_default'); + $objTemplate = new FrontendTemplate($this->moduleModel->navigationTpl ?: 'nav_default'); $objTemplate->setData([ - 'module' => $moduleModel->row(), + 'module' => $this->moduleModel->row(), 'level' => 'level_' . $currentLevel, 'items' => $renderedItems, - 'type' => static::class, + 'type' => self::class, ]); return $objTemplate->parse(); } - private function compileTree(ModuleModel $moduleModel, PageItems $items): void + private function compileTree(): void { - $forwardResolution = ! $moduleModel->hofff_navigation_noForwardResolution; - foreach ($items->items as $itemId => $item) { + $forwardResolution = ! $this->moduleModel->hofff_navigation_noForwardResolution; + foreach ($this->items->items as $itemId => $item) { if ($item === []) { continue; } - $items->items[$itemId] = $this->compileNavigationItem( - $moduleModel, - $items, - $items->items[$itemId], + $this->items->items[$itemId] = $this->compileNavigationItem( + $this->items->items[$itemId], $forwardResolution ); } @@ -246,12 +252,8 @@ private function compileTree(ModuleModel $moduleModel, PageItems $items): void * * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - private function compileNavigationItem( - ModuleModel $moduleModel, - PageItems $items, - array $page, - bool $forwardResolution = true - ): array { + private function compileNavigationItem(array $page, bool $forwardResolution = true): array + { // fallback for dataset field collisions $page['_title'] = $page['title']; $page['_pageTitle'] = $page['pageTitle']; @@ -265,7 +267,7 @@ private function compileNavigationItem( $page['target'] = ''; // overwrite DB value $page['nofollow'] = strncmp($page['robots'], 'noindex', 7) === 0; $page['description'] = str_replace(["\n", "\r"], [' ', ''], $page['_description']); - $page['isInTrail'] = $items->isInTrail((int) $page['id']); + $page['isInTrail'] = $this->items->isInTrail((int) $page['id']); switch ($page['type']) { case 'forward': @@ -315,7 +317,10 @@ private function compileNavigationItem( break; } - return $this->dispatchItemEvent($moduleModel, $page); + $event = new ItemEvent($this->moduleModel, $page); + $this->dispatchEvent($event); + + return $event->item(); } /** @param array $page */ @@ -348,82 +353,25 @@ private function encodeEmailURL(string $href): string return StringUtil::encodeEmail($href); } - /** - * @param array $page - * - * @return array - */ - private function dispatchItemEvent(ModuleModel $moduleModel, array $page): array - { - if (! $moduleModel->hofff_navigation_disableHooks) { - return $page; - } - - $event = new ItemEvent($moduleModel, $page); - $this->eventDispatcher->dispatch($event); - - return $event->item(); - } - - /** - * Executes the tree hook, to dynamically add navigations items to the tree - * the navigation is rendered from. - * - * The callback receives the following parameters: - * $this - This navigation module instance - */ - private function dispatchTreeEvent(ModuleModel $moduleModel, PageItems $items): void - { - if (! $moduleModel->hofff_navigation_disableHooks) { - return; - } - - $this->eventDispatcher->dispatch(new TreeEvent($moduleModel, $items)); - } - - /** - * Executes the navigation hook. - * The callback receives the following parameters: - * $this - This navigation module instance - * $rootIds - The IDs of the first navigation level - * - * And should return a new root array or null - * - * @param list $rootIds The root pages before hook execution - * - * @return list $rootIds The root pages after hook execution - */ - private function dispatchMenuEvent(ModuleModel $moduleModel, array $rootIds): array - { - if ($moduleModel->hofff_navigation_disableHooks) { - return $rootIds; - } - - $event = new MenuEvent($moduleModel, $rootIds); - $this->eventDispatcher->dispatch($event); - - return $event->rootIds(); - } - /** * @param list $rootIds * * @return list */ - private function getFirstNavigationLevel(ModuleModel $moduleModel, PageItems $items, array $rootIds): array + private function getFirstNavigationLevel(array $rootIds): array { - if ($moduleModel->hofff_navigation_includeStart) { + if ($this->moduleModel->hofff_navigation_includeStart) { return $rootIds; } // if we do not want to show the root level $firstIds = []; foreach ($rootIds as $rootId) { - if (! isset($items->subItems[$rootId])) { + if (! isset($this->items->subItems[$rootId])) { continue; } - $firstIds[] = $items->subItems[$rootId]; + $firstIds[] = $this->items->subItems[$rootId]; } return array_merge(...$firstIds); @@ -467,4 +415,13 @@ private function getRedirectPage(array $page): array return $next; } + + private function dispatchEvent(Event $event): void + { + if (! $this->moduleModel->hofff_navigation_disableHooks) { + return; + } + + $this->eventDispatcher->dispatch($event); + } } From 6d3c58037ad1a646af0e2cd57f95392483fe1fa8 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 15:48:23 +0200 Subject: [PATCH 43/75] Move getFirstNavigationLevel to the PageItems class --- src/Items/PageItems.php | 21 +++++++++++++++++++++ src/Renderer/NavigationRenderer.php | 29 +++-------------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/Items/PageItems.php b/src/Items/PageItems.php index 7ce3fb9..647fc4e 100644 --- a/src/Items/PageItems.php +++ b/src/Items/PageItems.php @@ -9,6 +9,7 @@ use function array_flip; use function array_key_exists; use function array_map; +use function array_merge; final class PageItems { @@ -41,4 +42,24 @@ public function isInTrail(int $pageId): bool { return array_key_exists($pageId, $this->trail); } + + /** + * @param list $rootIds + * + * @return list + */ + public function getFirstNavigationLevel(array $rootIds): array + { + // if we do not want to show the root level + $firstIds = []; + foreach ($rootIds as $rootId) { + if (! isset($this->subItems[$rootId])) { + continue; + } + + $firstIds[] = $this->subItems[$rootId]; + } + + return array_merge(...$firstIds); + } } diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 19d2ba8..781ff6c 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -18,7 +18,6 @@ use Symfony\Contracts\EventDispatcher\Event; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -use function array_merge; use function array_shift; use function count; use function ltrim; @@ -87,7 +86,9 @@ public function render( $event = new MenuEvent($moduleModel, $itemIds); $this->dispatchEvent($event); $itemIds = $event->rootIds(); - $firstIds = $this->getFirstNavigationLevel($itemIds); + $firstIds = $this->moduleModel->hofff_navigation_includeStart + ? $itemIds + : $this->items->getFirstNavigationLevel($itemIds); if ($moduleModel->hofff_navigation_hideSingleLevel) { $hasMultipleLevels = false; @@ -353,30 +354,6 @@ private function encodeEmailURL(string $href): string return StringUtil::encodeEmail($href); } - /** - * @param list $rootIds - * - * @return list - */ - private function getFirstNavigationLevel(array $rootIds): array - { - if ($this->moduleModel->hofff_navigation_includeStart) { - return $rootIds; - } - - // if we do not want to show the root level - $firstIds = []; - foreach ($rootIds as $rootId) { - if (! isset($this->items->subItems[$rootId])) { - continue; - } - - $firstIds[] = $this->items->subItems[$rootId]; - } - - return array_merge(...$firstIds); - } - /** * @param array $page * From 8e560de4f896ea8eb5d9f73d425a680c44fe8a1f Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 16:10:29 +0200 Subject: [PATCH 44/75] Fix branch aliase --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index e6c46fd..24755cb 100644 --- a/composer.json +++ b/composer.json @@ -67,8 +67,8 @@ }, "extra": { "branch-alias": { - "dev-develop": "2.0.x", - "dev-master": "1.9.x" + "dev-develop": "2.0.x-dev", + "dev-master": "1.9.x-dev" }, "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin" } From 0abbec7c0d33729f8e1cf1da1bbfafe30f76eeac Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 30 May 2022 16:23:35 +0200 Subject: [PATCH 45/75] Fix phpcq toolchain --- .composer-require-checker.json | 10 ++++++++++ .gitignore | 1 + .phpcq.lock | 2 +- .phpcq.yaml.dist | 5 ----- phpunit.xml.dist | 24 ------------------------ 5 files changed, 12 insertions(+), 30 deletions(-) create mode 100644 .composer-require-checker.json delete mode 100644 phpunit.xml.dist diff --git a/.composer-require-checker.json b/.composer-require-checker.json new file mode 100644 index 0000000..c11ac16 --- /dev/null +++ b/.composer-require-checker.json @@ -0,0 +1,10 @@ +{ + "symbol-whitelist": [ + "null", "true", "false", + "static", "self", "parent", + "array", "string", "int", "float", "bool", "iterable", "callable", "void", "object", + "Contao\\ManagerPlugin\\Bundle\\BundlePluginInterface", + "Contao\\ManagerPlugin\\Bundle\\Parser\\ParserInterface", + "Contao\\ManagerPlugin\\Bundle\\Config\\BundleConfig" + ] +} diff --git a/.gitignore b/.gitignore index 0000e3b..f7c6dec 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ !/phpunit.xml.dist !/psalm.xml !/.github +!/.composer-require-checker.json diff --git a/.phpcq.lock b/.phpcq.lock index 483ad85..19a52b2 100644 --- a/.phpcq.lock +++ b/.phpcq.lock @@ -1 +1 @@ -{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/psalm-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"4.23.0","url":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar","requirements":{"php":{"php":"^7.1|^8","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar.asc"}}},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-require-checker-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"5b0fd8cd5e0f5761c53b9d5375b6f6ba50f148468896248f823cc2a48361adfd872556066764b1b544ff51ffd5de60d6f9a75050db00b257d807976ac761bc3a"},"tools":{"composer-require-checker":{"version":"4.0.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.0.0/composer-require-checker.phar","requirements":{"php":{"php":"^8.0","ext-json":"*","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.0.0/composer-require-checker.phar.asc"}}},"phpmd":{"api-version":"1.0.0","version":"1.0.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpmd-1.0.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"88e267b9c36b2edc85e924717606b626e005ac8d97b1f65f5331e2a3b3894dec2cf124f6187541bf759d026477b6d94daacc5d5c81bb09714a68ffabe5698dc5"},"tools":{"phpmd":{"version":"2.12.0","url":"https://github.com/phpmd/phpmd/releases/download/2.12.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":null}}},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}}},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}}},"phpcs":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcs-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar.asc"},"phpcbf":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar.asc"}}},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.26.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.26.0/composer-normalize.phar","requirements":{"php":{"php":"^7.4 || ^8.0"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.26.0/composer-normalize.phar.asc"}}},"phpunit":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpunit-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0"},"tool":{"phpunit":"^6.0 || ^7.0 || ^8.0 || ^9.0"}},"checksum":{"type":"sha-512","value":"c73f15658e3ba62665f09492ec91c3a6a715760bfaa88473a987538439fff442540148e086e46a6aa18ce55a3ea2fbf76caaa581384cb84a38859fcc609ae7e4"},"tools":{"phpunit":{"version":"9.5.20","url":"https://phar.phpunit.de/phpunit-9.5.20.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-xml":"*","ext-xmlwriter":"*"}},"checksum":{"type":"sha-256","value":"6becad2da5c37f5ad101cc665ef05a2f1a6a45d2427c8edcc74f72c92fb1e05a"},"signature":"https://phar.phpunit.de/phpunit-9.5.20.phar.asc"}}}},"tools":[]} \ No newline at end of file +{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/psalm-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"4.23.0","url":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar","requirements":{"php":{"php":"^7.1|^8","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar.asc"}}},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-require-checker-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"5b0fd8cd5e0f5761c53b9d5375b6f6ba50f148468896248f823cc2a48361adfd872556066764b1b544ff51ffd5de60d6f9a75050db00b257d807976ac761bc3a"},"tools":{"composer-require-checker":{"version":"3.8.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/3.8.0/composer-require-checker.phar","requirements":{"php":{"php":"^7.4 || ^8.0","ext-json":"*","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/3.8.0/composer-require-checker.phar.asc"}}},"phpmd":{"api-version":"1.0.0","version":"1.0.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpmd-1.0.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"88e267b9c36b2edc85e924717606b626e005ac8d97b1f65f5331e2a3b3894dec2cf124f6187541bf759d026477b6d94daacc5d5c81bb09714a68ffabe5698dc5"},"tools":{"phpmd":{"version":"2.12.0","url":"https://github.com/phpmd/phpmd/releases/download/2.12.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":null}}},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}}},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}}},"phpcs":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcs-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar.asc"},"phpcbf":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar.asc"}}},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.27.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.27.0/composer-normalize.phar","requirements":{"php":{"php":"^7.4 || ^8.0"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.27.0/composer-normalize.phar.asc"}}}},"tools":[]} \ No newline at end of file diff --git a/.phpcq.yaml.dist b/.phpcq.yaml.dist index 56699b1..52bef67 100644 --- a/.phpcq.yaml.dist +++ b/.phpcq.yaml.dist @@ -3,7 +3,6 @@ phpcq: - https://phpcq.github.io/repository/repository.json directories: - src - - tests artifact: .phpcq/build plugins: @@ -31,9 +30,6 @@ phpcq: composer-normalize: version: ^1.0 signed: false - phpunit: - version: ^1.0 - signed: false trusted-keys: # composer-require-checker - 033E5F8D801A2F8D @@ -66,7 +62,6 @@ tasks: - phpmd - phpcs - psalm - - phpunit default: - verify diff --git a/phpunit.xml.dist b/phpunit.xml.dist deleted file mode 100644 index b603254..0000000 --- a/phpunit.xml.dist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - ./src - - - - - ./tests - - - From 04a05d1016373cb059066b75af9f5f0518b75fff Mon Sep 17 00:00:00 2001 From: David Molineus Date: Tue, 31 May 2022 11:07:09 +0200 Subject: [PATCH 46/75] Restore compatibility with MySQL < 8.0 --- src/Migration/BackboneNavigationMigration.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 2ab92e9..523df8e 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -7,6 +7,7 @@ use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Schema\Column; use function is_int; use function sprintf; @@ -65,8 +66,9 @@ public function run(): MigrationResult $this->renameNavigationModules(); $affectedFields = $this->determineAffectedFields(); + $table = $this->connection->getSchemaManager()->listTableDetails('tl_module'); foreach ($affectedFields as $oldName => $newName) { - $this->renameField($oldName, $newName); + $this->renameField($table->getColumn(self::OLD_PREFIX . $oldName), $newName); } return $this->createResult(true); @@ -112,15 +114,14 @@ private function determineAffectedFields(): array return $fields; } - private function renameField(string $oldName, string $newName): void + private function renameField(Column $column, string $newName): void { + $platform = $this->connection->getDatabasePlatform(); $this->connection->executeStatement( sprintf( - 'ALTER TABLE tl_module RENAME COLUMN %s%s TO %s%s', - self::OLD_PREFIX, - $oldName, - self::NEW_PREFIX, - $newName, + 'ALTER TABLE tl_module CHANGE %s %s', + $column->getName(), + $platform->getColumnDeclarationSQL(self::NEW_PREFIX . $newName, $column->toArray()) ) ); } From 6ff4c6396991acfd14b851716faf4c24e0b62652 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 13 Jun 2022 09:36:58 +0200 Subject: [PATCH 47/75] Handle empty description --- src/Renderer/NavigationRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 781ff6c..86a8883 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -259,7 +259,7 @@ private function compileNavigationItem(array $page, bool $forwardResolution = tr $page['_title'] = $page['title']; $page['_pageTitle'] = $page['pageTitle']; $page['_target'] = $page['target']; - $page['_description'] = $page['description']; + $page['_description'] = $page['description'] ?? ''; $page['link'] = $page['_title']; $page['class'] = $page['cssClass'] . ' ' . $page['type']; From 10c266c4434fae21e16a38dc47100b1b6c57adb4 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 13 Jun 2022 09:39:29 +0200 Subject: [PATCH 48/75] Do not flip root keys. Array values will be used as keys by array_fill_keys --- src/Items/PageItemsLoader.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index 6d17b17..c1d49f4 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -80,7 +80,7 @@ public function load( $this->hardLevel = $hardLevel; $this->activeId = $activeId; - $this->items->roots = array_fill_keys(array_flip($this->calculateRootIDs()), true); + $this->items->roots = array_fill_keys($this->calculateRootIDs(), true); if (! $this->items->roots) { return $this->items; } From 189bb5d5de21adb8b36659de555b7bb135fac6aa Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 13 Jun 2022 09:41:15 +0200 Subject: [PATCH 49/75] Add missing customTpl field --- src/Resources/contao/dca/tl_module.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 82bbb69..85a973a 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -23,7 +23,7 @@ . ',hofff_navigation_showHidden,hofff_navigation_showProtected' . ',hofff_navigation_showGuests,hofff_navigation_isSitemap' . ',hofff_navigation_hideSingleLevel' - . ';{template_legend:hide},navigationTpl,hofff_navigation_addLegacyCss' + . ';{template_legend:hide},customTpl,navigationTpl,hofff_navigation_addLegacyCss' . ',hofff_navigation_addFields' . ';{protected_legend:hide},protected,guests' . ';{expert_legend:hide},cssID,hofff_navigation_noForwardResolution,hofff_navigation_showErrorPages' From 23372594afda645d2dc9071c04a2e11205bfac38 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 13 Jun 2022 14:34:57 +0200 Subject: [PATCH 50/75] Fix category name --- src/FrontendModule/ModuleNavigationMenu.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index a2b2329..c1b5455 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -53,7 +53,7 @@ * _target * _description * - * @FrontendModule("hofff_navigation_menu", category="navigation") + * @FrontendModule("hofff_navigation_menu", category="navigationMenu") * @psalm-suppress PropertyNotSetInConstructor */ final class ModuleNavigationMenu extends AbstractFrontendModuleController From 6ec70673ec3599ab2db71a44423223241e8d1e22 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Tue, 14 Jun 2022 12:02:28 +0200 Subject: [PATCH 51/75] Add roots fields to the fields which has to be migrated --- src/Migration/BackboneNavigationMigration.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 523df8e..783a5a8 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -21,6 +21,7 @@ final class BackboneNavigationMigration extends AbstractMigration private const NEW_PREFIX = 'hofff_navigation_'; private const FIELDS = [ + 'roots', 'roots_order', 'start', 'respectHidden', From b873449dbac94ebb7ba70f64382294a8b17f57da Mon Sep 17 00:00:00 2001 From: David Molineus Date: Tue, 14 Jun 2022 12:02:43 +0200 Subject: [PATCH 52/75] Drop leftover palette selector --- src/Resources/contao/dca/tl_module.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Resources/contao/dca/tl_module.php b/src/Resources/contao/dca/tl_module.php index 85a973a..75db810 100644 --- a/src/Resources/contao/dca/tl_module.php +++ b/src/Resources/contao/dca/tl_module.php @@ -4,7 +4,6 @@ use Doctrine\DBAL\Types\Types; -$GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_rootSelectionType'; $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineRoots'; $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_includeStart'; $GLOBALS['TL_DCA']['tl_module']['palettes']['__selector__'][] = 'hofff_navigation_defineStop'; From c138b5518052ebcf6008538e3b2312b0e870779e Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 22 Aug 2022 14:34:33 +0200 Subject: [PATCH 53/75] Fix active and trail page detection --- src/Renderer/NavigationRenderer.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 86a8883..8f49db2 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -155,7 +155,7 @@ private function renderTree( $item['isInTrail'] = true; } } else { // do not flatten if/else - if ($item['tid'] === $activeId) { + if (isset($item['id']) && $item['tid'] === $activeId) { if ($item['href'] === Environment::get('request')) { $item['isActive'] = true; // nothing else (active class is set in template) $item['isInTrail'] = false; @@ -188,7 +188,8 @@ private function renderTree( $this->items->subItems[$itemId] ?? [], $stopLimit, $hardLevel, - $currentLevel + 1 + $currentLevel + 1, + $activeId ); } else { // should never be reached, if no hooks are used $item['class'] .= ' leaf'; From 894015303dfc83f206d8e8c1b56782b3edcf9bc6 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Tue, 20 Dec 2022 11:57:55 +0100 Subject: [PATCH 54/75] Fix support of events --- src/Renderer/NavigationRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 8f49db2..c32707f 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -396,7 +396,7 @@ private function getRedirectPage(array $page): array private function dispatchEvent(Event $event): void { - if (! $this->moduleModel->hofff_navigation_disableHooks) { + if ($this->moduleModel->hofff_navigation_disableHooks) { return; } From 3c4cd7cdac7cc19af190b27c9f41ac079eb2d768 Mon Sep 17 00:00:00 2001 From: zonky2 Date: Thu, 13 Apr 2023 12:20:24 +0200 Subject: [PATCH 55/75] Add p to Stop --- src/Resources/contao/languages/de/tl_module.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Resources/contao/languages/de/tl_module.php b/src/Resources/contao/languages/de/tl_module.php index 2e23997..5cb8175 100644 --- a/src/Resources/contao/languages/de/tl_module.php +++ b/src/Resources/contao/languages/de/tl_module.php @@ -6,7 +6,7 @@ $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_legend'] = 'Navigations-Einstellungen'; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_start'] = [ - 'Startebene', + 'Start-Ebene', 'Relativ zu den Referenzseiten. Negative Werte sind möglich.', ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_currentAsRoot'] = [ @@ -36,20 +36,20 @@ ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_includeStart'] = [ - 'Startebene anzeigen', - 'Rendert die Startebene in die Navigation.', + 'Start-Ebene anzeigen', + 'Rendert die Start-Ebene in die Navigation.', ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_showHiddenStart'] = [ 'Versteckte Seiten anzeigen (Startebene)', 'Seiten in der Startebene mit der Option "Im Menü verstecken" trotzdem anzeigen.', ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_defineStop'] = [ - 'Stop-Ebenen anpassen', + 'Stopp-Ebenen anpassen', 'Ebenen die tiefer als die Stop-Ebenen liegen werden nur dann angezeigt, wenn diese sich im aktuellen Navigationspfad befinden.', ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_stop'] = [ - 'Stop-Ebenen', - 'Stop-Ebenen als nicht-negative Ganzzahl (0, 1, 2, ...). Es können mehrere Stop-Ebenen als aufsteigend sortierte, Komma-separierte Liste angegeben werden. Angaben sind relativ zur Startebene.', + 'Stopp-Ebenen', + 'Stopp-Ebenen als nicht-negative Ganzzahl (0, 1, 2, ...). Es können mehrere Stopp-Ebenen als aufsteigend sortierte, Komma-separierte Liste angegeben werden. Angaben sind relativ zur Startebene.', ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_defineHard'] = [ 'Anzahl maximal auszugebender Ebenen anpassen', @@ -57,7 +57,7 @@ ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_hard'] = [ 'Maximal auszugebende Ebenen', - 'Angabe als positive Ganzzahl (1, 2, 3, ...). Angaben sind relativ zur Startebene.', + 'Angabe als positive Ganzzahl (1, 2, 3, ...). Angaben sind relativ zur Start-Ebene.', ]; $GLOBALS['TL_LANG']['tl_module']['hofff_navigation_showProtected'] = [ 'Geschützte Seiten anzeigen', From 96306fc152f34d2dc4c4192ac3e1beb65447ca2d Mon Sep 17 00:00:00 2001 From: Stefan Heimes Date: Tue, 25 Apr 2023 12:46:32 +0200 Subject: [PATCH 56/75] Update PageQueryBuilder.php Add a missing "Connection::PARAM_STR_ARRAY" --- src/QueryBuilder/PageQueryBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 4eac122..66b18b9 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -193,7 +193,7 @@ static function (QueryBuilder $queryBuilder): void { } ); - $query->setParameter('ids', $pageIds); + $query->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); return $query; } From a994b6767f58d918771876b222542072c0b04d3b Mon Sep 17 00:00:00 2001 From: David Molineus Date: Fri, 28 Apr 2023 11:10:47 +0200 Subject: [PATCH 57/75] Escape fields --- src/QueryBuilder/PageQueryBuilder.php | 30 ++++++++++++++++++++++----- src/Renderer/NavigationRenderer.php | 4 ++-- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 66b18b9..7a94760 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -12,6 +12,7 @@ use function array_flip; use function array_keys; +use function array_map; use function array_merge; use function count; @@ -64,7 +65,12 @@ public function createFetchItemsQuery(array $parentIds): QueryBuilder __FUNCTION__, function (QueryBuilder $queryBuilder): void { $queryBuilder - ->select(...$this->fields) + ->select( + ...array_map( + fn (string $field) => $this->connection->quoteIdentifier($field), + $this->fields + ) + ) ->andWhere('type != :rootType') ->setParameter('rootType', 'root') ->andWhere('pid IN (:pids)') @@ -128,8 +134,12 @@ public function createStartRootIdsQuery(): QueryBuilder return $this->query( __FUNCTION__, function (QueryBuilder $queryBuilder): void { - $queryBuilder - ->select('id', 'pid', 'protected', 'groups'); + $queryBuilder->select( + ...array_map( + fn (string $field) => $this->connection->quoteIdentifier($field), + ['id', 'pid', 'protected', 'groups'] + ) + ); $this ->addHiddenCondition( @@ -154,7 +164,12 @@ public function createPageInformationQuery(array $pageIds): QueryBuilder __FUNCTION__, static function (QueryBuilder $queryBuilder): void { $queryBuilder - ->select('id', 'pid', 'protected', 'groups') + ->select( + ...array_map( + fn (string $field) => $this->connection->quoteIdentifier($field), + ['id', 'pid', 'protected', 'groups'] + ) + ) ->where('id IN (:ids)'); } ); @@ -171,7 +186,12 @@ public function createRootInformationQuery(array $rootIds): QueryBuilder __FUNCTION__, function (QueryBuilder $queryBuilder): void { $queryBuilder - ->select(...$this->fields) + ->select( + ...array_map( + fn (string $field) => $this->connection->quoteIdentifier($field), + $this->fields + ) + ) ->where('id IN (:rootIds)'); } ); diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index c32707f..82cbfe8 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -183,7 +183,7 @@ private function renderTree( // we are at stop level and not trail and not active, never draw submenu $item['class'] .= ' submenu leaf'; } elseif ($this->items->subItems[$itemId]) { - $item['class'] .= ' submenu inner'; + $item['class'] .= ' submenu inner'; $item['subitems'] = $this->renderTree( $this->items->subItems[$itemId] ?? [], $stopLimit, @@ -365,7 +365,7 @@ private function getRedirectPage(array $page): array if (! $page['jumpTo']) { $query = $this->redirectQueryBuilder->createFallbackQuery((int) $page['id']); /** @psalm-var Result $result */ - $result = $query->execute(); + $result = $query->execute(); return $result->fetchAssociative() ?: []; } From a841e7f35c975f9560e2dc849b894f966aef0547 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Fri, 28 Apr 2023 14:53:55 +0200 Subject: [PATCH 58/75] Quote another identifiers --- src/QueryBuilder/PageQueryBuilder.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 7a94760..e5236a4 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -105,7 +105,12 @@ public function createRootIdsQuery(): QueryBuilder __FUNCTION__, function (QueryBuilder $queryBuilder): void { $queryBuilder - ->select('id', 'pid', 'protected', 'groups'); + ->select( + ...array_map( + fn (string $field) => $this->connection->quoteIdentifier($field), + ['id', 'pid', 'protected', 'groups'] + ) + ); $this ->addHiddenCondition( @@ -162,7 +167,7 @@ public function createPageInformationQuery(array $pageIds): QueryBuilder { $query = $this->query( __FUNCTION__, - static function (QueryBuilder $queryBuilder): void { + function (QueryBuilder $queryBuilder): void { $queryBuilder ->select( ...array_map( From b1ae0322c633a7137a33ebde92cd50652f7e4254 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Tue, 27 Jun 2023 15:13:50 +0200 Subject: [PATCH 59/75] Ensure default array keys used by Contao exists --- src/Renderer/NavigationRenderer.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 82cbfe8..9ed17f4 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -106,7 +106,11 @@ public function render( } if ($stopLimit[0] === 0) { - array_shift($stopLimit); // special case renderNavigationTree cannot handle + // special case renderNavigationTree cannot handle + array_shift($stopLimit); + if ($stopLimit === []) { + $stopLimit = [PHP_INT_MAX]; + } } return trim( @@ -142,25 +146,25 @@ private function renderTree( continue; } - $item = $this->items->items[$itemId]; + $item = $this->items->items[$itemId]; + $item['rel'] ??= ''; + $item['subitems'] ??= ''; + $item['isActive'] ??= false; + $item['isInTrail'] ??= false; if ($itemId === $activeId) { $containsActive = true; if ($item['href'] === Environment::get('request')) { $item['isActive'] = true; // nothing else (active class is set in template) - $item['isInTrail'] = false; } else { - $item['isActive'] = false; // nothing else (active class is set in template) $item['isInTrail'] = true; } } else { // do not flatten if/else - if (isset($item['id']) && $item['tid'] === $activeId) { + if (isset($item['tid']) && $item['tid'] === $activeId) { if ($item['href'] === Environment::get('request')) { $item['isActive'] = true; // nothing else (active class is set in template) - $item['isInTrail'] = false; } else { - $item['isActive'] = false; // nothing else (active class is set in template) $item['isInTrail'] = true; } } @@ -193,6 +197,7 @@ private function renderTree( ); } else { // should never be reached, if no hooks are used $item['class'] .= ' leaf'; + $item['subitems'] = null; } $renderedItems[] = $item; @@ -200,7 +205,7 @@ private function renderTree( if ($containsActive) { foreach ($renderedItems as &$item) { - if ($item['isActive']) { + if ($item['isActive'] ?? false) { continue; } From c379b2ec52f4e6544c60f2caa46b6baf75334c2b Mon Sep 17 00:00:00 2001 From: David Maack Date: Wed, 26 Jul 2023 15:58:40 +0200 Subject: [PATCH 60/75] Update PageQueryBuilder.php Don't quote the *, it will cause an error in newer DBAL versions --- src/QueryBuilder/PageQueryBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index e5236a4..c4c24c1 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -67,7 +67,7 @@ function (QueryBuilder $queryBuilder): void { $queryBuilder ->select( ...array_map( - fn (string $field) => $this->connection->quoteIdentifier($field), + fn (string $field) => ($field !== '*') ? $this->connection->quoteIdentifier($field) : $field, $this->fields ) ) From 5406ed365f29e5010dd025f77274671bd28aff12 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 13:35:24 +0100 Subject: [PATCH 61/75] Allow Contao 5.3 and fix new detected code issues --- .phpcq.lock | 2 +- .phpcq.yaml.dist | 8 +++++ composer.json | 19 ++++++------ psalm.xml | 11 ++++--- src/FrontendModule/ModuleNavigationMenu.php | 7 +++-- src/Items/PageItemsLoader.php | 26 +++++++--------- src/Migration/BackboneNavigationMigration.php | 2 +- src/QueryBuilder/PageQueryBuilder.php | 11 +++---- src/Renderer/NavigationRenderer.php | 30 ++++++++++--------- src/Security/PagePermissionGuard.php | 5 ++-- 10 files changed, 67 insertions(+), 54 deletions(-) diff --git a/.phpcq.lock b/.phpcq.lock index 19a52b2..31594ac 100644 --- a/.phpcq.lock +++ b/.phpcq.lock @@ -1 +1 @@ -{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/psalm-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"4.23.0","url":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar","requirements":{"php":{"php":"^7.1|^8","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/4.23.0/psalm.phar.asc"}}},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-require-checker-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"5b0fd8cd5e0f5761c53b9d5375b6f6ba50f148468896248f823cc2a48361adfd872556066764b1b544ff51ffd5de60d6f9a75050db00b257d807976ac761bc3a"},"tools":{"composer-require-checker":{"version":"3.8.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/3.8.0/composer-require-checker.phar","requirements":{"php":{"php":"^7.4 || ^8.0","ext-json":"*","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/3.8.0/composer-require-checker.phar.asc"}}},"phpmd":{"api-version":"1.0.0","version":"1.0.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpmd-1.0.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"88e267b9c36b2edc85e924717606b626e005ac8d97b1f65f5331e2a3b3894dec2cf124f6187541bf759d026477b6d94daacc5d5c81bb09714a68ffabe5698dc5"},"tools":{"phpmd":{"version":"2.12.0","url":"https://github.com/phpmd/phpmd/releases/download/2.12.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":null}}},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}}},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}}},"phpcs":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcs-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcs.phar.asc"},"phpcbf":{"version":"3.6.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.6.2/phpcbf.phar.asc"}}},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.27.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.27.0/composer-normalize.phar","requirements":{"php":{"php":"^7.4 || ^8.0"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.27.0/composer-normalize.phar.asc"}}}},"tools":[]} \ No newline at end of file +{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.2.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/psalm/psalm-1.2.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0 || ^5.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"5.22.1","url":"https://github.com/vimeo/psalm/releases/download/5.22.1/psalm.phar","requirements":{"php":{"php":"^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/5.22.1/psalm.phar.asc"}}},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/composer-require-checker/composer-require-checker-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"d5415bddfe024c5749d894034583882aee4e5c3e1087815d9fdd81cb5e71630f631a0e35de0ff84b97fbbf738c16ece5f83bd8c00695913eb846aa6f04577dc2"},"tools":{"composer-require-checker":{"version":"4.8.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.8.0/composer-require-checker.phar","requirements":{"php":{"php":"~8.2.0 || ~8.3.0","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.8.0/composer-require-checker.phar.asc"}}},"phpmd":{"api-version":"1.0.0","version":"1.0.2.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpmd/phpmd-1.0.2.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"f22280a6dec8dbdd2ec1d83b294f23237fe32c34f4a298e52038e0a7a0074d541635b2b488b1a6098a42d8418a6cd8eb804406ea82b91e362be2b5d11a0915b0"},"tools":{"phpmd":{"version":"2.15.0","url":"https://github.com/phpmd/phpmd/releases/download/2.15.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":"https://github.com/phpmd/phpmd/releases/download/2.15.0/phpmd.phar.asc"}}},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpcpd/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}}},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phploc/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}}},"phpcs":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpcs/phpcs-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.9.0","url":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-simplexml":"*","ext-tokenizer":"*","ext-xmlwriter":"*"}},"checksum":null,"signature":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcs.phar.asc"},"phpcbf":{"version":"3.9.0","url":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-simplexml":"*","ext-tokenizer":"*","ext-xmlwriter":"*"}},"checksum":null,"signature":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcbf.phar.asc"}}},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/composer-normalize/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.42.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.42.0/composer-normalize.phar","requirements":{"php":{"php":"~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0","ext-json":"*"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.42.0/composer-normalize.phar.asc"}}},"phpunit":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpunit/phpunit-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0"},"tool":{"phpunit":"^6.0 || ^7.0 || ^8.0 || ^9.0"}},"checksum":{"type":"sha-512","value":"c73f15658e3ba62665f09492ec91c3a6a715760bfaa88473a987538439fff442540148e086e46a6aa18ce55a3ea2fbf76caaa581384cb84a38859fcc609ae7e4"},"tools":{"phpunit":{"version":"9.6.16","url":"https://phar.phpunit.de/phpunit-9.6.16.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-xml":"*","ext-xmlwriter":"*"}},"checksum":{"type":"sha-256","value":"891d46f06284db3695498aff5dfd6a944f835e07db2981295db2c2bcf6cfd338"},"signature":"https://phar.phpunit.de/phpunit-9.6.16.phar.asc"}}}},"tools":[]} \ No newline at end of file diff --git a/.phpcq.yaml.dist b/.phpcq.yaml.dist index 52bef67..18b0d08 100644 --- a/.phpcq.yaml.dist +++ b/.phpcq.yaml.dist @@ -42,10 +42,12 @@ phpcq: - D2CCAC42F6295E7D # PHP_CodeSniffer - 31C7E470E2138192 + - 5E6DDE998AB73B8E # Composer normalize - C00543248C87FB13 # phpmd - 0F9684B8B16B7AB0 + - 9093F8B32E4815AA tasks: fix: @@ -93,7 +95,13 @@ tasks: <<: *phpcs-config fix: true + composer-normalize: + config: &composer-normalize-config + ignore_output: + - '#> pre-command-run: Contao\\ManagerPlugin\\Composer\\ArtifactsPlugin->preCommandRun#' + composer-normalize-fix: plugin: composer-normalize config: + <<: *composer-normalize-config dry_run: false diff --git a/composer.json b/composer.json index 24755cb..291d944 100644 --- a/composer.json +++ b/composer.json @@ -34,15 +34,15 @@ "source": "https://github.com/hofff/contao-navigation" }, "require": { - "php": "^7.4 || ^8.0", - "contao/core-bundle": "^4.9", - "doctrine/dbal": "^2.11 || ^3.0", - "symfony/config": "^4.4 || ^5.0", - "symfony/dependency-injection": "^4.4 || ^5.0", + "php": "^8.1", + "contao/core-bundle": "^4.13 || ^5.3", + "doctrine/dbal": "^3.8", + "symfony/config": "^5.4 || ^6.4", + "symfony/dependency-injection": "^5.4 || ^6.4", "symfony/event-dispatcher-contracts": "^1.1 || ^2.0 || ^3.0", - "symfony/http-foundation": "^4.4 || ^5.0", - "symfony/http-kernel": "^4.4 || ^5.0", - "symfony/security-core": "^4.4 || ^5.0" + "symfony/http-foundation": "^5.4 || ^6.4", + "symfony/http-kernel": "^5.4 || ^6.4", + "symfony/security-core": "^5.4 || ^6.4" }, "require-dev": { "contao/manager-plugin": "^2.0", @@ -62,7 +62,8 @@ "allow-plugins": { "contao-components/installer": false, "contao/manager-plugin": true, - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "php-http/discovery": true } }, "extra": { diff --git a/psalm.xml b/psalm.xml index 6c23f41..982c87b 100644 --- a/psalm.xml +++ b/psalm.xml @@ -15,12 +15,15 @@ + + + + + + - - - - + diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index c1b5455..92f6dd3 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -7,7 +7,6 @@ use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController; use Contao\CoreBundle\ServiceAnnotation\FrontendModule; use Contao\Environment; -use Contao\Input; use Contao\ModuleModel; use Contao\Template; use Hofff\Contao\Navigation\Items\PageItemsLoader; @@ -72,11 +71,13 @@ public function __construct(PageItemsLoader $loader, NavigationRenderer $rendere * @SuppressWarnings(PHPMD.Superglobals) * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ - protected function getResponse(Template $template, ModuleModel $model, Request $request): ?Response + protected function getResponse(Template $template, ModuleModel $model, Request $request): Response { $stopLevels = $this->getStopLevels($model); $hardLevel = $this->getHardLevel($model); - $activeId = $model->hofff_navigation_isSitemap || Input::get('articles') + + /** @psalm-suppress RiskyTruthyFalsyComparison */ + $activeId = $model->hofff_navigation_isSitemap || $request->query->has('articles') ? null : (int) $GLOBALS['objPage']->id; diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index c1d49f4..edadb6b 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -7,6 +7,7 @@ use Contao\ModuleModel; use Contao\PageModel; use Contao\StringUtil; +use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; use Doctrine\DBAL\Result; @@ -96,7 +97,7 @@ public function load( $this->fetchItems($rootIds, 2); /** @psalm-var Result $result */ - $result = $this->pageQueryBuilder->createRootInformationQuery($rootIds)->execute(); + $result = $this->pageQueryBuilder->createRootInformationQuery($rootIds)->executeQuery(); while ($row = $result->fetchAssociative()) { $this->items->items[$row['id']] = $row; $this->items->roots[$row['id']] = true; @@ -147,14 +148,12 @@ protected function fetchItems(array $parentIds, int $level = 1): array $endParentIds = []; } - /** @psalm-var Result $result */ - $result = $this->pageQueryBuilder->createFetchItemsQuery($parentIds)->execute(); + $result = $this->pageQueryBuilder->createFetchItemsQuery($parentIds)->executeQuery(); if ($result->rowCount() === 0) { break; } $parentIds = []; - /** @psalm-var Result $result */ while ($page = $result->fetchAssociative()) { if (isset($this->items->items[$page['id']])) { continue; @@ -190,6 +189,7 @@ private function calculateRootIDs(): array { $rootIds = $this->getRootIds(); if ($this->moduleModel->hofff_navigation_currentAsRoot) { + /** @psalm-suppress RedundantCastGivenDocblockType */ array_unshift($rootIds, (int) $this->items->currentPage->id); } @@ -266,9 +266,8 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array $queryBuilder ->andWhere('id IN (:ids)') - ->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); - /** @psalm-var Result $result */ - $result = $queryBuilder->execute(); + ->setParameter('ids', $pageIds, ArrayParameterType::STRING); + $result = $queryBuilder->executeQuery(); if (! $this->guard->isPermissionCheckRequired($this->moduleModel)) { return array_values( @@ -305,9 +304,8 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array $currentIds = $parentIds; $parentIds = []; - $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($currentIds)); - /** @psalm-var Result $result */ - $result = $query->execute(); + $query = $this->pageQueryBuilder->createPageInformationQuery(array_keys($currentIds)); + $result = $query->executeQuery(); while ($page = $result->fetchAssociative()) { if (! $page['protected']) { // do not remove, see above @@ -343,9 +341,8 @@ public function getNextLevel(array $pageIds, QueryBuilder $queryBuilder): array return $pageIds; } - $queryBuilder->setParameter('ids', array_keys(array_flip($pageIds)), Connection::PARAM_STR_ARRAY); - /** @psalm-var Result */ - $result = $queryBuilder->execute(); + $queryBuilder->setParameter('ids', array_keys(array_flip($pageIds)), ArrayParameterType::STRING); + $result = $queryBuilder->executeQuery(); $next = []; if ($this->guard->isPermissionCheckRequired($this->moduleModel)) { @@ -393,8 +390,7 @@ private function getPrevLevel(array $pageIds): array return $pageIds; } - /** @psalm-var Result $result */ - $result = $this->pageQueryBuilder->createPreviousLevelQuery($pageIds)->execute(); + $result = $this->pageQueryBuilder->createPreviousLevelQuery($pageIds)->executeQuery(); $previous = []; while ($row = $result->fetchAssociative()) { $previous[(int) $row['id']] = (int) $row['pid']; diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index 783a5a8..ad647c5 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -97,7 +97,7 @@ private function renameNavigationModules(): void /** @return array */ private function determineAffectedFields(): array { - $table = $this->connection->getSchemaManager()->listTableDetails('tl_module'); + $table = $this->connection->createSchemaManager()->introspectTable('tl_module'); $fields = []; foreach (self::FIELDS as $oldName => $newName) { diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index c4c24c1..10de07f 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -6,6 +6,7 @@ use Contao\ModuleModel; use Contao\StringUtil; +use Doctrine\DBAL\ArrayParameterType; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Query\QueryBuilder; use Symfony\Component\Security\Core\Security; @@ -94,7 +95,7 @@ function (QueryBuilder $queryBuilder): void { } ); - $query->setParameter('pids', $parentIds, Connection::PARAM_INT_ARRAY); + $query->setParameter('pids', $parentIds, ArrayParameterType::INTEGER); return $query; } @@ -179,7 +180,7 @@ function (QueryBuilder $queryBuilder): void { } ); - $query->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); + $query->setParameter('ids', $pageIds, ArrayParameterType::STRING); return $query; } @@ -201,7 +202,7 @@ function (QueryBuilder $queryBuilder): void { } ); - $query->setParameter('rootIds', $rootIds, Connection::PARAM_STR_ARRAY); + $query->setParameter('rootIds', $rootIds, ArrayParameterType::STRING); return $query; } @@ -251,7 +252,7 @@ private function addErrorPagesCondition(QueryBuilder $queryBuilder, bool $showEr if (! $showErrorPages) { $queryBuilder ->andWhere('type NOT IN (:errorPages)') - ->setParameter('errorPages', self::ERROR_PAGE_TYPES, Connection::PARAM_STR_ARRAY); + ->setParameter('errorPages', self::ERROR_PAGE_TYPES, ArrayParameterType::STRING); } return $this; @@ -274,7 +275,7 @@ private function determineFields(): void } $customFields = array_flip($customFields); - $table = $this->connection->getSchemaManager()->listTableDetails('tl_page'); + $table = $this->connection->createSchemaManager()->introspectTable('tl_page'); $fields = []; foreach ($table->getColumns() as $column) { diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index 9ed17f4..fdb8e4c 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -151,13 +151,16 @@ private function renderTree( $item['subitems'] ??= ''; $item['isActive'] ??= false; $item['isInTrail'] ??= false; + $item['class'] ??= ''; if ($itemId === $activeId) { $containsActive = true; if ($item['href'] === Environment::get('request')) { $item['isActive'] = true; // nothing else (active class is set in template) + $item['isInTrail'] = false; } else { + $item['isActive'] = false; // nothing else (active class is set in template) $item['isInTrail'] = true; } } else { // do not flatten if/else @@ -187,17 +190,16 @@ private function renderTree( // we are at stop level and not trail and not active, never draw submenu $item['class'] .= ' submenu leaf'; } elseif ($this->items->subItems[$itemId]) { - $item['class'] .= ' submenu inner'; + $item['class'] .= ' submenu inner'; $item['subitems'] = $this->renderTree( $this->items->subItems[$itemId] ?? [], $stopLimit, $hardLevel, $currentLevel + 1, - $activeId + $activeId, ); } else { // should never be reached, if no hooks are used $item['class'] .= ' leaf'; - $item['subitems'] = null; } $renderedItems[] = $item; @@ -205,7 +207,7 @@ private function renderTree( if ($containsActive) { foreach ($renderedItems as &$item) { - if ($item['isActive'] ?? false) { + if ($item['isActive']) { continue; } @@ -367,10 +369,10 @@ private function encodeEmailURL(string $href): string */ private function getRedirectPage(array $page): array { + /** @psalm-suppress RiskyTruthyFalsyComparison */ if (! $page['jumpTo']) { - $query = $this->redirectQueryBuilder->createFallbackQuery((int) $page['id']); - /** @psalm-var Result $result */ - $result = $query->execute(); + $query = $this->redirectQueryBuilder->createFallbackQuery((int) $page['id']); + $result = $query->executeQuery(); return $result->fetchAssociative() ?: []; } @@ -380,15 +382,15 @@ private function getRedirectPage(array $page): array do { $query = $this->redirectQueryBuilder->createJumpToQuery((int) $jumpToId); $query->setParameter('id', $jumpToId); - /** @psalm-var Result $result */ - $result = $query->execute(); - $next = $result->fetchAssociative() ?: []; + $result = $query->executeQuery(); + /** @psalm-suppress RiskyTruthyFalsyComparison */ + $next = $result->fetchAssociative() ?: []; if (! $result->rowCount()) { - $query = $this->redirectQueryBuilder->createFallbackQuery((int) $fallbackSearchId); - /** @psalm-var Result $result */ - $result = $query->execute(); - $next = $result->fetchAssociative() ?: []; + $query = $this->redirectQueryBuilder->createFallbackQuery((int) $fallbackSearchId); + $result = $query->executeQuery(); + /** @psalm-suppress RiskyTruthyFalsyComparison */ + $next = $result->fetchAssociative() ?: []; break; } diff --git a/src/Security/PagePermissionGuard.php b/src/Security/PagePermissionGuard.php index c237f71..5b2ed04 100644 --- a/src/Security/PagePermissionGuard.php +++ b/src/Security/PagePermissionGuard.php @@ -31,7 +31,7 @@ public function isPermissionCheckRequired(ModuleModel $model): bool * THIS IS NOT THE OPPOSITE OF ::isPermissionDenied()! * * Checks if the current user has permission to view the page of the given - * page dataset, in regards to the current navigation settings and the + * page dataset, in regard to the current navigation settings and the * permission requirements of the page. * * Context property: hofff_navigation_showProtected @@ -62,7 +62,7 @@ public function isPermissionGranted(ModuleModel $model, array $page): bool * THIS IS NOT THE OPPOSITE OF ::isPermissionGranted()! * * Checks if the current user has no permission to view the page of the - * given page dataset, in regards to the permission requirements of the + * given page dataset, in regard to the permission requirements of the * page. * * @param array $page The page dataset of the current page, with at least @@ -83,6 +83,7 @@ public function isPermissionDenied(array $page): bool } // the current user is not in any group + /** @psalm-suppress RiskyTruthyFalsyComparison */ if (! $user->groups) { return true; } From 0d050f02787ef9504b4a76c79b192363b671bb67 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 13:58:32 +0100 Subject: [PATCH 62/75] Update coding standard --- composer.json | 2 +- phpcs.xml.dist | 6 --- src/Event/Event.php | 5 +-- src/Event/ItemEvent.php | 7 +-- src/Event/MenuEvent.php | 7 +-- src/Event/TreeEvent.php | 6 +-- .../Dca/NavigationDcaListener.php | 13 ++---- src/FrontendModule/ModuleNavigationMenu.php | 10 +---- src/Items/PageItemsLoader.php | 44 +++++++------------ src/Migration/BackboneNavigationMigration.php | 10 ++--- src/QueryBuilder/BaseQueryBuilder.php | 8 +--- src/QueryBuilder/PageQueryBuilder.php | 35 +++++++-------- src/QueryBuilder/RedirectPageQueryBuilder.php | 4 +- src/Renderer/NavigationRenderer.php | 23 +++------- src/Resources/config/services.xml | 2 +- src/Security/PagePermissionGuard.php | 5 +-- 16 files changed, 57 insertions(+), 130 deletions(-) diff --git a/composer.json b/composer.json index 291d944..07f776f 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ }, "require-dev": { "contao/manager-plugin": "^2.0", - "doctrine/coding-standard": "^9.0.", + "doctrine/coding-standard": "^12.0.", "phpcq/runner-bootstrap": "1.x-dev" }, "replace": { diff --git a/phpcs.xml.dist b/phpcs.xml.dist index f638e54..8acdf1f 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -22,12 +22,6 @@ - - - - - - diff --git a/src/Event/Event.php b/src/Event/Event.php index 4cb1956..790a18d 100644 --- a/src/Event/Event.php +++ b/src/Event/Event.php @@ -9,11 +9,8 @@ abstract class Event extends BaseEvent { - private ModuleModel $moduleModel; - - public function __construct(ModuleModel $moduleModel) + public function __construct(private readonly ModuleModel $moduleModel) { - $this->moduleModel = $moduleModel; } public function moduleModel(): ModuleModel diff --git a/src/Event/ItemEvent.php b/src/Event/ItemEvent.php index be9f1b0..47b4d25 100644 --- a/src/Event/ItemEvent.php +++ b/src/Event/ItemEvent.php @@ -8,15 +8,10 @@ final class ItemEvent extends Event { - /** @var array */ - private array $item; - /** @param array $item */ - public function __construct(ModuleModel $moduleModel, array $item) + public function __construct(ModuleModel $moduleModel, private array $item) { parent::__construct($moduleModel); - - $this->item = $item; } /** @param array $item */ diff --git a/src/Event/MenuEvent.php b/src/Event/MenuEvent.php index fc47200..2f063e2 100644 --- a/src/Event/MenuEvent.php +++ b/src/Event/MenuEvent.php @@ -8,15 +8,10 @@ final class MenuEvent extends Event { - /** @var list */ - private array $rootIds; - /** @param list $rootIds */ - public function __construct(ModuleModel $moduleModel, array $rootIds) + public function __construct(ModuleModel $moduleModel, private array $rootIds) { parent::__construct($moduleModel); - - $this->rootIds = $rootIds; } /** @param list $rootIds */ diff --git a/src/Event/TreeEvent.php b/src/Event/TreeEvent.php index 827a247..7af856c 100644 --- a/src/Event/TreeEvent.php +++ b/src/Event/TreeEvent.php @@ -9,13 +9,9 @@ final class TreeEvent extends Event { - private PageItems $items; - - public function __construct(ModuleModel $moduleModel, PageItems $items) + public function __construct(ModuleModel $moduleModel, private readonly PageItems $items) { parent::__construct($moduleModel); - - $this->items = $items; } public function items(): PageItems diff --git a/src/EventListener/Dca/NavigationDcaListener.php b/src/EventListener/Dca/NavigationDcaListener.php index d43909f..226e3fc 100644 --- a/src/EventListener/Dca/NavigationDcaListener.php +++ b/src/EventListener/Dca/NavigationDcaListener.php @@ -5,8 +5,8 @@ namespace Hofff\Contao\Navigation\EventListener\Dca; use Contao\Controller; +use Contao\CoreBundle\DependencyInjection\Attribute\AsCallback; use Contao\CoreBundle\Framework\ContaoFramework; -use Contao\CoreBundle\ServiceAnnotation\Callback; use Hofff\Contao\Navigation\QueryBuilder\PageQueryBuilder; use function array_map; @@ -17,19 +17,16 @@ /** @psalm-suppress PropertyNotSetInConstructor */ final class NavigationDcaListener { - private ContaoFramework $framework; - - public function __construct(ContaoFramework $framework) + public function __construct(private readonly ContaoFramework $framework) { - $this->framework = $framework; } /** * @return array * - * @Callback(table="tl_module", target="fields.hofff_navigation_addFields.options") * @SuppressWarnings(PHPMD.Superglobals) */ + #[AsCallback('tl_module', 'fields.hofff_navigation_addFields.options')] public function getPageFields(): array { $controller = $this->framework->getAdapter(Controller::class); @@ -49,9 +46,7 @@ public function getPageFields(): array return $fields; } - /** - * @Callback(table="tl_module", target="fields.hofff_navigation_stop.save") - */ + #[AsCallback('tl_module', 'fields.hofff_navigation_stop.save')] public function saveStop(string $value): string { $minimum = -1; diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 92f6dd3..385d46e 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -57,14 +57,8 @@ */ final class ModuleNavigationMenu extends AbstractFrontendModuleController { - private PageItemsLoader $loader; - - private NavigationRenderer $renderer; - - public function __construct(PageItemsLoader $loader, NavigationRenderer $renderer) + public function __construct(private readonly PageItemsLoader $loader, private readonly NavigationRenderer $renderer) { - $this->loader = $loader; - $this->renderer = $renderer; } /** @@ -89,7 +83,7 @@ protected function getResponse(Template $template, ModuleModel $model, Request $ array_keys($items->roots), $stopLevels, $hardLevel, - $activeId + $activeId, ); if ($navigation === '') { diff --git a/src/Items/PageItemsLoader.php b/src/Items/PageItemsLoader.php index edadb6b..e74b38b 100644 --- a/src/Items/PageItemsLoader.php +++ b/src/Items/PageItemsLoader.php @@ -35,12 +35,6 @@ /** @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ final class PageItemsLoader { - private Connection $connection; - - private Security $security; - - private PagePermissionGuard $guard; - /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ private PageQueryBuilder $pageQueryBuilder; @@ -55,24 +49,22 @@ final class PageItemsLoader private int $hardLevel = PHP_INT_MAX; - private ?int $activeId = null; + private int|null $activeId = null; - public function __construct(Connection $connection, Security $security, PagePermissionGuard $guard) - { - $this->connection = $connection; - $this->security = $security; - $this->guard = $guard; + public function __construct( + private readonly Connection $connection, + private readonly Security $security, + private readonly PagePermissionGuard $guard, + ) { } - /** - * @param list $stopLevels - */ + /** @param list $stopLevels */ public function load( ModuleModel $moduleModel, PageModel $currentPage, array $stopLevels = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, - ?int $activeId = null + int|null $activeId = null, ): PageItems { $this->items = new PageItems($currentPage); $this->pageQueryBuilder = new PageQueryBuilder($this->connection, $this->security, $moduleModel); @@ -182,9 +174,7 @@ protected function fetchItems(array $parentIds, int $level = 1): array return $fetched; } - /** - * @return list - */ + /** @return list */ private function calculateRootIDs(): array { $rootIds = $this->getRootIds(); @@ -220,9 +210,7 @@ private function calculateRootIDs(): array return $rootIds; } - /** - * @return list - */ + /** @return list */ private function getRootIds(): array { if (! $this->moduleModel->hofff_navigation_defineRoots) { @@ -236,10 +224,10 @@ private function getRootIds(): array array_unique( array_merge( StringUtil::deserialize($this->moduleModel->hofff_navigation_roots_order, true), - StringUtil::deserialize($this->moduleModel->hofff_navigation_roots, true) - ) - ) - ) + StringUtil::deserialize($this->moduleModel->hofff_navigation_roots, true), + ), + ), + ), ); } @@ -273,8 +261,8 @@ private function filterPages(array $pageIds, QueryBuilder $queryBuilder): array return array_values( array_intersect( $pageIds, - array_map(static fn (array $row): int => (int) $row['id'], $result->fetchAllAssociative()) - ) + array_map(static fn (array $row): int => (int) $row['id'], $result->fetchAllAssociative()), + ), ); } // restore order diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index ad647c5..b251798 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -7,15 +7,12 @@ use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Schema\Column; use function is_int; use function sprintf; final class BackboneNavigationMigration extends AbstractMigration { - private Connection $connection; - private const OLD_PREFIX = 'backboneit_navigation_'; private const NEW_PREFIX = 'hofff_navigation_'; @@ -48,9 +45,8 @@ final class BackboneNavigationMigration extends AbstractMigration 'addLegacyCss', ]; - public function __construct(Connection $connection) + public function __construct(private readonly Connection $connection) { - $this->connection = $connection; } public function shouldRun(): bool @@ -79,7 +75,7 @@ private function hasBackboneItNavigationModules(): bool { $result = $this->connection->executeQuery( 'SELECT count(id) FROM tl_module WHERE type=:type', - ['type' => 'backboneit_navigation_menu'] + ['type' => 'backboneit_navigation_menu'], ); return $result->fetchOne() > 0; @@ -90,7 +86,7 @@ private function renameNavigationModules(): void $this->connection->update( 'tl_module', ['type' => 'hofff_navigation_menu'], - ['type' => 'backboneit_navigation_menu'] + ['type' => 'backboneit_navigation_menu'], ); } diff --git a/src/QueryBuilder/BaseQueryBuilder.php b/src/QueryBuilder/BaseQueryBuilder.php index 99382f2..69b06fe 100644 --- a/src/QueryBuilder/BaseQueryBuilder.php +++ b/src/QueryBuilder/BaseQueryBuilder.php @@ -12,17 +12,11 @@ abstract class BaseQueryBuilder { - private Security $security; - - protected Connection $connection; - /** @var array */ private array $queries = []; - public function __construct(Connection $connection, Security $security) + public function __construct(protected readonly Connection $connection, private readonly Security $security) { - $this->connection = $connection; - $this->security = $security; } protected function query(string $name, callable $builder): QueryBuilder diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 10de07f..814856f 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -46,16 +46,13 @@ final class PageQueryBuilder extends BaseQueryBuilder 'error_404', ]; - private ModuleModel $moduleModel; - /** @var list */ private array $fields = []; - public function __construct(Connection $connection, Security $security, ModuleModel $moduleModel) + public function __construct(Connection $connection, Security $security, private readonly ModuleModel $moduleModel) { parent::__construct($connection, $security); - $this->moduleModel = $moduleModel; $this->determineFields(); } @@ -81,18 +78,18 @@ function (QueryBuilder $queryBuilder): void { ->addHiddenCondition( $queryBuilder, (bool) $this->moduleModel->hofff_navigation_showHidden, - (bool) $this->moduleModel->hofff_navigation_isSitemap + (bool) $this->moduleModel->hofff_navigation_isSitemap, ) ->addPublishedCondition($queryBuilder) ->addErrorPagesCondition( $queryBuilder, - (bool) $this->moduleModel->hofff_navigation_showErrorPages + (bool) $this->moduleModel->hofff_navigation_showErrorPages, ) ->addGuestsQueryParts( $queryBuilder, - (bool) $this->moduleModel->backboneit_navigation_showGuests + (bool) $this->moduleModel->backboneit_navigation_showGuests, ); - } + }, ); $query->setParameter('pids', $parentIds, ArrayParameterType::INTEGER); @@ -117,17 +114,17 @@ function (QueryBuilder $queryBuilder): void { ->addHiddenCondition( $queryBuilder, ! $this->moduleModel->hofff_navigation_respectHidden, - (bool) $this->moduleModel->hofff_navigation_isSitemap + (bool) $this->moduleModel->hofff_navigation_isSitemap, ) ->addGuestsQueryParts( $queryBuilder, - ! $this->moduleModel->hofff_navigation_respectGuests + ! $this->moduleModel->hofff_navigation_respectGuests, ) ->addPublishedCondition( $queryBuilder, - (bool) $this->moduleModel->hofff_navigation_respectPublish + (bool) $this->moduleModel->hofff_navigation_respectPublish, ); - } + }, ); } @@ -151,15 +148,15 @@ function (QueryBuilder $queryBuilder): void { ->addHiddenCondition( $queryBuilder, (bool) $this->moduleModel->hofff_navigation_showHiddenStart, - (bool) $this->moduleModel->hofff_navigation_isSitemap + (bool) $this->moduleModel->hofff_navigation_isSitemap, ) ->addPublishedCondition($queryBuilder) ->addErrorPagesCondition( $queryBuilder, - (bool) $this->moduleModel->hofff_navigation_showErrorPages + (bool) $this->moduleModel->hofff_navigation_showErrorPages, ) ->addGuestsQueryParts($queryBuilder, (bool) $this->moduleModel->hofff_navigation_showGuests); - } + }, ); } @@ -177,7 +174,7 @@ function (QueryBuilder $queryBuilder): void { ) ) ->where('id IN (:ids)'); - } + }, ); $query->setParameter('ids', $pageIds, ArrayParameterType::STRING); @@ -199,7 +196,7 @@ function (QueryBuilder $queryBuilder): void { ) ) ->where('id IN (:rootIds)'); - } + }, ); $query->setParameter('rootIds', $rootIds, ArrayParameterType::STRING); @@ -216,7 +213,7 @@ static function (QueryBuilder $queryBuilder): void { $queryBuilder ->select('id', 'pid') ->where('id IN (:ids)'); - } + }, ); $query->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); @@ -230,7 +227,7 @@ static function (QueryBuilder $queryBuilder): void { private function addHiddenCondition( QueryBuilder $queryBuilder, bool $showHidden = false, - bool $sitemap = false + bool $sitemap = false, ): self { if ($showHidden) { return $this; diff --git a/src/QueryBuilder/RedirectPageQueryBuilder.php b/src/QueryBuilder/RedirectPageQueryBuilder.php index e476786..645971f 100644 --- a/src/QueryBuilder/RedirectPageQueryBuilder.php +++ b/src/QueryBuilder/RedirectPageQueryBuilder.php @@ -21,7 +21,7 @@ function (QueryBuilder $queryBuilder): void { $this ->addGuestsQueryParts($queryBuilder) ->addPublishedCondition($queryBuilder); - } + }, ); $query->setParameter('id', $jumpToId); @@ -44,7 +44,7 @@ function (QueryBuilder $queryBuilder): void { $this ->addGuestsQueryParts($queryBuilder); - } + }, ); $query->setParameter('pid', $fallbackSearchId); diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index fdb8e4c..a7c9e40 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -9,7 +9,6 @@ use Contao\ModuleModel; use Contao\PageModel; use Contao\StringUtil; -use Doctrine\DBAL\Result; use Hofff\Contao\Navigation\Event\ItemEvent; use Hofff\Contao\Navigation\Event\MenuEvent; use Hofff\Contao\Navigation\Event\TreeEvent; @@ -29,15 +28,9 @@ use const PHP_INT_MAX; -/** - * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) - */ +/** @SuppressWarnings(PHPMD.ExcessiveClassComplexity) */ final class NavigationRenderer { - private RedirectPageQueryBuilder $redirectQueryBuilder; - - private EventDispatcherInterface $eventDispatcher; - /** @psalm-suppress PropertyNotSetInConstructor - Will be initialized in the only public method load() */ private PageItems $items; @@ -45,11 +38,9 @@ final class NavigationRenderer private ModuleModel $moduleModel; public function __construct( - EventDispatcherInterface $eventDispatcher, - RedirectPageQueryBuilder $redirectQueryBuilder + private readonly EventDispatcherInterface $eventDispatcher, + private readonly RedirectPageQueryBuilder $redirectQueryBuilder, ) { - $this->redirectQueryBuilder = $redirectQueryBuilder; - $this->eventDispatcher = $eventDispatcher; } /** @@ -113,9 +104,7 @@ public function render( } } - return trim( - $this->renderTree($firstIds, $stopLimit, $hardLevel, $currentLevel, $activeId) - ); + return trim($this->renderTree($firstIds, $stopLimit, $hardLevel, $currentLevel, $activeId)); } /** @@ -131,7 +120,7 @@ private function renderTree( array $stopLimit = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, int $currentLevel = 1, - ?int $activeId = null + int|null $activeId = null, ): string { if (! $itemIds) { return ''; @@ -247,7 +236,7 @@ private function compileTree(): void $this->items->items[$itemId] = $this->compileNavigationItem( $this->items->items[$itemId], - $forwardResolution + $forwardResolution, ); } } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 7883638..9caa50b 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -7,7 +7,7 @@ - + diff --git a/src/Security/PagePermissionGuard.php b/src/Security/PagePermissionGuard.php index 5b2ed04..4aa1fe5 100644 --- a/src/Security/PagePermissionGuard.php +++ b/src/Security/PagePermissionGuard.php @@ -13,11 +13,8 @@ final class PagePermissionGuard { - private Security $security; - - public function __construct(Security $security) + public function __construct(private readonly Security $security) { - $this->security = $security; } public function isPermissionCheckRequired(ModuleModel $model): bool From 8f1d4a03bd84e7bd848a3ba09252430ef869dfc1 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:14:05 +0100 Subject: [PATCH 63/75] Do not run migration if table does not exist --- src/Migration/BackboneNavigationMigration.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index b251798..a5b3985 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -51,6 +51,10 @@ public function __construct(private readonly Connection $connection) public function shouldRun(): bool { + if (! $this->connection->createSchemaManager()->tablesExist('tl_module')) { + return false; + } + if ($this->hasBackboneItNavigationModules()) { return true; } From df4ee06288a799dce10bce3abba7864668fe4d22 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:14:49 +0100 Subject: [PATCH 64/75] Use attribute insteadof service annotation --- src/FrontendModule/ModuleNavigationMenu.php | 4 ++-- src/Resources/config/services.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FrontendModule/ModuleNavigationMenu.php b/src/FrontendModule/ModuleNavigationMenu.php index 385d46e..4f5bbdd 100644 --- a/src/FrontendModule/ModuleNavigationMenu.php +++ b/src/FrontendModule/ModuleNavigationMenu.php @@ -5,7 +5,7 @@ namespace Hofff\Contao\Navigation\FrontendModule; use Contao\CoreBundle\Controller\FrontendModule\AbstractFrontendModuleController; -use Contao\CoreBundle\ServiceAnnotation\FrontendModule; +use Contao\CoreBundle\DependencyInjection\Attribute\AsFrontendModule; use Contao\Environment; use Contao\ModuleModel; use Contao\Template; @@ -52,9 +52,9 @@ * _target * _description * - * @FrontendModule("hofff_navigation_menu", category="navigationMenu") * @psalm-suppress PropertyNotSetInConstructor */ +#[AsFrontendModule('hofff_navigation_menu', 'navigation', template: 'mod_hofff_navigation_menu')] final class ModuleNavigationMenu extends AbstractFrontendModuleController { public function __construct(private readonly PageItemsLoader $loader, private readonly NavigationRenderer $renderer) diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 9caa50b..d45a682 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -32,7 +32,7 @@ - + From 42ce2a555722ee9281f298e19f688d9c5851d0e0 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:15:29 +0100 Subject: [PATCH 65/75] Add ddev test instance --- .ddev/commands/host/console | 7 + .ddev/commands/host/migrate | 7 + .ddev/config.yaml | 24 + .ddev/contao/.env | 2 + .ddev/contao/composer.json | 42 + .ddev/contao/composer.lock | 12954 ++++++++++++++++++++++++++++++++++ .gitignore | 1 - 7 files changed, 13036 insertions(+), 1 deletion(-) create mode 100755 .ddev/commands/host/console create mode 100755 .ddev/commands/host/migrate create mode 100644 .ddev/config.yaml create mode 100644 .ddev/contao/.env create mode 100644 .ddev/contao/composer.json create mode 100644 .ddev/contao/composer.lock diff --git a/.ddev/commands/host/console b/.ddev/commands/host/console new file mode 100755 index 0000000..b1e0711 --- /dev/null +++ b/.ddev/commands/host/console @@ -0,0 +1,7 @@ +#!/bin/bash + +## Description: Delegates commands to the contao console +## Usage: console +## Example: "ddev console contao:migrate" + +ddev exec vendor/bin/contao-console "$@" diff --git a/.ddev/commands/host/migrate b/.ddev/commands/host/migrate new file mode 100755 index 0000000..16144eb --- /dev/null +++ b/.ddev/commands/host/migrate @@ -0,0 +1,7 @@ +#!/bin/bash + +## Description: Executes Contao database migration +## Usage: migrate +## Example: "ddev migrate --no-backup" + +ddev exec vendor/bin/contao-console contao:migrate "$@" diff --git a/.ddev/config.yaml b/.ddev/config.yaml new file mode 100644 index 0000000..64653d9 --- /dev/null +++ b/.ddev/config.yaml @@ -0,0 +1,24 @@ +name: hofff-contao-navigation +type: php +docroot: ".ddev/contao/public" +php_version: "8.1" +webserver_type: apache-fpm +router_http_port: "80" +router_https_port: "443" +xdebug_enabled: false +additional_hostnames: [] +additional_fqdns: [] +database: + type: mariadb + version: "10.4" +nfs_mount_enabled: false +mutagen_enabled: false +use_dns_when_possible: true +composer_root: ".ddev/contao" +composer_version: "2" +web_environment: [] +nodejs_version: "16" +timezone: Europe/Berlin +working_dir: { + web: "/var/www/html/.ddev/contao" +} diff --git a/.ddev/contao/.env b/.ddev/contao/.env new file mode 100644 index 0000000..fd23acf --- /dev/null +++ b/.ddev/contao/.env @@ -0,0 +1,2 @@ +APP_ENV=dev +DATABASE_URL="mysql://db:db@db:3306/db" diff --git a/.ddev/contao/composer.json b/.ddev/contao/composer.json new file mode 100644 index 0000000..8d937a8 --- /dev/null +++ b/.ddev/contao/composer.json @@ -0,0 +1,42 @@ +{ + "name": "contao/managed-edition", + "description": "Contao Managed Edition", + "license": "LGPL-3.0-or-later", + "type": "project", + "require": { + "contao/conflicts": "@dev", + "contao/manager-bundle": "^5.3.x-dev", + "hofff/contao-navigation": "@dev" + }, + "conflict": { + "contao-components/installer": "<1.3" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "config": { + "allow-plugins": { + "composer/package-versions-deprecated": true, + "contao-community-alliance/composer-plugin": true, + "contao-components/installer": true, + "contao/manager-plugin": true, + "php-http/discovery": false + } + }, + "extra": { + "contao-component-dir": "assets" + }, + "scripts": { + "post-install-cmd": [ + "@php vendor/bin/contao-setup" + ], + "post-update-cmd": [ + "@php vendor/bin/contao-setup" + ] + }, + "repositories": [ + { + "type": "path", + "url": "../.." + } + ] +} diff --git a/.ddev/contao/composer.lock b/.ddev/contao/composer.lock new file mode 100644 index 0000000..c7881a1 --- /dev/null +++ b/.ddev/contao/composer.lock @@ -0,0 +1,12954 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "717cc1c2336faee42ac370641948f248", + "packages": [ + { + "name": "ausi/slug-generator", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/ausi/slug-generator.git", + "reference": "4e761b08966c5d4aeecc1829ac997e5a5a29d231" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ausi/slug-generator/zipball/4e761b08966c5d4aeecc1829ac997e5a5a29d231", + "reference": "4e761b08966c5d4aeecc1829ac997e5a5a29d231", + "shasum": "" + }, + "require": { + "ext-intl": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "lib-icu": ">=4.2.1", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "contao/easy-coding-standard": "^3.0", + "phpstan/phpstan": "^0.12.40", + "phpstan/phpstan-phpunit": "^0.12.16", + "phpunit/phpunit": "^7.5.20 || ^8.5.4 || ^9.4.2", + "psalm/plugin-phpunit": "^0.9", + "slam/phpstan-extensions": "^5.0", + "vimeo/psalm": "^3.9" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ausi\\SlugGenerator\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Martin Auswöger", + "email": "martin@auswoeger.com" + } + ], + "description": "Slug Generator", + "keywords": [ + "ascii", + "cldr", + "pretty-url", + "slug", + "slug-generator", + "slugify", + "transliteration", + "unicode" + ], + "support": { + "issues": "https://github.com/ausi/slug-generator/issues", + "source": "https://github.com/ausi/slug-generator/tree/v1.1.1" + }, + "funding": [ + { + "url": "https://github.com/ausi", + "type": "github" + } + ], + "time": "2020-10-19T15:25:33+00:00" + }, + { + "name": "bacon/bacon-qr-code", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/Bacon/BaconQrCode.git", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/8674e51bb65af933a5ffaf1c308a660387c35c22", + "reference": "8674e51bb65af933a5ffaf1c308a660387c35c22", + "shasum": "" + }, + "require": { + "dasprid/enum": "^1.0.3", + "ext-iconv": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phly/keep-a-changelog": "^2.1", + "phpunit/phpunit": "^7 | ^8 | ^9", + "spatie/phpunit-snapshot-assertions": "^4.2.9", + "squizlabs/php_codesniffer": "^3.4" + }, + "suggest": { + "ext-imagick": "to generate QR code images" + }, + "type": "library", + "autoload": { + "psr-4": { + "BaconQrCode\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "BaconQrCode is a QR code generator for PHP.", + "homepage": "https://github.com/Bacon/BaconQrCode", + "support": { + "issues": "https://github.com/Bacon/BaconQrCode/issues", + "source": "https://github.com/Bacon/BaconQrCode/tree/2.0.8" + }, + "time": "2022-12-07T17:46:57+00:00" + }, + { + "name": "beberlei/assert", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/beberlei/assert.git", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/beberlei/assert/zipball/cb70015c04be1baee6f5f5c953703347c0ac1655", + "reference": "cb70015c04be1baee6f5f5c953703347c0ac1655", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "*", + "phpstan/phpstan": "*", + "phpunit/phpunit": ">=6.0.0", + "yoast/phpunit-polyfills": "^0.1.0" + }, + "suggest": { + "ext-intl": "Needed to allow Assertion::count(), Assertion::isCountable(), Assertion::minCount(), and Assertion::maxCount() to operate on ResourceBundles" + }, + "type": "library", + "autoload": { + "files": [ + "lib/Assert/functions.php" + ], + "psr-4": { + "Assert\\": "lib/Assert" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "role": "Lead Developer" + }, + { + "name": "Richard Quadling", + "email": "rquadling@gmail.com", + "role": "Collaborator" + } + ], + "description": "Thin assertion library for input validation in business models.", + "keywords": [ + "assert", + "assertion", + "validation" + ], + "support": { + "issues": "https://github.com/beberlei/assert/issues", + "source": "https://github.com/beberlei/assert/tree/v3.3.2" + }, + "time": "2021-12-16T21:41:27+00:00" + }, + { + "name": "clue/stream-filter", + "version": "v1.7.0", + "source": { + "type": "git", + "url": "https://github.com/clue/stream-filter.git", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/stream-filter/zipball/049509fef80032cb3f051595029ab75b49a3c2f7", + "reference": "049509fef80032cb3f051595029ab75b49a3c2f7", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "Clue\\StreamFilter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "A simple and modern approach to stream filtering in PHP", + "homepage": "https://github.com/clue/stream-filter", + "keywords": [ + "bucket brigade", + "callback", + "filter", + "php_user_filter", + "stream", + "stream_filter_append", + "stream_filter_register" + ], + "support": { + "issues": "https://github.com/clue/stream-filter/issues", + "source": "https://github.com/clue/stream-filter/tree/v1.7.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2023-12-20T15:40:13+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "b66d11b7479109ab547f9405b97205640b17d385" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/b66d11b7479109ab547f9405b97205640b17d385", + "reference": "b66d11b7479109ab547f9405b97205640b17d385", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.55", + "psr/log": "^1.0", + "symfony/phpunit-bridge": "^4.2 || ^5", + "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/ca-bundle/issues", + "source": "https://github.com/composer/ca-bundle/tree/1.4.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-12-18T12:05:55+00:00" + }, + { + "name": "contao-components/ace", + "version": "1.32.6", + "source": { + "type": "git", + "url": "https://github.com/contao-components/ace.git", + "reference": "cdf6a74c93d03c28457ccce16c61184edd3fa047" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/ace/zipball/cdf6a74c93d03c28457ccce16c61184edd3fa047", + "reference": "cdf6a74c93d03c28457ccce16c61184edd3fa047", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabian Jakobs", + "homepage": "https://github.com/fjakobs" + } + ], + "description": "ACE code editor integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/ace/issues", + "source": "https://github.com/contao-components/ace/tree/1.32.6" + }, + "time": "2024-02-07T09:27:31+00:00" + }, + { + "name": "contao-components/chosen", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/contao-components/chosen.git", + "reference": "da03c67010b8fc520f64f2a9bbfcafb453ad2489" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/chosen/zipball/da03c67010b8fc520f64f2a9bbfcafb453ad2489", + "reference": "da03c67010b8fc520f64f2a9bbfcafb453ad2489", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jules Janssen", + "homepage": "https://github.com/julesjanssen" + } + ], + "description": "Chosen integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/chosen/issues", + "source": "https://github.com/contao-components/chosen/tree/2.0.2" + }, + "time": "2023-09-01T07:42:59+00:00" + }, + { + "name": "contao-components/colorbox", + "version": "1.6.6", + "source": { + "type": "git", + "url": "https://github.com/contao-components/colorbox.git", + "reference": "80c3b1b5adff4add0a7a54db93ad0bf15ae6bd9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/colorbox/zipball/80c3b1b5adff4add0a7a54db93ad0bf15ae6bd9d", + "reference": "80c3b1b5adff4add0a7a54db93ad0bf15ae6bd9d", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "Colorbox integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/colorbox/issues", + "source": "https://github.com/contao-components/colorbox/tree/1.6.6" + }, + "time": "2020-05-01T15:29:20+00:00" + }, + { + "name": "contao-components/colorpicker", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/contao-components/colorpicker.git", + "reference": "fd6f899746c6a18fbfdfd30e156f862894b00d3b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/colorpicker/zipball/fd6f899746c6a18fbfdfd30e156f862894b00d3b", + "reference": "fd6f899746c6a18fbfdfd30e156f862894b00d3b", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christopher Beloch", + "homepage": "https://github.com/CBeloch" + } + ], + "description": "Color picker integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/colorpicker/issues", + "source": "https://github.com/contao-components/colorpicker/tree/1.5.3" + }, + "time": "2024-01-19T16:00:42+00:00" + }, + { + "name": "contao-components/contao", + "version": "9.3.4", + "source": { + "type": "git", + "url": "https://github.com/contao-components/contao.git", + "reference": "a34e1327beabe1f1623e853c46ab7a7cbf9fc7da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/contao/zipball/a34e1327beabe1f1623e853c46ab7a7cbf9fc7da", + "reference": "a34e1327beabe1f1623e853c46ab7a7cbf9fc7da", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "Contao Open Source CMS components", + "support": { + "issues": "https://github.com/contao-components/contao/issues", + "source": "https://github.com/contao-components/contao/tree/9.3.4" + }, + "time": "2023-10-12T07:49:31+00:00" + }, + { + "name": "contao-components/datepicker", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/contao-components/datepicker.git", + "reference": "355e79949cb2c3ff5016b41ef13f426333d01632" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/datepicker/zipball/355e79949cb2c3ff5016b41ef13f426333d01632", + "reference": "355e79949cb2c3ff5016b41ef13f426333d01632", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Arian Stolwijk", + "homepage": "https://github.com/arian" + } + ], + "description": "Date picker integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/datepicker/issues", + "source": "https://github.com/contao-components/datepicker/tree/3.0.0" + }, + "time": "2023-01-07T14:42:52+00:00" + }, + { + "name": "contao-components/dropzone", + "version": "5.9.3", + "source": { + "type": "git", + "url": "https://github.com/contao-components/dropzone.git", + "reference": "212c524e3c226b01e8232287c764b22d7469df6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/dropzone/zipball/212c524e3c226b01e8232287c764b22d7469df6a", + "reference": "212c524e3c226b01e8232287c764b22d7469df6a", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "DropZone integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/dropzone/issues", + "source": "https://github.com/contao-components/dropzone/tree/5.9.3" + }, + "time": "2021-09-28T07:38:53+00:00" + }, + { + "name": "contao-components/handorgel", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/contao-components/handorgel.git", + "reference": "0f617439750945848dfea006ea19e8f49244bc1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/handorgel/zipball/0f617439750945848dfea006ea19e8f49244bc1f", + "reference": "0f617439750945848dfea006ea19e8f49244bc1f", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Manuel Sommerhalder", + "homepage": "https://github.com/oncode" + } + ], + "description": "Handorgel integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/handorgel/issues", + "source": "https://github.com/contao-components/handorgel/tree/1.0.0" + }, + "time": "2023-12-22T15:41:53+00:00" + }, + { + "name": "contao-components/installer", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/contao-components/installer.git", + "reference": "eb0c34f0f61a3338dd985a55bd865483e78c3bb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/installer/zipball/eb0c34f0f61a3338dd985a55bd865483e78c3bb7", + "reference": "eb0c34f0f61a3338dd985a55bd865483e78c3bb7", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.6" + }, + "require-dev": { + "composer/composer": "^1.0 || ^2.0", + "phpunit/phpunit": "^5.7.26" + }, + "type": "composer-plugin", + "extra": { + "class": "Contao\\ComponentsInstaller\\Composer\\Plugin" + }, + "autoload": { + "psr-4": { + "Contao\\ComponentsInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "Contao components installer", + "support": { + "issues": "https://github.com/contao-components/installer/issues", + "source": "https://github.com/contao-components/installer/tree/1.4.1" + }, + "time": "2020-12-23T10:51:52+00:00" + }, + { + "name": "contao-components/jquery", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/contao-components/jquery.git", + "reference": "34215fee962fc9b9831600d6b983d2f77d9e6f71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/jquery/zipball/34215fee962fc9b9831600d6b983d2f77d9e6f71", + "reference": "34215fee962fc9b9831600d6b983d2f77d9e6f71", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "OpenJS Foundation and other contributors", + "homepage": "https://github.com/jquery/jquery/blob/main/AUTHORS.txt" + } + ], + "description": "jQuery integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/jquery/issues", + "source": "https://github.com/contao-components/jquery/tree/3.7.1" + }, + "time": "2023-08-31T10:23:57+00:00" + }, + { + "name": "contao-components/jquery-ui", + "version": "1.13.2", + "source": { + "type": "git", + "url": "https://github.com/contao-components/jquery-ui.git", + "reference": "f1ac19cfd2093663278ffa509038d0ffc6d38db5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/jquery-ui/zipball/f1ac19cfd2093663278ffa509038d0ffc6d38db5", + "reference": "f1ac19cfd2093663278ffa509038d0ffc6d38db5", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "jQuery Foundation and other contributors", + "homepage": "https://github.com/jquery/jquery-ui/blob/main/AUTHORS.txt" + } + ], + "description": "jQuery UI integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/jquery-ui/issues", + "source": "https://github.com/contao-components/jquery-ui/tree/1.13.2" + }, + "time": "2022-12-07T15:46:44+00:00" + }, + { + "name": "contao-components/mediabox", + "version": "1.5.5", + "source": { + "type": "git", + "url": "https://github.com/contao-components/mediabox.git", + "reference": "8f56fdbcfe7156e90a7f43e4976e09f61bdb1082" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/mediabox/zipball/8f56fdbcfe7156e90a7f43e4976e09f61bdb1082", + "reference": "8f56fdbcfe7156e90a7f43e4976e09f61bdb1082", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "Mediabox integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/mediabox/issues", + "source": "https://github.com/contao-components/mediabox/tree/1.5.5" + }, + "time": "2019-07-12T07:33:27+00:00" + }, + { + "name": "contao-components/mootools", + "version": "1.6.0.7", + "source": { + "type": "git", + "url": "https://github.com/contao-components/mootools.git", + "reference": "048bdd9264156f9b66175fddc4531694bfd5ce1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/mootools/zipball/048bdd9264156f9b66175fddc4531694bfd5ce1b", + "reference": "048bdd9264156f9b66175fddc4531694bfd5ce1b", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "MooTools Development Team", + "homepage": "http://mootools.net/developers" + } + ], + "description": "MooTools integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/mootools/issues", + "source": "https://github.com/contao-components/mootools/tree/1.6.0.7" + }, + "time": "2022-10-20T09:36:26+00:00" + }, + { + "name": "contao-components/simplemodal", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/contao-components/simplemodal.git", + "reference": "ba6aab8a88430f05a869a6f42f4573714ce6d762" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/simplemodal/zipball/ba6aab8a88430f05a869a6f42f4573714ce6d762", + "reference": "ba6aab8a88430f05a869a6f42f4573714ce6d762", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Dell'Anna", + "homepage": "https://plasm.it" + } + ], + "description": "SimpleModal integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/simplemodal/issues", + "source": "https://github.com/contao-components/simplemodal/tree/3.0.1" + }, + "time": "2023-11-06T10:36:23+00:00" + }, + { + "name": "contao-components/swipe", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/contao-components/swipe.git", + "reference": "29aec32b76cb7192d949f3bf3a51283b26b16094" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/swipe/zipball/29aec32b76cb7192d949f3bf3a51283b26b16094", + "reference": "29aec32b76cb7192d949f3bf3a51283b26b16094", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brad Birdsall", + "homepage": "https://github.com/thebird" + }, + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "A JavaScript touch slider with dot menu", + "support": { + "issues": "https://github.com/contao-components/swipe/issues", + "source": "https://github.com/contao-components/swipe/tree/2.2.1" + }, + "time": "2023-10-10T13:09:42+00:00" + }, + { + "name": "contao-components/swiper", + "version": "11.0.5", + "source": { + "type": "git", + "url": "https://github.com/contao-components/swiper.git", + "reference": "22e17071488228f52b54d83f5b7c87048306bfb9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/swiper/zipball/22e17071488228f52b54d83f5b7c87048306bfb9", + "reference": "22e17071488228f52b54d83f5b7c87048306bfb9", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Vladimir Kharlampidi", + "homepage": "https://github.com/nolimits4web" + } + ], + "description": "The most modern mobile touch slider", + "support": { + "issues": "https://github.com/contao-components/swiper/issues", + "source": "https://github.com/contao-components/swiper/tree/11.0.5" + }, + "time": "2023-12-15T15:58:56+00:00" + }, + { + "name": "contao-components/tablesort", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/contao-components/tablesort.git", + "reference": "faabcfab17e388b767c8f5a18987c44429692a9d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/tablesort/zipball/faabcfab17e388b767c8f5a18987c44429692a9d", + "reference": "faabcfab17e388b767c8f5a18987c44429692a9d", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "Contao Open Source CMS tablesort", + "support": { + "issues": "https://github.com/contao-components/tablesort/issues", + "source": "https://github.com/contao-components/tablesort/tree/4.0.1" + }, + "time": "2019-07-12T07:43:54+00:00" + }, + { + "name": "contao-components/tablesorter", + "version": "2.31.3", + "source": { + "type": "git", + "url": "https://github.com/contao-components/tablesorter.git", + "reference": "2b3f64c2ababdfe291e3248b26bbef5f4821f868" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/tablesorter/zipball/2b3f64c2ababdfe291e3248b26bbef5f4821f868", + "reference": "2b3f64c2ababdfe291e3248b26bbef5f4821f868", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "jQuery tablesorter integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/tablesorter/issues", + "source": "https://github.com/contao-components/tablesorter/tree/2.31.3" + }, + "time": "2020-05-14T15:24:29+00:00" + }, + { + "name": "contao-components/tinymce4", + "version": "6.8.3", + "source": { + "type": "git", + "url": "https://github.com/contao-components/tinymce4.git", + "reference": "3c0d160bedf1825fdc7a9a04d79008356cdf7a8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/tinymce4/zipball/3c0d160bedf1825fdc7a9a04d79008356cdf7a8e", + "reference": "3c0d160bedf1825fdc7a9a04d79008356cdf7a8e", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1-or-later" + ], + "authors": [ + { + "name": "Tiny", + "homepage": "https://github.com/tinymce" + } + ], + "description": "TinyMCE integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/tinymce4/issues", + "source": "https://github.com/contao-components/tinymce4/tree/6.8.3" + }, + "time": "2024-02-09T09:54:31+00:00" + }, + { + "name": "contao-components/tristen-tablesort", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/contao-components/tristen-tablesort.git", + "reference": "41367130f19432efa8e13c19483c16420110fc97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao-components/tristen-tablesort/zipball/41367130f19432efa8e13c19483c16420110fc97", + "reference": "41367130f19432efa8e13c19483c16420110fc97", + "shasum": "" + }, + "require": { + "contao-components/installer": "^1.0.9" + }, + "type": "contao-component", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tristen Brown", + "homepage": "https://github.com/tristen" + } + ], + "description": "Tablesort integration for Contao Open Source CMS", + "support": { + "issues": "https://github.com/contao-components/tristen-tablesort/issues", + "source": "https://github.com/contao-components/tristen-tablesort/tree/5.3.0" + }, + "time": "2022-06-24T13:24:06+00:00" + }, + { + "name": "contao/conflicts", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/contao/conflicts.git", + "reference": "8d5342f2a54ce5ff61315ce8e1f58fa9d648a4ba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao/conflicts/zipball/8d5342f2a54ce5ff61315ce8e1f58fa9d648a4ba", + "reference": "8d5342f2a54ce5ff61315ce8e1f58fa9d648a4ba", + "shasum": "" + }, + "conflict": { + "doctrine/dbal": "2.9.* <2.9.3 || 3.3.0 || 3.5.0 || 3.7.0", + "doctrine/doctrine-bundle": "2.6.0", + "doctrine/doctrine-migrations-bundle": "<1.1", + "doctrine/orm": "<2.4", + "doctrine/persistence": "1.3.2", + "knplabs/knp-time-bundle": "1.9.0", + "lcobucci/jwt": ">=4.2.0", + "league/flysystem-bundle": "3.3.0", + "lexik/maintenance-bundle": "2.1.4", + "php-http/discovery": "1.15.0", + "symfony/dependency-injection": "5.4.16 || 6.0.16 || 6.1.8 || 6.2.0 || 6.2.1", + "symfony/finder": "3.4.7 || 4.0.7 || 5.4.26 || 6.2.13 || 6.3.2", + "symfony/framework-bundle": "4.2.7 || 5.2.6", + "symfony/http-foundation": "4.4.27 || 4.4.46 || 5.4.13 || 6.0.13 || 6.1.5", + "symfony/http-kernel": "5.4.1 || 5.4.12", + "symfony/routing": "6.4.0", + "symfony/security": "3.3.17 || 3.4.7 || 3.4.8 || 3.4.11", + "symfony/swiftmailer-bundle": "2.6.* <2.6.2", + "symfony/twig-bundle": "4.1.0", + "symfony/web-profiler-bundle": "6.1.* <6.1.2", + "twig/twig": "2.7.0" + }, + "default-branch": true, + "type": "metapackage", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + } + ], + "description": "Contao 4 conflicting packages", + "support": { + "source": "https://github.com/contao/conflicts/tree/main" + }, + "funding": [ + { + "url": "https://to.contao.org/donate", + "type": "custom" + } + ], + "time": "2023-11-30T14:27:33+00:00" + }, + { + "name": "contao/core-bundle", + "version": "5.x-dev", + "source": { + "type": "git", + "url": "https://github.com/contao/core-bundle.git", + "reference": "4cffcff438214c009fc78684f78756be8a3c9822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao/core-bundle/zipball/4cffcff438214c009fc78684f78756be8a3c9822", + "reference": "4cffcff438214c009fc78684f78756be8a3c9822", + "shasum": "" + }, + "require": { + "ausi/slug-generator": "^1.1", + "bacon/bacon-qr-code": "^2.0", + "composer-runtime-api": "^2.0.14", + "contao-components/ace": "^1.8", + "contao-components/chosen": "^2.0", + "contao-components/colorbox": "^1.6", + "contao-components/colorpicker": "^1.5", + "contao-components/contao": "^9.1", + "contao-components/datepicker": "^3.0", + "contao-components/dropzone": "^5.0.1", + "contao-components/handorgel": "^1.0", + "contao-components/jquery": "^3.5", + "contao-components/jquery-ui": "^1.11.4", + "contao-components/mediabox": "^1.5", + "contao-components/mootools": "^1.6.0.1", + "contao-components/simplemodal": "^3.0", + "contao-components/swipe": "^2.0.3", + "contao-components/swiper": "^11.0", + "contao-components/tablesort": "^4.0", + "contao-components/tablesorter": "^2.1", + "contao-components/tinymce4": "^5.0 || ^6.0", + "contao-components/tristen-tablesort": "^5.3", + "contao/image": "^1.2", + "contao/imagine-svg": "^1.0", + "debril/feed-io": "^6.0", + "doctrine/collections": "^2.1", + "doctrine/dbal": "^3.6", + "doctrine/doctrine-bundle": "^2.8", + "doctrine/orm": "^2.17", + "doctrine/persistence": "^3.2", + "dragonmantank/cron-expression": "^2.3", + "ext-dom": "*", + "ext-filter": "*", + "ext-gd": "*", + "ext-hash": "*", + "ext-intl": "*", + "ext-json": "*", + "ext-pcre": "*", + "ext-pdo": "*", + "ext-session": "*", + "ext-zlib": "*", + "friendsofsymfony/http-cache": "^2.15.1", + "friendsofsymfony/http-cache-bundle": "^2.6", + "guzzlehttp/promises": "^1.5", + "imagine/imagine": "^1.2.4", + "knplabs/knp-menu": "^3.1", + "knplabs/knp-menu-bundle": "^3.0", + "knplabs/knp-time-bundle": "^1.11 || ^2.0", + "lcobucci/jwt": "^4.0", + "league/commonmark": "^2.2", + "league/flysystem": "^3.0", + "league/flysystem-bundle": "^3.0", + "matthiasmullie/minify": "^1.3", + "monolog/monolog": "^2.0", + "nelmio/cors-bundle": "^2.0.1", + "nelmio/security-bundle": "^3.0", + "nikic/php-parser": "^4.9", + "nyholm/psr7": "^1.2", + "paragonie/constant_time_encoding": "^2.2", + "php": "^8.1", + "phpspec/php-diff": "^1.0", + "psr/cache": "^3.0", + "psr/container": "^2.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/log": "^1.1 || 2.0 || ^3.0", + "scheb/2fa-backup-code": "^6.0", + "scheb/2fa-bundle": "^6.0", + "scheb/2fa-trusted-device": "^6.0", + "scrivo/highlight.php": "^9.18", + "scssphp/scssphp": "^1.5", + "simplepie/simplepie": "^1.3", + "spatie/schema-org": "^3.4", + "spomky-labs/otphp": "^10.0", + "symfony-cmf/routing": "^3.0", + "symfony-cmf/routing-bundle": "^3.0", + "symfony/asset": "^6.4", + "symfony/cache": "^6.4", + "symfony/cache-contracts": "^3.0", + "symfony/config": "^6.4", + "symfony/console": "^6.4", + "symfony/dependency-injection": "^6.4", + "symfony/deprecation-contracts": "^3.0", + "symfony/doctrine-bridge": "^6.4", + "symfony/doctrine-messenger": "^6.4", + "symfony/dom-crawler": "^6.4", + "symfony/event-dispatcher": "^6.4", + "symfony/event-dispatcher-contracts": "^3.0", + "symfony/expression-language": "^6.4", + "symfony/filesystem": "^6.4", + "symfony/finder": "^6.4", + "symfony/framework-bundle": "^6.4", + "symfony/html-sanitizer": "^6.4", + "symfony/http-client": "^6.4", + "symfony/http-client-contracts": "^3.1", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.4", + "symfony/intl": "^6.4", + "symfony/lock": "^6.4", + "symfony/mailer": "^6.4", + "symfony/messenger": "^6.4", + "symfony/mime": "^6.4", + "symfony/monolog-bridge": "^6.4", + "symfony/password-hasher": "^6.4", + "symfony/polyfill-intl-idn": "^1.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/process": "^6.4", + "symfony/property-access": "^6.4", + "symfony/rate-limiter": "^6.4", + "symfony/routing": "^6.4", + "symfony/security-bundle": "^6.4", + "symfony/security-core": "^6.4", + "symfony/security-csrf": "^6.4", + "symfony/security-http": "^6.4", + "symfony/service-contracts": "^3.0", + "symfony/string": "^6.4", + "symfony/translation": "^6.4", + "symfony/translation-contracts": "^3.0", + "symfony/twig-bridge": "^6.4", + "symfony/twig-bundle": "^6.4", + "symfony/uid": "^6.4", + "symfony/var-dumper": "^6.4", + "symfony/yaml": "^6.4", + "terminal42/escargot": "^1.6", + "terminal42/service-annotation-bundle": "^1.1", + "toflar/cronjob-supervisor": "^1.0", + "twig/string-extra": "^3.0", + "twig/twig": "^3.8", + "ua-parser/uap-php": "^3.9", + "webignition/robots-txt-file": "^3.0", + "wikimedia/less.php": "^1.7" + }, + "conflict": { + "contao-community-alliance/composer-plugin": "<3.0", + "contao/core": "*", + "contao/manager-bundle": "^4.5 <4.5.2", + "contao/manager-plugin": "<2.0 || >=3.0", + "doctrine/cache": "<1.10", + "terminal42/contao-ce-access": "<3.0", + "thecodingmachine/safe": "<1.2" + }, + "require-dev": { + "contao/manager-plugin": "^2.3.1", + "contao/test-case": "self.version", + "ext-fileinfo": "*", + "league/flysystem-memory": "^3.0", + "phpunit/phpunit": "^9.5.19", + "symfony/browser-kit": "^6.4", + "symfony/phpunit-bridge": "^6.4", + "symfony/web-profiler-bundle": "^6.4" + }, + "default-branch": true, + "type": "symfony-bundle", + "extra": { + "contao-manager-plugin": "Contao\\CoreBundle\\ContaoManager\\Plugin" + }, + "autoload": { + "psr-4": { + "Contao\\CoreBundle\\": "src/" + }, + "classmap": [ + "contao/" + ], + "exclude-from-classmap": [ + "contao/config/", + "contao/dca/", + "contao/languages/", + "contao/templates/", + "contao/themes/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + }, + { + "name": "Contao Community", + "homepage": "https://contao.org/contributors" + } + ], + "description": "Contao Open Source CMS", + "homepage": "https://contao.org", + "support": { + "docs": "https://docs.contao.org", + "forum": "https://community.contao.org", + "issues": "https://github.com/contao/contao/issues", + "source": "https://github.com/contao/core-bundle" + }, + "funding": [ + { + "url": "https://to.contao.org/donate", + "type": "other" + } + ], + "time": "2024-02-16T14:28:16+00:00" + }, + { + "name": "contao/image", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/contao/image.git", + "reference": "858d8be1f8500d26ace75c3a724b2ce73b11eebe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao/image/zipball/858d8be1f8500d26ace75c3a724b2ce73b11eebe", + "reference": "858d8be1f8500d26ace75c3a724b2ce73b11eebe", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-gd": "*", + "ext-hash": "*", + "ext-json": "*", + "ext-zlib": "*", + "imagine/imagine": "^1.3", + "php": "^7.2 || ^8.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/polyfill-php73": "^1.27", + "symfony/polyfill-php80": "^1.27" + }, + "conflict": { + "contao/imagine-svg": "<1.0 || >=2.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4", + "contao/imagine-svg": "^1.0", + "contao/test-case": "^4.5", + "phpunit/phpunit": "^8.5 || ^9.5", + "symfony/phpunit-bridge": "^5.4", + "symfony/polyfill-php81": "^1.27" + }, + "suggest": { + "ext-exif": "To support EXIF auto-rotation and preserve copyright metadata" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false, + "target-directory": "tools" + } + }, + "autoload": { + "psr-4": { + "Contao\\Image\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Martin Auswöger", + "homepage": "https://github.com/ausi" + } + ], + "description": "Contao image library", + "support": { + "issues": "https://github.com/contao/image/issues", + "source": "https://github.com/contao/image/tree/1.2.0" + }, + "funding": [ + { + "url": "https://to.contao.org/donate", + "type": "custom" + } + ], + "time": "2023-05-30T13:29:46+00:00" + }, + { + "name": "contao/imagine-svg", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/contao/imagine-svg.git", + "reference": "913cf57746fbbf00ab7eba5e0585e2ef47a05b99" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao/imagine-svg/zipball/913cf57746fbbf00ab7eba5e0585e2ef47a05b99", + "reference": "913cf57746fbbf00ab7eba5e0585e2ef47a05b99", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "imagine/imagine": "^1.1", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "contao/easy-coding-standard": "^3.0", + "contao/test-case": "^4.4", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12.8", + "phpstan/phpstan-symfony": "^0.12.6", + "phpunit/phpunit": "^8.5.4", + "psalm/plugin-phpunit": "^0.15", + "psalm/plugin-symfony": "^2.0", + "slam/phpstan-extensions": "^5.0", + "symfony/filesystem": "^5.0", + "thecodingmachine/phpstan-strict-rules": "^0.12", + "vimeo/psalm": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Contao\\ImagineSvg\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Martin Auswöger", + "homepage": "https://github.com/ausi" + } + ], + "description": "Contao Imagine SVG library", + "support": { + "issues": "https://github.com/contao/imagine-svg/issues", + "source": "https://github.com/contao/imagine-svg/tree/1.0.3" + }, + "time": "2021-08-10T09:33:50+00:00" + }, + { + "name": "contao/manager-bundle", + "version": "5.x-dev", + "source": { + "type": "git", + "url": "https://github.com/contao/manager-bundle.git", + "reference": "c5b416a3105e605becfc799ae98c24fe64233306" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao/manager-bundle/zipball/c5b416a3105e605becfc799ae98c24fe64233306", + "reference": "c5b416a3105e605becfc799ae98c24fe64233306", + "shasum": "" + }, + "require": { + "contao/core-bundle": "self.version", + "contao/manager-plugin": "^2.4", + "doctrine/dbal": "^3.6", + "doctrine/doctrine-bundle": "^2.8", + "ext-json": "*", + "friendsofsymfony/http-cache": "^2.6", + "friendsofsymfony/http-cache-bundle": "^2.6", + "nelmio/cors-bundle": "^2.0.1", + "nelmio/security-bundle": "^2.2 || ^3.0", + "php": "^8.1", + "symfony/cache": "^6.4", + "symfony/config": "^6.4", + "symfony/console": "^6.4", + "symfony/debug-bundle": "^6.4", + "symfony/dependency-injection": "^6.4", + "symfony/deprecation-contracts": "^3.0", + "symfony/doctrine-bridge": "^6.4", + "symfony/dotenv": "^6.4", + "symfony/error-handler": "^6.4", + "symfony/expression-language": "^6.4", + "symfony/filesystem": "^6.4", + "symfony/finder": "^6.4", + "symfony/framework-bundle": "^6.4", + "symfony/http-client": "^6.4", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.4", + "symfony/mailer": "^6.4", + "symfony/monolog-bridge": "^6.4", + "symfony/monolog-bundle": "^3.1", + "symfony/process": "^6.4", + "symfony/routing": "^6.4", + "symfony/security-bundle": "^6.4", + "symfony/stopwatch": "^6.4", + "symfony/twig-bundle": "^6.4", + "symfony/web-profiler-bundle": "^6.4", + "symfony/yaml": "^6.4", + "toflar/psr6-symfony-http-cache-store": "^4.0", + "twig/extra-bundle": "^3.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "contao/news-bundle": "self.version", + "contao/test-case": "self.version", + "phpunit/phpunit": "^9.5", + "symfony/phpunit-bridge": "^6.4" + }, + "default-branch": true, + "bin": [ + "bin/contao-console", + "bin/contao-setup" + ], + "type": "symfony-bundle", + "extra": { + "contao-manager-plugin": "Contao\\ManagerBundle\\ContaoManager\\Plugin" + }, + "autoload": { + "psr-4": { + "Contao\\ManagerBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Leo Feyer", + "homepage": "https://github.com/leofeyer" + }, + { + "name": "Contao Community", + "homepage": "https://contao.org/contributors" + } + ], + "description": "Provides the Contao Managed Edition", + "homepage": "https://contao.org", + "support": { + "docs": "https://docs.contao.org", + "forum": "https://community.contao.org", + "issues": "https://github.com/contao/contao/issues", + "source": "https://github.com/contao/manager-bundle" + }, + "funding": [ + { + "url": "https://to.contao.org/donate", + "type": "other" + } + ], + "time": "2024-02-16T11:01:20+00:00" + }, + { + "name": "contao/manager-plugin", + "version": "2.13.1", + "source": { + "type": "git", + "url": "https://github.com/contao/manager-plugin.git", + "reference": "06b53b7f5a63f5632e3da7788a96536b4a5d0b9b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contao/manager-plugin/zipball/06b53b7f5a63f5632e3da7788a96536b4a5d0b9b", + "reference": "06b53b7f5a63f5632e3da7788a96536b4a5d0b9b", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.7 || ^2.0", + "php": "^7.1 || ^8.0", + "symfony/config": "^3.3 || ^4.0 || ^5.0 || ^6.0", + "symfony/dependency-injection": "^3.3 || ^4.0 || ^5.0 || ^6.0", + "symfony/filesystem": "^3.3 || ^4.0 || ^5.0 || ^6.0", + "symfony/http-kernel": "^3.3 || ^4.0 || ^5.0 || ^6.0", + "symfony/routing": "^3.3 || ^4.0 || ^5.0 || ^6.0" + }, + "conflict": { + "contao/manager-bundle": "4.9.* <4.9.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4", + "composer/composer": "^1.7 || ^2.0", + "contao/core-bundle": "^4.4 || ^5.0", + "ext-zip": "*", + "php-http/guzzle6-adapter": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.3", + "symfony/phpunit-bridge": "^3.4.40 || ^4.0 || ^5.0 || ^6.0", + "webmozart/path-util": "^2.0" + }, + "type": "composer-plugin", + "extra": { + "bamarni-bin": { + "bin-links": false, + "target-directory": "tools" + }, + "class": [ + "Contao\\ManagerPlugin\\Composer\\ArtifactsPlugin", + "Contao\\ManagerPlugin\\Composer\\ManagerPluginInstaller", + "Contao\\ManagerPlugin\\Composer\\AppAutoloadPlugin" + ] + }, + "autoload": { + "psr-4": { + "Contao\\ManagerPlugin\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Andreas Schempp", + "homepage": "https://github.com/aschempp" + } + ], + "description": "Contao 4 manager plugin", + "support": { + "issues": "https://github.com/contao/manager-plugin/issues", + "source": "https://github.com/contao/manager-plugin/tree/2.13.1" + }, + "funding": [ + { + "url": "https://to.contao.org/donate", + "type": "custom" + } + ], + "time": "2024-01-26T11:34:57+00:00" + }, + { + "name": "dasprid/enum", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/DASPRiD/Enum.git", + "reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/6faf451159fb8ba4126b925ed2d78acfce0dc016", + "reference": "6faf451159fb8ba4126b925ed2d78acfce0dc016", + "shasum": "" + }, + "require": { + "php": ">=7.1 <9.0" + }, + "require-dev": { + "phpunit/phpunit": "^7 | ^8 | ^9", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "DASPRiD\\Enum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Ben Scholzen 'DASPRiD'", + "email": "mail@dasprids.de", + "homepage": "https://dasprids.de/", + "role": "Developer" + } + ], + "description": "PHP 7.1 enum implementation", + "keywords": [ + "enum", + "map" + ], + "support": { + "issues": "https://github.com/DASPRiD/Enum/issues", + "source": "https://github.com/DASPRiD/Enum/tree/1.0.5" + }, + "time": "2023-08-25T16:18:39+00:00" + }, + { + "name": "debril/feed-io", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/alexdebril/feed-io.git", + "reference": "0bde9ae2a611d7d36c5ba5afb291b174c2cccb27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/alexdebril/feed-io/zipball/0bde9ae2a611d7d36c5ba5afb291b174c2cccb27", + "reference": "0bde9ae2a611d7d36c5ba5afb291b174c2cccb27", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "nyholm/psr7": "^1.5", + "php": ">=8.1", + "php-http/discovery": "^1.14", + "php-http/httplug": "^2.3", + "psr/http-client-implementation": "*", + "psr/log": "~1.0|~2.0|~3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.5", + "monolog/monolog": "1.*|2.*", + "php-http/mock-client": "^1.5", + "phpstan/phpstan": "^0.12.81", + "phpunit/phpunit": "~9.3.0" + }, + "suggest": { + "monolog/monolog": "Allows to handle logs", + "php-http/guzzle7-adapter": "Handles HTTP requests and responses" + }, + "bin": [ + "bin/feedio" + ], + "type": "library", + "autoload": { + "psr-4": { + "FeedIo\\": "src/FeedIo" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexandre Debril", + "email": "alex.debril@gmail.com" + } + ], + "description": "PHP library built to consume and serve JSONFeed / RSS / Atom feeds", + "homepage": "https://feed-io.net", + "keywords": [ + "atom", + "cli", + "client", + "feed", + "jsonfeed", + "news", + "rss" + ], + "support": { + "issues": "https://github.com/alexdebril/feed-io/issues", + "source": "https://github.com/alexdebril/feed-io/tree/v6.0.3" + }, + "time": "2023-10-16T14:12:49+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "f41715465d65213d644d3141a6a93081be5d3549" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549", + "reference": "f41715465d65213d644d3141a6a93081be5d3549", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2" + }, + "time": "2022-10-27T11:44:00+00:00" + }, + { + "name": "doctrine/annotations", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2 || ^3", + "ext-tokenizer": "*", + "php": "^7.2 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" + }, + "require-dev": { + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^5.4 || ^6", + "vimeo/psalm": "^4.10" + }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/2.0.1" + }, + "time": "2023-02-02T22:02:53+00:00" + }, + { + "name": "doctrine/cache", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "time": "2022-05-20T20:07:39+00:00" + }, + { + "name": "doctrine/collections", + "version": "2.1.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "72328a11443a0de79967104ad36ba7b30bded134" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/72328a11443a0de79967104ad36ba7b30bded134", + "reference": "72328a11443a0de79967104ad36ba7b30bded134", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1", + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "ext-json": "*", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Collections\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", + "keywords": [ + "array", + "collections", + "iterators", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/2.1.4" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections", + "type": "tidelift" + } + ], + "time": "2023-10-03T09:22:33+00:00" + }, + { + "name": "doctrine/common", + "version": "3.4.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/8b5e5650391f851ed58910b3e3d48a71062eeced", + "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced", + "shasum": "" + }, + "require": { + "doctrine/persistence": "^2.0 || ^3.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0 || ^10.0", + "doctrine/collections": "^1", + "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.0", + "symfony/phpunit-bridge": "^6.1", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", + "homepage": "https://www.doctrine-project.org/projects/common.html", + "keywords": [ + "common", + "doctrine", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/common/issues", + "source": "https://github.com/doctrine/common/tree/3.4.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", + "type": "tidelift" + } + ], + "time": "2022-10-09T11:47:59+00:00" + }, + { + "name": "doctrine/dbal", + "version": "3.8.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "a19a1d05ca211f41089dffcc387733a6875196cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/a19a1d05ca211f41089dffcc387733a6875196cb", + "reference": "a19a1d05ca211f41089dffcc387733a6875196cb", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1|^2", + "php": "^7.4 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.1", + "phpstan/phpstan": "1.10.57", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "9.6.16", + "psalm/plugin-phpunit": "0.18.4", + "slevomat/coding-standard": "8.13.1", + "squizlabs/php_codesniffer": "3.8.1", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/console": "^4.4|^5.4|^6.0|^7.0", + "vimeo/psalm": "4.30.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.8.2" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2024-02-12T18:36:36+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "doctrine/doctrine-bundle", + "version": "2.11.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "492725310ae9a1b5b20d6ae09fb5ae6404616e68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/492725310ae9a1b5b20d6ae09fb5ae6404616e68", + "reference": "492725310ae9a1b5b20d6ae09fb5ae6404616e68", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/dbal": "^3.7.0 || ^4.0", + "doctrine/persistence": "^2.2 || ^3", + "doctrine/sql-formatter": "^1.0.1", + "php": "^7.4 || ^8.0", + "symfony/cache": "^5.4 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/doctrine-bridge": "^5.4.19 || ^6.0.7 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" + }, + "conflict": { + "doctrine/annotations": ">=3.0", + "doctrine/orm": "<2.17 || >=4.0", + "twig/twig": "<1.34 || >=2.0 <2.4" + }, + "require-dev": { + "doctrine/annotations": "^1 || ^2", + "doctrine/coding-standard": "^12", + "doctrine/deprecations": "^1.0", + "doctrine/orm": "^2.17 || ^3.0", + "friendsofphp/proxy-manager-lts": "^1.0", + "phpunit/phpunit": "^9.5.26", + "psalm/plugin-phpunit": "^0.18.4", + "psalm/plugin-symfony": "^5", + "psr/log": "^1.1.4 || ^2.0 || ^3.0", + "symfony/phpunit-bridge": "^6.1 || ^7.0", + "symfony/property-info": "^5.4 || ^6.0 || ^7.0", + "symfony/proxy-manager-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/security-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/string": "^5.4 || ^6.0 || ^7.0", + "symfony/twig-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/validator": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^5.4 || ^6.2 || ^7.0", + "symfony/web-profiler-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0", + "twig/twig": "^1.34 || ^2.12 || ^3.0", + "vimeo/psalm": "^5.15" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", + "ext-pdo": "*", + "symfony/web-profiler-bundle": "To use the data collector." + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Doctrine Project", + "homepage": "https://www.doctrine-project.org/" + } + ], + "description": "Symfony DoctrineBundle", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "orm", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/DoctrineBundle/issues", + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.11.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-bundle", + "type": "tidelift" + } + ], + "time": "2024-02-10T20:56:20+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.28" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2022-10-12T20:59:15+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.10", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^11.0", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.10" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" + }, + { + "name": "doctrine/lexer", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^5.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/3.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2024-02-05T11:56:58+00:00" + }, + { + "name": "doctrine/orm", + "version": "2.18.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/orm.git", + "reference": "f2176a9ce56cafdfd1624d54bfdb076819083d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/orm/zipball/f2176a9ce56cafdfd1624d54bfdb076819083d5b", + "reference": "f2176a9ce56cafdfd1624d54bfdb076819083d5b", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.12.1 || ^2.1.1", + "doctrine/collections": "^1.5 || ^2.1", + "doctrine/common": "^3.0.3", + "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/deprecations": "^0.5.3 || ^1", + "doctrine/event-manager": "^1.2 || ^2", + "doctrine/inflector": "^1.4 || ^2.0", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^2 || ^3", + "doctrine/persistence": "^2.4 || ^3", + "ext-ctype": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3", + "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", + "symfony/polyfill-php72": "^1.23", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "doctrine/annotations": "<1.13 || >= 3.0" + }, + "require-dev": { + "doctrine/annotations": "^1.13 || ^2", + "doctrine/coding-standard": "^9.0.2 || ^12.0", + "phpbench/phpbench": "^0.16.10 || ^1.0", + "phpstan/phpstan": "~1.4.10 || 1.10.35", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "psr/log": "^1 || ^2 || ^3", + "squizlabs/php_codesniffer": "3.7.2", + "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "vimeo/psalm": "4.30.0 || 5.16.0" + }, + "suggest": { + "ext-dom": "Provides support for XSD validation for XML mapping files", + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", + "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + }, + "bin": [ + "bin/doctrine" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\ORM\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Object-Relational-Mapper for PHP", + "homepage": "https://www.doctrine-project.org/projects/orm.html", + "keywords": [ + "database", + "orm" + ], + "support": { + "issues": "https://github.com/doctrine/orm/issues", + "source": "https://github.com/doctrine/orm/tree/2.18.0" + }, + "time": "2024-01-31T15:53:12+00:00" + }, + { + "name": "doctrine/persistence", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/persistence.git", + "reference": "63fee8c33bef740db6730eb2a750cd3da6495603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/63fee8c33bef740db6730eb2a750cd3da6495603", + "reference": "63fee8c33bef740db6730eb2a750cd3da6495603", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1 || ^2", + "php": "^7.2 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "doctrine/common": "<2.10" + }, + "require-dev": { + "composer/package-versions-deprecated": "^1.11", + "doctrine/coding-standard": "^11", + "doctrine/common": "^3.0", + "phpstan/phpstan": "1.9.4", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0", + "vimeo/psalm": "4.30.0 || 5.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Persistence\\": "src/Persistence" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "homepage": "https://www.doctrine-project.org/projects/persistence.html", + "keywords": [ + "mapper", + "object", + "odm", + "orm", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/3.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", + "type": "tidelift" + } + ], + "time": "2023-05-17T18:32:04+00:00" + }, + { + "name": "doctrine/sql-formatter", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/sql-formatter.git", + "reference": "25a06c7bf4c6b8218f47928654252863ffc890a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/25a06c7bf4c6b8218f47928654252863ffc890a5", + "reference": "25a06c7bf4c6b8218f47928654252863ffc890a5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4" + }, + "bin": [ + "bin/sql-formatter" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\SqlFormatter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "https://jeremydorn.com/" + } + ], + "description": "a PHP SQL highlighting library", + "homepage": "https://github.com/doctrine/sql-formatter/", + "keywords": [ + "highlight", + "sql" + ], + "support": { + "issues": "https://github.com/doctrine/sql-formatter/issues", + "source": "https://github.com/doctrine/sql-formatter/tree/1.1.3" + }, + "time": "2022-05-23T21:33:49+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "65b2d8ee1f10915efb3b55597da3404f096acba2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/65b2d8ee1f10915efb3b55597da3404f096acba2", + "reference": "65b2d8ee1f10915efb3b55597da3404f096acba2", + "shasum": "" + }, + "require": { + "php": "^7.0|^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.4|^7.0|^8.0|^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2020-10-13T00:52:37+00:00" + }, + { + "name": "egulias/email-validator", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ebaaf5be6c0286928352e054f2d5125608e5405e", + "reference": "ebaaf5be6c0286928352e054f2d5125608e5405e", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^2.0 || ^3.0", + "php": ">=8.1", + "symfony/polyfill-intl-idn": "^1.26" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "vimeo/psalm": "^5.12" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/4.0.2" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2023-10-06T06:47:41+00:00" + }, + { + "name": "friendsofsymfony/http-cache", + "version": "2.15.3", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSHttpCache.git", + "reference": "39f6b356fb253f95067b3c29139949ddbcae3934" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSHttpCache/zipball/39f6b356fb253f95067b3c29139949ddbcae3934", + "reference": "39f6b356fb253f95067b3c29139949ddbcae3934", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "php-http/client-common": "^1.1.0 || ^2.0", + "php-http/client-implementation": "^1.0 || ^2.0", + "php-http/discovery": "^1.12", + "php-http/message": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "symfony/event-dispatcher": "^4.3 || ^5.0 || ^6.0", + "symfony/options-resolver": "^4.3 || ^5.0 || ^6.0" + }, + "conflict": { + "toflar/psr6-symfony-http-cache-store": "<2.2.1" + }, + "require-dev": { + "mockery/mockery": "^1.3.1", + "monolog/monolog": "^1.0", + "php-http/guzzle7-adapter": "^0.1.1", + "php-http/mock-client": "^1.2", + "symfony/http-kernel": "^4.3 || ^5.0 || ^6.0", + "symfony/phpunit-bridge": "^5.0 || ^6.0", + "symfony/process": "^4.3 || ^5.0 || ^6.0" + }, + "suggest": { + "friendsofsymfony/http-cache-bundle": "For integration with the Symfony framework", + "monolog/monolog": "For logging issues while invalidating" + }, + "type": "library", + "autoload": { + "psr-4": { + "FOS\\HttpCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Driebit", + "email": "tech@driebit.nl", + "homepage": "http://www.driebit.nl" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCache/contributors" + } + ], + "description": "Tools to manage HTTP caching proxies with PHP", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCache", + "keywords": [ + "caching", + "http", + "invalidation", + "nginx", + "purge", + "varnish" + ], + "support": { + "issues": "https://github.com/FriendsOfSymfony/FOSHttpCache/issues", + "source": "https://github.com/FriendsOfSymfony/FOSHttpCache/tree/2.15.3" + }, + "time": "2023-12-11T10:07:11+00:00" + }, + { + "name": "friendsofsymfony/http-cache-bundle", + "version": "2.17.0", + "source": { + "type": "git", + "url": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle.git", + "reference": "70f641381efa77307b22a56b98f1f8b60b27bb23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FriendsOfSymfony/FOSHttpCacheBundle/zipball/70f641381efa77307b22a56b98f1f8b60b27bb23", + "reference": "70f641381efa77307b22a56b98f1f8b60b27bb23", + "shasum": "" + }, + "require": { + "friendsofsymfony/http-cache": "^2.15", + "php": "^7.3 || ^8.0", + "symfony/framework-bundle": "^4.4.0 || ^5.0 || ^6.0", + "symfony/http-foundation": "^4.4.0 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.4.0 || ^5.0 || ^6.0" + }, + "conflict": { + "symfony/monolog-bridge": "<3.4.4", + "twig/twig": "<1.12.0" + }, + "require-dev": { + "doctrine/annotations": "^1.11", + "guzzlehttp/guzzle": "^7.2", + "matthiasnoback/symfony-dependency-injection-test": "^4.0", + "mockery/mockery": "^1.3.2", + "monolog/monolog": "*", + "php-http/discovery": "^1.13", + "php-http/guzzle7-adapter": "^0.1.1", + "php-http/httplug": "^2.2.0", + "php-http/message": "^1.0 || ^2.0", + "sebastian/exporter": "^2.0", + "sensio/framework-extra-bundle": "^4.0 || ^5.5.1 || ^6.0", + "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0", + "symfony/console": "^4.4 || ^5.0 || ^6.0", + "symfony/css-selector": "^4.4 || ^5.0 || ^6.0", + "symfony/expression-language": "^4.4 || ^5.0 || ^6.0", + "symfony/finder": "^4.4 || ^5.0 || ^6.0", + "symfony/monolog-bundle": "^3.0", + "symfony/phpunit-bridge": "v5.3.7", + "symfony/routing": "^4.4 || ^5.0 || ^6.0", + "symfony/security-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0", + "symfony/yaml": "^4.4 || ^5.0 || ^6.0", + "twig/twig": "^2.13" + }, + "suggest": { + "jean-beru/fos-http-cache-cloudfront": "To use CloudFront proxy", + "sensio/framework-extra-bundle": "For Tagged Cache Invalidation", + "symfony/console": "To send invalidation requests from the command line", + "symfony/expression-language": "For Tagged Cache Invalidation" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "FOS\\HttpCacheBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Liip AG", + "homepage": "http://www.liip.ch/" + }, + { + "name": "Driebit", + "email": "tech@driebit.nl", + "homepage": "http://www.driebit.nl" + }, + { + "name": "Community contributions", + "homepage": "https://github.com/friendsofsymfony/FOSHttpCacheBundle/contributors" + } + ], + "description": "Set path based HTTP cache headers and send invalidation requests to your HTTP cache", + "homepage": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle", + "keywords": [ + "caching", + "esi", + "http", + "invalidation", + "purge", + "varnish" + ], + "support": { + "issues": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle/issues", + "source": "https://github.com/FriendsOfSymfony/FOSHttpCacheBundle/tree/2.17.0" + }, + "time": "2023-10-10T09:15:19+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2023-05-21T12:31:43+00:00" + }, + { + "name": "hofff/contao-navigation", + "version": "dev-develop", + "dist": { + "type": "path", + "url": "../..", + "reference": "7e3605812828abc41705c857fb765e2b4c117ded" + }, + "require": { + "contao/core-bundle": "^4.13 || ^5.3", + "doctrine/dbal": "^3.8", + "php": "^8.1", + "symfony/config": "^5.4 || ^6.4", + "symfony/dependency-injection": "^5.4 || ^6.4", + "symfony/event-dispatcher-contracts": "^1.1 || ^2.0 || ^3.0", + "symfony/http-foundation": "^5.4 || ^6.4", + "symfony/http-kernel": "^5.4 || ^6.4", + "symfony/security-core": "^5.4 || ^6.4" + }, + "replace": { + "backboneit/contao-navigation": "self.version", + "contao-legacy/backboneit_navigation": "self.version" + }, + "require-dev": { + "contao/manager-plugin": "^2.0", + "doctrine/coding-standard": "^12.0.", + "phpcq/runner-bootstrap": "1.x-dev" + }, + "type": "contao-bundle", + "extra": { + "branch-alias": { + "dev-develop": "2.0.x", + "dev-master": "1.9.x" + }, + "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin" + }, + "autoload": { + "psr-4": { + "Hofff\\Contao\\Navigation\\": "src/" + } + }, + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Oliver Hoff", + "email": "oliver@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Developer" + }, + { + "name": "Nicky Hoff", + "email": "nick@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Maintainer" + }, + { + "name": "David Molineus", + "email": "david@hofff.com", + "homepage": "https://www.hofff.com/", + "role": "Maintainer" + } + ], + "description": "Advanced navigation module for Contao CMS", + "keywords": [ + "contao", + "module", + "navigation", + "page" + ], + "support": { + "issues": "https://github.com/hofff/contao-navigation/issues", + "source": "https://github.com/hofff/contao-navigation" + }, + "transport-options": { + "relative": true + } + }, + { + "name": "imagine/imagine", + "version": "1.3.5", + "source": { + "type": "git", + "url": "https://github.com/php-imagine/Imagine.git", + "reference": "7151d553edec4dc2bbac60419f7a74ff34700e7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-imagine/Imagine/zipball/7151d553edec4dc2bbac60419f7a74ff34700e7f", + "reference": "7151d553edec4dc2bbac60419f7a74ff34700e7f", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.4 || ^9.3" + }, + "suggest": { + "ext-exif": "to read EXIF metadata", + "ext-gd": "to use the GD implementation", + "ext-gmagick": "to use the Gmagick implementation", + "ext-imagick": "to use the Imagick implementation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Imagine\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bulat Shakirzyanov", + "email": "mallluhuct@gmail.com", + "homepage": "http://avalanche123.com" + } + ], + "description": "Image processing for PHP 5.3", + "homepage": "http://imagine.readthedocs.org/", + "keywords": [ + "drawing", + "graphics", + "image manipulation", + "image processing" + ], + "support": { + "issues": "https://github.com/php-imagine/Imagine/issues", + "source": "https://github.com/php-imagine/Imagine/tree/1.3.5" + }, + "time": "2023-06-07T14:49:52+00:00" + }, + { + "name": "knplabs/knp-menu", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/KnpLabs/KnpMenu.git", + "reference": "bf7d89a7ef406fd2ec1aae6f30f722e844bf6d31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/KnpLabs/KnpMenu/zipball/bf7d89a7ef406fd2ec1aae6f30f722e844bf6d31", + "reference": "bf7d89a7ef406fd2ec1aae6f30f722e844bf6d31", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "conflict": { + "twig/twig": "<1.42.3 || >=2,<2.9" + }, + "require-dev": { + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "psr/container": "^1.0", + "symfony/http-foundation": "^5.4 || ^6.0", + "symfony/phpunit-bridge": "^6.2", + "symfony/routing": "^5.4 || ^6.0", + "twig/twig": "^2.9 || ^3.0" + }, + "suggest": { + "twig/twig": "for the TwigRenderer and the integration with your templates" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Menu\\": "src/Knp/Menu" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KnpLabs", + "homepage": "https://knplabs.com" + }, + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + }, + { + "name": "The Community", + "homepage": "https://github.com/KnpLabs/KnpMenu/contributors" + } + ], + "description": "An object oriented menu library", + "homepage": "https://knplabs.com", + "keywords": [ + "menu", + "tree" + ], + "support": { + "issues": "https://github.com/KnpLabs/KnpMenu/issues", + "source": "https://github.com/KnpLabs/KnpMenu/tree/v3.4.0" + }, + "time": "2023-05-17T18:48:46+00:00" + }, + { + "name": "knplabs/knp-menu-bundle", + "version": "v3.3.0", + "source": { + "type": "git", + "url": "https://github.com/KnpLabs/KnpMenuBundle.git", + "reference": "02a2c68a2d6247a21c1d5ed185e2e3e3d9e7dfb5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/KnpLabs/KnpMenuBundle/zipball/02a2c68a2d6247a21c1d5ed185e2e3e3d9e7dfb5", + "reference": "02a2c68a2d6247a21c1d5ed185e2e3e3d9e7dfb5", + "shasum": "" + }, + "require": { + "knplabs/knp-menu": "^3.3", + "php": "^8.0", + "symfony/deprecation-contracts": "^2.5 | ^3.3", + "symfony/framework-bundle": "^5.4 | ^6.0 | ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 | ^10.1", + "symfony/expression-language": "^5.4 | ^6.0 | ^7.0", + "symfony/phpunit-bridge": "^6.0 | ^7.0", + "symfony/templating": "^5.4 | ^6.0 | ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Bundle\\MenuBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Knplabs", + "homepage": "http://knplabs.com" + }, + { + "name": "Christophe Coevoet", + "email": "stof@notk.org" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/KnpLabs/KnpMenuBundle/contributors" + } + ], + "description": "This bundle provides an integration of the KnpMenu library", + "keywords": [ + "menu" + ], + "support": { + "issues": "https://github.com/KnpLabs/KnpMenuBundle/issues", + "source": "https://github.com/KnpLabs/KnpMenuBundle/tree/v3.3.0" + }, + "time": "2023-11-01T09:25:40+00:00" + }, + { + "name": "knplabs/knp-time-bundle", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/KnpLabs/KnpTimeBundle.git", + "reference": "69cb36a9f22ac8432e8532c9ae84e92d46820d96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/KnpLabs/KnpTimeBundle/zipball/69cb36a9f22ac8432e8532c9ae84e92d46820d96", + "reference": "69cb36a9f22ac8432e8532c9ae84e92d46820d96", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "phpunit/phpunit": "^9.6", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0" + }, + "suggest": { + "symfony/twig-bundle": "to use the Twig `time_diff()` function and `|time_diff`/`|duration` filter" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Knp\\Bundle\\TimeBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "KnpLabs Team", + "homepage": "https://knplabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/KnpLabs/KnpTimeBundle/contributors" + } + ], + "description": "Making your dates and durations look sensible and descriptive", + "homepage": "https://github.com/KnpLabs/KnpTimeBundle", + "keywords": [ + "bundle", + "date", + "descriptive time", + "duration", + "knp", + "knplabs", + "time" + ], + "support": { + "issues": "https://github.com/KnpLabs/KnpTimeBundle/issues", + "source": "https://github.com/KnpLabs/KnpTimeBundle/tree/v2.2.0" + }, + "time": "2023-11-13T19:38:34+00:00" + }, + { + "name": "lcobucci/clock", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/clock.git", + "reference": "c7aadcd6fd97ed9e199114269c0be3f335e38876" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/clock/zipball/c7aadcd6fd97ed9e199114269c0be3f335e38876", + "reference": "c7aadcd6fd97ed9e199114269c0be3f335e38876", + "shasum": "" + }, + "require": { + "php": "~8.1.0 || ~8.2.0", + "stella-maris/clock": "^0.1.7" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "require-dev": { + "infection/infection": "^0.26", + "lcobucci/coding-standard": "^9.0", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-deprecation-rules": "^1.1.1", + "phpstan/phpstan-phpunit": "^1.3.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^9.5.27" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com" + } + ], + "description": "Yet another clock abstraction", + "support": { + "issues": "https://github.com/lcobucci/clock/issues", + "source": "https://github.com/lcobucci/clock/tree/2.3.0" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2022-12-19T14:38:11+00:00" + }, + { + "name": "lcobucci/jwt", + "version": "4.1.5", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "fe2d89f2eaa7087af4aa166c6f480ef04e000582" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/fe2d89f2eaa7087af4aa166c6f480ef04e000582", + "reference": "fe2d89f2eaa7087af4aa166c6f480ef04e000582", + "shasum": "" + }, + "require": { + "ext-hash": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", + "ext-sodium": "*", + "lcobucci/clock": "^2.0", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "infection/infection": "^0.21", + "lcobucci/coding-standard": "^6.0", + "mikey179/vfsstream": "^1.6.7", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/php-invoker": "^3.1", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Cobucci", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "support": { + "issues": "https://github.com/lcobucci/jwt/issues", + "source": "https://github.com/lcobucci/jwt/tree/4.1.5" + }, + "funding": [ + { + "url": "https://github.com/lcobucci", + "type": "github" + }, + { + "url": "https://www.patreon.com/lcobucci", + "type": "patreon" + } + ], + "time": "2021-09-28T19:34:56+00:00" + }, + { + "name": "league/commonmark", + "version": "2.4.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.3", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4 || ^2.0", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3 | ^6.0 || ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0", + "unleashedtech/php-coding-standard": "^3.1.1", + "vimeo/psalm": "^4.24.0 || ^5.0.0" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2024-02-02T11:59:32+00:00" + }, + { + "name": "league/config", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.8.2", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2022-12-11T20:36:23+00:00" + }, + { + "name": "league/flysystem", + "version": "3.24.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "b25a361508c407563b34fac6f64a8a17a8819675" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b25a361508c407563b34fac6f64a8a17a8819675", + "reference": "b25a361508c407563b34fac6f64a8a17a8819675", + "shasum": "" + }, + "require": { + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^3.0.34", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.24.0" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2024-02-04T12:10:17+00:00" + }, + { + "name": "league/flysystem-bundle", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-bundle.git", + "reference": "ad6ef9c0a8d918269ae5cf47da2f0a4a995bfbd8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-bundle/zipball/ad6ef9c0a8d918269ae5cf47da2f0a4a995bfbd8", + "reference": "ad6ef9c0a8d918269ae5cf47da2f0a4a995bfbd8", + "shasum": "" + }, + "require": { + "league/flysystem": "^3.0", + "php": ">=8.0", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "league/flysystem-async-aws-s3": "^3.1", + "league/flysystem-aws-s3-v3": "^3.1", + "league/flysystem-azure-blob-storage": "^3.1", + "league/flysystem-ftp": "^3.1", + "league/flysystem-google-cloud-storage": "^3.1", + "league/flysystem-memory": "^3.1", + "league/flysystem-read-only": "^3.15", + "league/flysystem-sftp-v3": "^3.1", + "symfony/dotenv": "^5.4 || ^6.0 || ^7.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "League\\FlysystemBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + } + ], + "description": "Symfony bundle integrating Flysystem into Symfony 5.4+ applications", + "support": { + "issues": "https://github.com/thephpleague/flysystem-bundle/issues", + "source": "https://github.com/thephpleague/flysystem-bundle/tree/3.3.2" + }, + "time": "2023-12-02T17:27:51+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.23.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/b884d2bf9b53bb4804a56d2df4902bb51e253f00", + "reference": "b884d2bf9b53bb4804a56d2df4902bb51e253f00", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem-local/issues", + "source": "https://github.com/thephpleague/flysystem-local/tree/3.23.1" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + } + ], + "time": "2024-01-26T18:25:23+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.15.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "reference": "ce0f4d1e8a6f4eb0ddff33f57c69c50fd09f4301", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.15.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2024-01-28T23:22:08+00:00" + }, + { + "name": "league/uri", + "version": "7.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "bf414ba956d902f5d98bf9385fcf63954f09dce5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/bf414ba956d902f5d98bf9385fcf63954f09dce5", + "reference": "bf414ba956d902f5d98bf9385fcf63954f09dce5", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.3", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.4.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2023-12-01T06:24:25+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.4.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "bd8c487ec236930f7bbc42b8d374fa882fbba0f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/bd8c487ec236930f7bbc42b8d374fa882fbba0f3", + "reference": "bd8c487ec236930f7bbc42b8d374fa882fbba0f3", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.4.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2023-11-24T15:40:42+00:00" + }, + { + "name": "masterminds/html5", + "version": "2.8.1", + "source": { + "type": "git", + "url": "https://github.com/Masterminds/html5-php.git", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f47dcf3c70c584de14f21143c55d9939631bc6cf", + "reference": "f47dcf3c70c584de14f21143c55d9939631bc6cf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Masterminds\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Butcher", + "email": "technosophos@gmail.com" + }, + { + "name": "Matt Farina", + "email": "matt@mattfarina.com" + }, + { + "name": "Asmir Mustafic", + "email": "goetas@gmail.com" + } + ], + "description": "An HTML5 parser and serializer.", + "homepage": "http://masterminds.github.io/html5-php", + "keywords": [ + "HTML5", + "dom", + "html", + "parser", + "querypath", + "serializer", + "xml" + ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.8.1" + }, + "time": "2023-05-10T11:58:31+00:00" + }, + { + "name": "matthiasmullie/minify", + "version": "1.3.71", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/minify.git", + "reference": "ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1", + "reference": "ae42a47d7fecc1fbb7277b2f2d84c37a33edc3b1", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "matthiasmullie/path-converter": "~1.1", + "php": ">=5.3.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": ">=2.0", + "matthiasmullie/scrapbook": ">=1.3", + "phpunit/phpunit": ">=4.8", + "squizlabs/php_codesniffer": ">=3.0" + }, + "suggest": { + "psr/cache-implementation": "Cache implementation to use with Minify::cache" + }, + "bin": [ + "bin/minifycss", + "bin/minifyjs" + ], + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\Minify\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "minify@mullie.eu", + "homepage": "https://www.mullie.eu", + "role": "Developer" + } + ], + "description": "CSS & JavaScript minifier, in PHP. Removes whitespace, strips comments, combines files (incl. @import statements and small assets in CSS files), and optimizes/shortens a few common programming patterns.", + "homepage": "https://github.com/matthiasmullie/minify", + "keywords": [ + "JS", + "css", + "javascript", + "minifier", + "minify" + ], + "support": { + "issues": "https://github.com/matthiasmullie/minify/issues", + "source": "https://github.com/matthiasmullie/minify/tree/1.3.71" + }, + "funding": [ + { + "url": "https://github.com/matthiasmullie", + "type": "github" + } + ], + "time": "2023-04-25T20:33:03+00:00" + }, + { + "name": "matthiasmullie/path-converter", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/path-converter.git", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/path-converter/zipball/e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "reference": "e7d13b2c7e2f2268e1424aaed02085518afa02d9", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\PathConverter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "pathconverter@mullie.eu", + "homepage": "http://www.mullie.eu", + "role": "Developer" + } + ], + "description": "Relative path converter", + "homepage": "http://github.com/matthiasmullie/path-converter", + "keywords": [ + "converter", + "path", + "paths", + "relative" + ], + "support": { + "issues": "https://github.com/matthiasmullie/path-converter/issues", + "source": "https://github.com/matthiasmullie/path-converter/tree/1.1.3" + }, + "time": "2019-02-05T23:41:09+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.9.2", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", + "reference": "437cb3628f4cf6042cc10ae97fc2b8472e48ca1f", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7 || ^8", + "ext-json": "*", + "graylog2/gelf-php": "^1.4.2 || ^2@dev", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "phpspec/prophecy": "^1.15", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5.14", + "predis/predis": "^1.1 || ^2.0", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": "^7", + "swiftmailer/swiftmailer": "^5.3|^6.0", + "symfony/mailer": "^5.4 || ^6", + "symfony/mime": "^5.4 || ^6" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.9.2" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2023-10-27T15:25:26+00:00" + }, + { + "name": "nelmio/cors-bundle", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/nelmio/NelmioCorsBundle.git", + "reference": "78fcdb91f76b080a1008133def9c7f613833933d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/NelmioCorsBundle/zipball/78fcdb91f76b080a1008133def9c7f613833933d", + "reference": "78fcdb91f76b080a1008133def9c7f613833933d", + "shasum": "" + }, + "require": { + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "mockery/mockery": "^1.3.6", + "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Nelmio\\CorsBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nelmio", + "homepage": "http://nelm.io" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/nelmio/NelmioCorsBundle/contributors" + } + ], + "description": "Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony application", + "keywords": [ + "api", + "cors", + "crossdomain" + ], + "support": { + "issues": "https://github.com/nelmio/NelmioCorsBundle/issues", + "source": "https://github.com/nelmio/NelmioCorsBundle/tree/2.4.0" + }, + "time": "2023-11-30T16:41:19+00:00" + }, + { + "name": "nelmio/security-bundle", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/nelmio/NelmioSecurityBundle.git", + "reference": "9ae9fabf708ec5899cda46b2d764864bceaa9c8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nelmio/NelmioSecurityBundle/zipball/9ae9fabf708ec5899cda46b2d764864bceaa9c8e", + "reference": "9ae9fabf708ec5899cda46b2d764864bceaa9c8e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "symfony/framework-bundle": "^5.4 || ^6.3 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.3 || ^7.0", + "symfony/security-core": "^5.4 || ^6.3 || ^7.0", + "symfony/security-csrf": "^5.4 || ^6.3 || ^7.0", + "symfony/security-http": "^5.4 || ^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.3 || ^7.0", + "ua-parser/uap-php": "^3.4.4" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan-symfony": "^1.1", + "phpunit/phpunit": "^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/browser-kit": "^5.4 || ^6.3 || ^7.0", + "symfony/cache": "^5.4 || ^6.3 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/twig-bundle": "^5.4 || ^6.3 || ^7.0", + "twig/twig": "^2.10 || ^3.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Nelmio\\SecurityBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nelmio", + "homepage": "http://nelm.io" + }, + { + "name": "Symfony Community", + "homepage": "https://github.com/nelmio/NelmioSecurityBundle/contributors" + } + ], + "description": "Extra security-related features for Symfony: signed/encrypted cookies, HTTPS/SSL/HSTS handling, cookie session storage, ...", + "keywords": [ + "security" + ], + "support": { + "issues": "https://github.com/nelmio/NelmioSecurityBundle/issues", + "source": "https://github.com/nelmio/NelmioSecurityBundle/tree/v3.1.1" + }, + "time": "2024-01-17T14:32:52+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188", + "reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.3" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.0" + }, + "time": "2023-12-11T11:54:22+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "shasum": "" + }, + "require": { + "php": ">=8.0 <8.4" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.4" + }, + "time": "2024-01-17T16:50:36+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.18.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + }, + "time": "2023-12-10T21:03:43+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.1" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-11-13T09:31:12+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-06-14T06:56:20+00:00" + }, + { + "name": "php-http/client-common", + "version": "2.7.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/client-common.git", + "reference": "1e19c059b0e4d5f717bf5d524d616165aeab0612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/client-common/zipball/1e19c059b0e4d5f717bf5d524d616165aeab0612", + "reference": "1e19c059b0e4d5f717bf5d524d616165aeab0612", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/httplug": "^2.0", + "php-http/message": "^1.6", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0", + "symfony/options-resolver": "~4.0.15 || ~4.1.9 || ^4.2.1 || ^5.0 || ^6.0 || ^7.0", + "symfony/polyfill-php80": "^1.17" + }, + "require-dev": { + "doctrine/instantiator": "^1.1", + "guzzlehttp/psr7": "^1.4", + "nyholm/psr7": "^1.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "phpspec/prophecy": "^1.10.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.33 || ^9.6.7" + }, + "suggest": { + "ext-json": "To detect JSON responses with the ContentTypePlugin", + "ext-libxml": "To detect XML responses with the ContentTypePlugin", + "php-http/cache-plugin": "PSR-6 Cache plugin", + "php-http/logger-plugin": "PSR-3 Logger plugin", + "php-http/stopwatch-plugin": "Symfony Stopwatch plugin" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\Common\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Common HTTP Client implementations and tools for HTTPlug", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "common", + "http", + "httplug" + ], + "support": { + "issues": "https://github.com/php-http/client-common/issues", + "source": "https://github.com/php-http/client-common/tree/2.7.1" + }, + "time": "2023-11-30T10:31:25+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.19.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.19.2" + }, + "time": "2023-11-30T16:49:05+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/625ad742c360c8ac580fcc647a1541d29e257f67", + "reference": "625ad742c360c8ac580fcc647a1541d29e257f67", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1 || ^5.0 || ^6.0", + "phpspec/phpspec": "^5.1 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.4.0" + }, + "time": "2023-04-14T15:10:03+00:00" + }, + { + "name": "php-http/message", + "version": "1.16.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/message.git", + "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message/zipball/47a14338bf4ebd67d317bf1144253d7db4ab55fd", + "reference": "47a14338bf4ebd67d317bf1144253d7db4ab55fd", + "shasum": "" + }, + "require": { + "clue/stream-filter": "^1.5", + "php": "^7.2 || ^8.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.6", + "ext-zlib": "*", + "guzzlehttp/psr7": "^1.0 || ^2.0", + "laminas/laminas-diactoros": "^2.0 || ^3.0", + "php-http/message-factory": "^1.0.2", + "phpspec/phpspec": "^5.1 || ^6.3 || ^7.1", + "slim/slim": "^3.0" + }, + "suggest": { + "ext-zlib": "Used with compressor/decompressor streams", + "guzzlehttp/psr7": "Used with Guzzle PSR-7 Factories", + "laminas/laminas-diactoros": "Used with Diactoros Factories", + "slim/slim": "Used with Slim Framework PSR-7 implementation" + }, + "type": "library", + "autoload": { + "files": [ + "src/filters.php" + ], + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "HTTP Message related tools", + "homepage": "http://php-http.org", + "keywords": [ + "http", + "message", + "psr-7" + ], + "support": { + "issues": "https://github.com/php-http/message/issues", + "source": "https://github.com/php-http/message/tree/1.16.0" + }, + "time": "2023-05-17T06:43:38+00:00" + }, + { + "name": "php-http/message-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/message-factory.git", + "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/4d8778e1c7d405cbb471574821c1ff5b68cc8f57", + "reference": "4d8778e1c7d405cbb471574821c1ff5b68cc8f57", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "stream", + "uri" + ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/1.1.0" + }, + "abandoned": "psr/http-factory", + "time": "2023-04-14T14:16:17+00:00" + }, + { + "name": "php-http/promise", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/2916a606d3b390f4e9e8e2b8dd68581508be0f07", + "reference": "2916a606d3b390f4e9e8e2b8dd68581508be0f07", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2 || ^6.3", + "phpspec/phpspec": "^5.1.2 || ^6.2 || ^7.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.3.0" + }, + "time": "2024-01-04T18:49:48+00:00" + }, + { + "name": "phpspec/php-diff", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/phpspec/php-diff.git", + "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/php-diff/zipball/fc1156187f9f6c8395886fe85ed88a0a245d72e9", + "reference": "fc1156187f9f6c8395886fe85ed88a0a245d72e9", + "shasum": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Diff": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Chris Boulton", + "homepage": "http://github.com/chrisboulton" + } + ], + "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", + "support": { + "source": "https://github.com/phpspec/php-diff/tree/v1.1.3" + }, + "time": "2020-09-18T13:47:07+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + }, + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "scheb/2fa-backup-code", + "version": "v6.12.0", + "source": { + "type": "git", + "url": "https://github.com/scheb/2fa-backup-code.git", + "reference": "1ad84e7eb26eb425c609e03097cac99387dde44c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scheb/2fa-backup-code/zipball/1ad84e7eb26eb425c609e03097cac99387dde44c", + "reference": "1ad84e7eb26eb425c609e03097cac99387dde44c", + "shasum": "" + }, + "require": { + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "scheb/2fa-bundle": "self.version" + }, + "type": "library", + "autoload": { + "psr-4": { + "Scheb\\TwoFactorBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Scheb", + "email": "me@christianscheb.de" + } + ], + "description": "Extends scheb/2fa-bundle with backup codes support", + "homepage": "https://github.com/scheb/2fa", + "keywords": [ + "2fa", + "Authentication", + "backup-codes", + "symfony", + "two-factor", + "two-step" + ], + "support": { + "source": "https://github.com/scheb/2fa-backup-code/tree/v6.12.0" + }, + "time": "2023-12-03T15:44:26+00:00" + }, + { + "name": "scheb/2fa-bundle", + "version": "v6.12.0", + "source": { + "type": "git", + "url": "https://github.com/scheb/2fa-bundle.git", + "reference": "6e51477c53070f27ac3e3d36be1a991870db415a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scheb/2fa-bundle/zipball/6e51477c53070f27ac3e3d36be1a991870db415a", + "reference": "6e51477c53070f27ac3e3d36be1a991870db415a", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "symfony/config": "^5.4 || ^6.0", + "symfony/dependency-injection": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/framework-bundle": "^5.4 || ^6.0", + "symfony/http-foundation": "^5.4 || ^6.0", + "symfony/http-kernel": "^5.4 || ^6.0", + "symfony/property-access": "^5.4 || ^6.0", + "symfony/security-bundle": "^5.4 || ^6.0", + "symfony/twig-bundle": "^5.4 || ^6.0" + }, + "conflict": { + "scheb/two-factor-bundle": "*", + "symfony/security-core": "^7" + }, + "suggest": { + "scheb/2fa-backup-code": "Emergency codes when you have no access to other methods", + "scheb/2fa-email": "Send codes by email", + "scheb/2fa-google-authenticator": "Google Authenticator support", + "scheb/2fa-totp": "Temporary one-time password (TOTP) support (Google Authenticator compatible)", + "scheb/2fa-trusted-device": "Trusted devices support" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Scheb\\TwoFactorBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Scheb", + "email": "me@christianscheb.de" + } + ], + "description": "A generic interface to implement two-factor authentication in Symfony applications", + "homepage": "https://github.com/scheb/2fa", + "keywords": [ + "2fa", + "Authentication", + "symfony", + "two-factor", + "two-step" + ], + "support": { + "source": "https://github.com/scheb/2fa-bundle/tree/v6.12.0" + }, + "time": "2023-12-03T16:02:15+00:00" + }, + { + "name": "scheb/2fa-trusted-device", + "version": "v6.12.0", + "source": { + "type": "git", + "url": "https://github.com/scheb/2fa-trusted-device.git", + "reference": "1ca6158dc6518ca9dba8b111bd9807a8b9be2903" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scheb/2fa-trusted-device/zipball/1ca6158dc6518ca9dba8b111bd9807a8b9be2903", + "reference": "1ca6158dc6518ca9dba8b111bd9807a8b9be2903", + "shasum": "" + }, + "require": { + "lcobucci/clock": "^2.0 || ^3.0", + "lcobucci/jwt": "^4.1 || ^5.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", + "scheb/2fa-bundle": "self.version" + }, + "type": "library", + "autoload": { + "psr-4": { + "Scheb\\TwoFactorBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Scheb", + "email": "me@christianscheb.de" + } + ], + "description": "Extends scheb/2fa-bundle with trusted devices support", + "homepage": "https://github.com/scheb/2fa", + "keywords": [ + "2fa", + "Authentication", + "symfony", + "trusted-device", + "two-factor", + "two-step" + ], + "support": { + "source": "https://github.com/scheb/2fa-trusted-device/tree/v6.12.0" + }, + "time": "2023-12-03T15:44:26+00:00" + }, + { + "name": "scrivo/highlight.php", + "version": "v9.18.1.10", + "source": { + "type": "git", + "url": "https://github.com/scrivo/highlight.php.git", + "reference": "850f4b44697a2552e892ffe71490ba2733c2fc6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/850f4b44697a2552e892ffe71490ba2733c2fc6e", + "reference": "850f4b44697a2552e892ffe71490ba2733c2fc6e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4|^5.4", + "symfony/var-dumper": "^2.8|^3.4|^5.4" + }, + "suggest": { + "ext-mbstring": "Allows highlighting code with unicode characters and supports language with unicode keywords" + }, + "type": "library", + "autoload": { + "files": [ + "HighlightUtilities/functions.php" + ], + "psr-0": { + "Highlight\\": "", + "HighlightUtilities\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Geert Bergman", + "homepage": "http://www.scrivo.org/", + "role": "Project Author" + }, + { + "name": "Vladimir Jimenez", + "homepage": "https://allejo.io", + "role": "Maintainer" + }, + { + "name": "Martin Folkers", + "homepage": "https://twobrain.io", + "role": "Contributor" + } + ], + "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", + "keywords": [ + "code", + "highlight", + "highlight.js", + "highlight.php", + "syntax" + ], + "support": { + "issues": "https://github.com/scrivo/highlight.php/issues", + "source": "https://github.com/scrivo/highlight.php" + }, + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], + "time": "2022-12-17T21:53:22+00:00" + }, + { + "name": "scssphp/scssphp", + "version": "v1.12.1", + "source": { + "type": "git", + "url": "https://github.com/scssphp/scssphp.git", + "reference": "394ed1e960138710a60d035c1a85d43d0bf0faeb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/394ed1e960138710a60d035c1a85d43d0bf0faeb", + "reference": "394ed1e960138710a60d035c1a85d43d0bf0faeb", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4", + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3 || ^9.4", + "sass/sass-spec": "*", + "squizlabs/php_codesniffer": "~3.5", + "symfony/phpunit-bridge": "^5.1", + "thoughtbot/bourbon": "^7.0", + "twbs/bootstrap": "~5.0", + "twbs/bootstrap4": "4.6.1", + "zurb/foundation": "~6.7.0" + }, + "suggest": { + "ext-iconv": "Can be used as fallback when ext-mbstring is not available", + "ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv" + }, + "bin": [ + "bin/pscss" + ], + "type": "library", + "extra": { + "bamarni-bin": { + "forward-command": false, + "bin-links": false + } + }, + "autoload": { + "psr-4": { + "ScssPhp\\ScssPhp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Anthon Pang", + "email": "apang@softwaredevelopment.ca", + "homepage": "https://github.com/robocoder" + }, + { + "name": "Cédric Morin", + "email": "cedric@yterium.com", + "homepage": "https://github.com/Cerdic" + } + ], + "description": "scssphp is a compiler for SCSS written in PHP.", + "homepage": "http://scssphp.github.io/scssphp/", + "keywords": [ + "css", + "less", + "sass", + "scss", + "stylesheet" + ], + "support": { + "issues": "https://github.com/scssphp/scssphp/issues", + "source": "https://github.com/scssphp/scssphp/tree/v1.12.1" + }, + "time": "2024-01-13T12:36:40+00:00" + }, + { + "name": "simplepie/simplepie", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/simplepie/simplepie.git", + "reference": "65b095d87bc00898d8fa7737bdbcda93a3fbcc55" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/simplepie/simplepie/zipball/65b095d87bc00898d8fa7737bdbcda93a3fbcc55", + "reference": "65b095d87bc00898d8fa7737bdbcda93a3fbcc55", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "php": ">=7.2.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.19 || ^3.8", + "psr/simple-cache": "^1 || ^2 || ^3", + "yoast/phpunit-polyfills": "^1.0.1" + }, + "suggest": { + "ext-curl": "", + "ext-iconv": "", + "ext-intl": "", + "ext-mbstring": "", + "mf2/mf2": "Microformat module that allows for parsing HTML for microformats" + }, + "type": "library", + "autoload": { + "psr-0": { + "SimplePie": "library" + }, + "psr-4": { + "SimplePie\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Ryan Parman", + "homepage": "http://ryanparman.com/", + "role": "Creator, alumnus developer" + }, + { + "name": "Sam Sneddon", + "homepage": "https://gsnedders.com/", + "role": "Alumnus developer" + }, + { + "name": "Ryan McCue", + "email": "me@ryanmccue.info", + "homepage": "http://ryanmccue.info/", + "role": "Developer" + } + ], + "description": "A simple Atom/RSS parsing library for PHP", + "homepage": "http://simplepie.org/", + "keywords": [ + "atom", + "feeds", + "rss" + ], + "support": { + "issues": "https://github.com/simplepie/simplepie/issues", + "source": "https://github.com/simplepie/simplepie/tree/1.8.0" + }, + "time": "2023-01-20T08:37:35+00:00" + }, + { + "name": "spatie/schema-org", + "version": "3.23.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/schema-org.git", + "reference": "c95abf7da59f16570aec18ca11d861255e645c39" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/schema-org/zipball/c95abf7da59f16570aec18ca11d861255e645c39", + "reference": "c95abf7da59f16570aec18ca11d861255e645c39", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.6", + "graham-campbell/analyzer": "^3.0.5", + "illuminate/collections": "^8.62.0", + "league/flysystem": "^2.3.0 || ^3.0", + "pestphp/pest": "^1.21", + "symfony/console": "^5.3.7 || 6.0", + "twig/twig": "^3.3.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\SchemaOrg\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + }, + { + "name": "Tom Witkowski", + "email": "dev.gummibeer@gmail.com", + "homepage": "https://gummibeer.de", + "role": "Developer" + } + ], + "description": "A fluent builder Schema.org types and ld+json generator", + "homepage": "https://github.com/spatie/schema-org", + "keywords": [ + "schema-org", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/schema-org/issues", + "source": "https://github.com/spatie/schema-org/tree/3.23.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-01-11T14:58:44+00:00" + }, + { + "name": "spomky-labs/otphp", + "version": "v10.0.3", + "source": { + "type": "git", + "url": "https://github.com/Spomky-Labs/otphp.git", + "reference": "9784d9f7c790eed26e102d6c78f12c754036c366" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/9784d9f7c790eed26e102d6c78f12c754036c366", + "reference": "9784d9f7c790eed26e102d6c78f12c754036c366", + "shasum": "" + }, + "require": { + "beberlei/assert": "^3.0", + "ext-mbstring": "*", + "paragonie/constant_time_encoding": "^2.0", + "php": "^7.2|^8.0", + "thecodingmachine/safe": "^0.1.14|^1.0|^2.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-beberlei-assert": "^0.12", + "phpstan/phpstan-deprecation-rules": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^8.0", + "thecodingmachine/phpstan-safe-rule": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "v10.0": "10.0.x-dev", + "v9.0": "9.0.x-dev", + "v8.3": "8.3.x-dev" + } + }, + "autoload": { + "psr-4": { + "OTPHP\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Florent Morselli", + "homepage": "https://github.com/Spomky" + }, + { + "name": "All contributors", + "homepage": "https://github.com/Spomky-Labs/otphp/contributors" + } + ], + "description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator", + "homepage": "https://github.com/Spomky-Labs/otphp", + "keywords": [ + "FreeOTP", + "RFC 4226", + "RFC 6238", + "google authenticator", + "hotp", + "otp", + "totp" + ], + "support": { + "issues": "https://github.com/Spomky-Labs/otphp/issues", + "source": "https://github.com/Spomky-Labs/otphp/tree/v10.0.3" + }, + "time": "2022-03-17T08:00:35+00:00" + }, + { + "name": "stella-maris/clock", + "version": "0.1.7", + "source": { + "type": "git", + "url": "https://github.com/stella-maris-solutions/clock.git", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stella-maris-solutions/clock/zipball/fa23ce16019289a18bb3446fdecd45befcdd94f8", + "reference": "fa23ce16019289a18bb3446fdecd45befcdd94f8", + "shasum": "" + }, + "require": { + "php": "^7.0|^8.0", + "psr/clock": "^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "StellaMaris\\Clock\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Heigl", + "role": "Maintainer" + } + ], + "description": "A pre-release of the proposed PSR-20 Clock-Interface", + "homepage": "https://gitlab.com/stella-maris/clock", + "keywords": [ + "clock", + "datetime", + "point in time", + "psr20" + ], + "support": { + "source": "https://github.com/stella-maris-solutions/clock/tree/0.1.7" + }, + "time": "2022-11-25T16:15:06+00:00" + }, + { + "name": "symfony-cmf/routing", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony-cmf/Routing.git", + "reference": "4d6e40f8f91f5729e00e5a023640eb13fb359cbd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony-cmf/Routing/zipball/4d6e40f8f91f5729e00e5a023640eb13fb359cbd", + "reference": "4d6e40f8f91f5729e00e5a023640eb13fb359cbd", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/http-kernel": "^6.0 || ^7.0", + "symfony/routing": "^6.0 || ^7.0" + }, + "require-dev": { + "symfony/config": "^6.0 || ^7.0", + "symfony/dependency-injection": "^6.0 || ^7.0", + "symfony/event-dispatcher": "^6.0 || ^7.0", + "symfony/phpunit-bridge": "^7.0.3" + }, + "suggest": { + "symfony/event-dispatcher": "DynamicRouter can optionally trigger an event at the start of matching. Minimal version ^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Cmf\\Component\\Routing\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/Routing/contributors" + } + ], + "description": "Extends the Symfony routing component for dynamic routes and chaining several routers", + "homepage": "http://cmf.symfony.com", + "keywords": [ + "database", + "routing" + ], + "support": { + "issues": "https://github.com/symfony-cmf/Routing/issues", + "source": "https://github.com/symfony-cmf/Routing/tree/3.0.3" + }, + "time": "2024-02-19T02:00:24+00:00" + }, + { + "name": "symfony-cmf/routing-bundle", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony-cmf/routing-bundle.git", + "reference": "e90e86175d4640be33d252645cfd57439d8902ad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony-cmf/routing-bundle/zipball/e90e86175d4640be33d252645cfd57439d8902ad", + "reference": "e90e86175d4640be33d252645cfd57439d8902ad", + "shasum": "" + }, + "require": { + "php": "^8.0", + "symfony-cmf/routing": "^3.0", + "symfony/framework-bundle": "^6.0" + }, + "conflict": { + "doctrine/common": "<3.1.1", + "doctrine/persistence": "<1.3.0", + "doctrine/phpcr-odm": "<1.4", + "phpunit/phpunit": "<6" + }, + "require-dev": { + "doctrine/data-fixtures": "^1.0.0", + "doctrine/doctrine-bundle": "^2.0", + "doctrine/orm": "^2.9", + "doctrine/phpcr-bundle": "^2.3", + "doctrine/phpcr-odm": "^1.4|^2.0", + "jackalope/jackalope-doctrine-dbal": "^1.3", + "matthiasnoback/symfony-config-test": "^4.1.0", + "matthiasnoback/symfony-dependency-injection-test": "^4.1.0", + "symfony-cmf/testing": "dev-master as 4.2.0", + "symfony/form": "^6.0", + "symfony/monolog-bundle": "^3.5", + "symfony/phpunit-bridge": "^6.0", + "symfony/security-bundle": "^6.0", + "symfony/serializer": "^6.0", + "symfony/translation": "^6.0", + "symfony/twig-bundle": "^6.0", + "symfony/validator": "^6.0", + "twig/twig": "^2.4.4 || ^3.0" + }, + "suggest": { + "doctrine/orm": "To enable support for the ORM entities (^2.5)", + "doctrine/phpcr-bundle": "To enable support for the PHPCR ODM documents", + "doctrine/phpcr-odm": "To enable support for the PHPCR ODM documents (^1.4)" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Cmf\\Bundle\\RoutingBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony CMF Community", + "homepage": "https://github.com/symfony-cmf/RoutingBundle/contributors" + } + ], + "description": "Symfony RoutingBundle", + "homepage": "http://cmf.symfony.com", + "keywords": [ + "database", + "routing" + ], + "support": { + "issues": "https://github.com/symfony-cmf/routing-bundle/issues", + "source": "https://github.com/symfony-cmf/routing-bundle/tree/3.0.2" + }, + "time": "2023-06-03T15:52:53+00:00" + }, + { + "name": "symfony/asset", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset.git", + "reference": "14b1c0fddb64af6ea626af51bb3c47af9fa19cb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset/zipball/14b1c0fddb64af6ea626af51bb3c47af9fa19cb7", + "reference": "14b1c0fddb64af6ea626af51bb3c47af9fa19cb7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "symfony/http-foundation": "<5.4" + }, + "require-dev": { + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Asset\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/asset/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/cache", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "49f8cdee544a621a621cd21b6cda32a38926d310" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/49f8cdee544a621a621cd21b6cda32a38926d310", + "reference": "49f8cdee544a621a621cd21b6cda32a38926d310", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.3.6|^7.0" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/var-dumper": "<5.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "1d74b127da04ffa87aa940abe15446fa89653778" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/1d74b127da04ffa87aa940abe15446fa89653778", + "reference": "1d74b127da04ffa87aa940abe15446fa89653778", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-09-25T12:52:38+00:00" + }, + { + "name": "symfony/clock", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/clock.git", + "reference": "f48770105c544001da00b8d745873a628e0de198" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/clock/zipball/f48770105c544001da00b8d745873a628e0de198", + "reference": "f48770105c544001da00b8d745873a628e0de198", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/clock": "^1.0", + "symfony/polyfill-php83": "^1.28" + }, + "provide": { + "psr/clock-implementation": "1.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/now.php" + ], + "psr-4": { + "Symfony\\Component\\Clock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Decouples applications from the system clock", + "homepage": "https://symfony.com", + "keywords": [ + "clock", + "psr20", + "time" + ], + "support": { + "source": "https://github.com/symfony/clock/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/config", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "206482ff3ed450495b1d5b7bad1bc3a852def96f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/206482ff3ed450495b1d5b7bad1bc3a852def96f", + "reference": "206482ff3ed450495b1d5b7bad1bc3a852def96f", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T13:26:27+00:00" + }, + { + "name": "symfony/console", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e", + "reference": "2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/debug-bundle", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug-bundle.git", + "reference": "425c7760a4e6fdc6cb643c791d32277037c971df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/425c7760a4e6fdc6cb643c791d32277037c971df", + "reference": "425c7760a4e6fdc6cb643c791d32277037c971df", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "php": ">=8.1", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/twig-bridge": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/dependency-injection": "<5.4" + }, + "require-dev": { + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/web-profiler-bundle": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\DebugBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/debug-bundle/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "6871811c5a5c5e180244ddb689746446db02c05b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/6871811c5a5c5e180244ddb689746446db02c05b", + "reference": "6871811c5a5c5e180244ddb689746446db02c05b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.2.10|^7.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2", + "symfony/config": "<6.1", + "symfony/finder": "<5.4", + "symfony/proxy-manager-bridge": "<6.3", + "symfony/yaml": "<5.4" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "symfony/service-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "symfony/config": "^6.1|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows you to standardize and centralize the way objects are constructed in your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-30T08:32:12+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/doctrine-bridge", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-bridge.git", + "reference": "9c9a44bb06337dadeb9db1a8b202f15cca804353" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/9c9a44bb06337dadeb9db1a8b202f15cca804353", + "reference": "9c9a44bb06337dadeb9db1a8b202f15cca804353", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1.2|^2", + "doctrine/persistence": "^3.1", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "doctrine/lexer": "<1.1", + "doctrine/orm": "<2.15", + "symfony/cache": "<5.4", + "symfony/dependency-injection": "<6.2", + "symfony/form": "<5.4.21|>=6,<6.2.7", + "symfony/http-foundation": "<6.3", + "symfony/http-kernel": "<6.2", + "symfony/lock": "<6.3", + "symfony/messenger": "<5.4", + "symfony/property-info": "<5.4", + "symfony/security-bundle": "<5.4", + "symfony/security-core": "<6.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "doctrine/collections": "^1.0|^2.0", + "doctrine/data-fixtures": "^1.1", + "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/orm": "^2.15|^3", + "psr/log": "^1|^2|^3", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.2|^7.0", + "symfony/doctrine-messenger": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4.21|^6.2.7|^7.0", + "symfony/http-kernel": "^6.3|^7.0", + "symfony/lock": "^6.3|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/proxy-manager-bridge": "^6.4", + "symfony/security-core": "^6.4|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Doctrine with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-30T11:24:52+00:00" + }, + { + "name": "symfony/doctrine-messenger", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-messenger.git", + "reference": "bd83f174a5f26aa07086a41e1a1f4812409e6542" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/bd83f174a5f26aa07086a41e1a1f4812409e6542", + "reference": "bd83f174a5f26aa07086a41e1a1f4812409e6542", + "shasum": "" + }, + "require": { + "doctrine/dbal": "^2.13|^3|^4", + "php": ">=8.1", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/persistence": "<1.3" + }, + "require-dev": { + "doctrine/persistence": "^1.3|^2|^3", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" + }, + "type": "symfony-messenger-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Doctrine Messenger Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-messenger/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "6db31849011fefe091e94d0bb10cba26f7919894" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/6db31849011fefe091e94d0bb10cba26f7919894", + "reference": "6db31849011fefe091e94d0bb10cba26f7919894", + "shasum": "" + }, + "require": { + "masterminds/html5": "^2.6", + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "symfony/css-selector": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases DOM navigation for HTML and XML documents", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/dotenv", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/dotenv.git", + "reference": "3cb7ca997124760ed1389d5341806247670f4ef8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/3cb7ca997124760ed1389d5341806247670f4ef8", + "reference": "3cb7ca997124760ed1389d5341806247670f4ef8", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "symfony/console": "<5.4", + "symfony/process": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Dotenv\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Registers environment variables from a .env file", + "homepage": "https://symfony.com", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "source": "https://github.com/symfony/dotenv/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "6dc3c76a278b77f01d864a6005d640822c6f26a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/6dc3c76a278b77f01d864a6005d640822c6f26a6", + "reference": "6dc3c76a278b77f01d864a6005d640822c6f26a6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T15:40:36+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae9d3a6f3003a6caf56acd7466d8d52378d44fef", + "reference": "ae9d3a6f3003a6caf56acd7466d8d52378d44fef", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/event-dispatcher": "^1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-05-23T14:45:45+00:00" + }, + { + "name": "symfony/expression-language", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "b4a4ae33fbb33a99d23c5698faaecadb76ad0fe4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/b4a4ae33fbb33a99d23c5698faaecadb76ad0fe4", + "reference": "b4a4ae33fbb33a99d23c5698faaecadb76ad0fe4", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an engine that can compile and evaluate expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/expression-language/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", + "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-10-31T17:30:12+00:00" + }, + { + "name": "symfony/framework-bundle", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/framework-bundle.git", + "reference": "fb413ac4483803954411966a39f3a9204835848e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/fb413ac4483803954411966a39f3a9204835848e", + "reference": "fb413ac4483803954411966a39f3a9204835848e", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.1", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.1|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4", + "symfony/polyfill-mbstring": "~1.0", + "symfony/routing": "^6.4|^7.0" + }, + "conflict": { + "doctrine/annotations": "<1.13.1", + "doctrine/persistence": "<1.3", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/asset": "<5.4", + "symfony/asset-mapper": "<6.4", + "symfony/clock": "<6.3", + "symfony/console": "<5.4|>=7.0", + "symfony/dom-crawler": "<6.4", + "symfony/dotenv": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<6.3", + "symfony/lock": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<6.3", + "symfony/mime": "<6.4", + "symfony/property-access": "<5.4", + "symfony/property-info": "<5.4", + "symfony/scheduler": "<6.4.3|>=7.0.0,<7.0.3", + "symfony/security-core": "<5.4", + "symfony/security-csrf": "<5.4", + "symfony/serializer": "<6.4", + "symfony/stopwatch": "<5.4", + "symfony/translation": "<6.4", + "symfony/twig-bridge": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/validator": "<6.4", + "symfony/web-profiler-bundle": "<6.4", + "symfony/workflow": "<6.4" + }, + "require-dev": { + "doctrine/annotations": "^1.13.1|^2", + "doctrine/persistence": "^1.3|^2|^3", + "dragonmantank/cron-expression": "^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "seld/jsonlint": "^1.10", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/asset-mapper": "^6.4|^7.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/console": "^5.4.9|^6.0.9|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/dotenv": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/html-sanitizer": "^6.1|^7.0", + "symfony/http-client": "^6.3|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/mailer": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.3|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/notifier": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0", + "symfony/scheduler": "^6.4.3|^7.0.3", + "symfony/security-bundle": "^5.4|^6.0|^7.0", + "symfony/semaphore": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/string": "^5.4|^6.0|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0", + "symfony/workflow": "^6.4|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "twig/twig": "^2.10|^3.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\FrameworkBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/framework-bundle/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T15:02:55+00:00" + }, + { + "name": "symfony/html-sanitizer", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/html-sanitizer.git", + "reference": "116335ab09e10b05405f01d8afd31ccc3832b08b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/html-sanitizer/zipball/116335ab09e10b05405f01d8afd31ccc3832b08b", + "reference": "116335ab09e10b05405f01d8afd31ccc3832b08b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "league/uri": "^6.5|^7.0", + "masterminds/html5": "^2.7.2", + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HtmlSanitizer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Titouan Galopin", + "email": "galopintitouan@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to sanitize untrusted HTML input for safe insertion into a document's DOM.", + "homepage": "https://symfony.com", + "keywords": [ + "Purifier", + "html", + "sanitizer" + ], + "support": { + "source": "https://github.com/symfony/html-sanitizer/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/http-client", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "a9034bc119fab8238f76cf49c770f3135f3ead86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/a9034bc119fab8238f76cf49c770f3135f3ead86", + "reference": "a9034bc119fab8238f76cf49c770f3135f3ead86", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "^3", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.3" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/amp": "^2.5", + "amphp/http-client": "^4.2.1", + "amphp/http-tunnel": "^1.0", + "amphp/socket": "^1.1", + "guzzlehttp/promises": "^1.4", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T15:01:07+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "1ee70e699b41909c209a0c930f11034b93578654" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/1ee70e699b41909c209a0c930f11034b93578654", + "reference": "1ee70e699b41909c209a0c930f11034b93578654", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-30T20:28:31+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "5677bdf7cade4619cb17fc9e1e7b31ec392244a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5677bdf7cade4619cb17fc9e1e7b31ec392244a9", + "reference": "5677bdf7cade4619cb17fc9e1e7b31ec392244a9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" + }, + "conflict": { + "symfony/cache": "<6.3" + }, + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "9c6ec4e543044f7568a53a76ab1484ecd30637a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9c6ec4e543044f7568a53a76ab1484ecd30637a2", + "reference": "9c6ec4e543044f7568a53a76ab1484ecd30637a2", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.3", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4.5|^6.0.5|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-exporter": "^6.2|^7.0", + "twig/twig": "^2.13|^3.0.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-31T07:21:29+00:00" + }, + { + "name": "symfony/intl", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/intl.git", + "reference": "2628ded562ca132ed7cdea72f5ec6aaf65d94414" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/intl/zipball/2628ded562ca132ed7cdea72f5ec6aaf65d94414", + "reference": "2628ded562ca132ed7cdea72f5ec6aaf65d94414", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Intl\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Eriksen Costa", + "email": "eriksen.costa@infranology.com.br" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides access to the localization data of the ICU library", + "homepage": "https://symfony.com", + "keywords": [ + "i18n", + "icu", + "internationalization", + "intl", + "l10n", + "localization" + ], + "support": { + "source": "https://github.com/symfony/intl/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/lock", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/lock.git", + "reference": "1cabf3cc775b1aa6008ebd471fa773444af4e956" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/lock/zipball/1cabf3cc775b1aa6008ebd471fa773444af4e956", + "reference": "1cabf3cc775b1aa6008ebd471fa773444af4e956", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/dbal": "<2.13", + "symfony/cache": "<6.2" + }, + "require-dev": { + "doctrine/dbal": "^2.13|^3|^4", + "predis/predis": "^1.1|^2.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Lock\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jérémy Derussé", + "email": "jeremy@derusse.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Creates and manages locks, a mechanism to provide exclusive access to a shared resource", + "homepage": "https://symfony.com", + "keywords": [ + "cas", + "flock", + "locking", + "mutex", + "redlock", + "semaphore" + ], + "support": { + "source": "https://github.com/symfony/lock/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/74412c62f88a85a41b61f0b71ab0afcaad6f03ee", + "reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3|^4", + "php": ">=8.1", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<6.2", + "symfony/mime": "<6.2", + "symfony/twig-bridge": "<6.2.1" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/messenger": "^6.2|^7.0", + "symfony/twig-bridge": "^6.2|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T15:01:07+00:00" + }, + { + "name": "symfony/messenger", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/messenger.git", + "reference": "18d3ea9ed6d1487802f3f716596a6325cdc5ef15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/messenger/zipball/18d3ea9ed6d1487802f3f716596a6325cdc5ef15", + "reference": "18d3ea9ed6d1487802f3f716596a6325cdc5ef15", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/clock": "^6.3|^7.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<6.3", + "symfony/event-dispatcher": "<5.4", + "symfony/event-dispatcher-contracts": "<2.5", + "symfony/framework-bundle": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/serializer": "<5.4" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/console": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/validator": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Samuel Roze", + "email": "samuel.roze@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps applications send and receive messages to/from other applications or via message queues", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/messenger/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-30T13:33:32+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "5017e0a9398c77090b7694be46f20eb796262a34" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/5017e0a9398c77090b7694be46f20eb796262a34", + "reference": "5017e0a9398c77090b7694be46f20eb796262a34", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.3.2" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3.2|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-30T08:32:12+00:00" + }, + { + "name": "symfony/monolog-bridge", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bridge.git", + "reference": "1e1ec293f15dcc815146637ee9ee8a7f43642fa1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/1e1ec293f15dcc815146637ee9ee8a7f43642fa1", + "reference": "1e1ec293f15dcc815146637ee9ee8a7f43642fa1", + "shasum": "" + }, + "require": { + "monolog/monolog": "^1.25.1|^2|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/console": "<5.4", + "symfony/http-foundation": "<5.4", + "symfony/security-core": "<6.0" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/mailer": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/security-core": "^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Monolog\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Monolog with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/monolog-bridge/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T15:01:07+00:00" + }, + { + "name": "symfony/monolog-bundle", + "version": "v3.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/monolog-bundle.git", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181", + "shasum": "" + }, + "require": { + "monolog/monolog": "^1.25.1 || ^2.0 || ^3.0", + "php": ">=7.2.5", + "symfony/config": "^5.4 || ^6.0 || ^7.0", + "symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0", + "symfony/http-kernel": "^5.4 || ^6.0 || ^7.0", + "symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^6.3 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "type": "symfony-bundle", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bundle\\MonologBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony MonologBundle", + "homepage": "https://symfony.com", + "keywords": [ + "log", + "logging" + ], + "support": { + "issues": "https://github.com/symfony/monolog-bundle/issues", + "source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-11-06T17:08:13+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v6.4.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22301f0e7fdeaacc14318928612dee79be99860e", + "reference": "22301f0e7fdeaacc14318928612dee79be99860e", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v6.4.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-08-08T10:16:24+00:00" + }, + { + "name": "symfony/password-hasher", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/password-hasher.git", + "reference": "5189cdfe89a9acb56cc6d6d7a5233bfb180c7268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/password-hasher/zipball/5189cdfe89a9acb56cc6d6d7a5233bfb180c7268", + "reference": "5189cdfe89a9acb56cc6d6d7a5233bfb180c7268", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "conflict": { + "symfony/security-core": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/security-core": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PasswordHasher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Robin Chalas", + "email": "robin.chalas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides password hashing utilities", + "homepage": "https://symfony.com", + "keywords": [ + "hashing", + "password" + ], + "support": { + "source": "https://github.com/symfony/password-hasher/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/polyfill-uuid", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-uuid.git", + "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-uuid/zipball/3abdd21b0ceaa3000ee950097bc3cf9efc137853", + "reference": "3abdd21b0ceaa3000ee950097bc3cf9efc137853", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-uuid": "*" + }, + "suggest": { + "ext-uuid": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Uuid\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for uuid functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/polyfill-uuid/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:11:03+00:00" + }, + { + "name": "symfony/process", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "31642b0818bfcff85930344ef93193f8c607e0a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/31642b0818bfcff85930344ef93193f8c607e0a3", + "reference": "31642b0818bfcff85930344ef93193f8c607e0a3", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/property-access", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-access.git", + "reference": "dd22c9247a16c712bfa128b3c90ebdd505102778" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-access/zipball/dd22c9247a16c712bfa128b3c90ebdd505102778", + "reference": "dd22c9247a16c712bfa128b3c90ebdd505102778", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/property-info": "^5.4|^6.0|^7.0" + }, + "require-dev": { + "symfony/cache": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyAccess\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides functions to read and write from/to an object or array using a simple string notation", + "homepage": "https://symfony.com", + "keywords": [ + "access", + "array", + "extraction", + "index", + "injection", + "object", + "property", + "property-path", + "reflection" + ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/property-info", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/property-info.git", + "reference": "e96d740ab5ac39aa530c8eaa0720ea8169118e26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/property-info/zipball/e96d740ab5ac39aa530c8eaa0720ea8169118e26", + "reference": "e96d740ab5ac39aa530c8eaa0720ea8169118e26", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/string": "^5.4|^6.0|^7.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<5.2", + "phpdocumentor/type-resolver": "<1.5.1", + "symfony/dependency-injection": "<5.4", + "symfony/serializer": "<6.4" + }, + "require-dev": { + "phpdocumentor/reflection-docblock": "^5.2", + "phpstan/phpdoc-parser": "^1.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\PropertyInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kévin Dunglas", + "email": "dunglas@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts information about PHP class' properties using metadata of popular sources", + "homepage": "https://symfony.com", + "keywords": [ + "doctrine", + "phpdoc", + "property", + "symfony", + "type", + "validator" + ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/rate-limiter", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/rate-limiter.git", + "reference": "5b8689fd55becd6b376ec49a542773c98985a7df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/rate-limiter/zipball/5b8689fd55becd6b376ec49a542773c98985a7df", + "reference": "5b8689fd55becd6b376ec49a542773c98985a7df", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/options-resolver": "^5.4|^6.0|^7.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/lock": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\RateLimiter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Wouter de Jong", + "email": "wouter@wouterj.nl" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a Token Bucket implementation to rate limit input and output in your application", + "homepage": "https://symfony.com", + "keywords": [ + "limiter", + "rate-limiter" + ], + "support": { + "source": "https://github.com/symfony/rate-limiter/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/routing", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "3b2957ad54902f0f544df83e3d58b38d7e8e5842" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/3b2957ad54902f0f544df83e3d58b38d7e8e5842", + "reference": "3b2957ad54902f0f544df83e3d58b38d7e8e5842", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<6.2", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12|^2", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.2|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-30T13:55:02+00:00" + }, + { + "name": "symfony/security-bundle", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-bundle.git", + "reference": "a53a9e1f6695447ce613aa8c9c698cfd012bd2aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-bundle/zipball/a53a9e1f6695447ce613aa8c9c698cfd012bd2aa", + "reference": "a53a9e1f6695447ce613aa8c9c698cfd012bd2aa", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "ext-xml": "*", + "php": ">=8.1", + "symfony/clock": "^6.3|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/dependency-injection": "^6.2|^7.0", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.2|^7.0", + "symfony/http-kernel": "^6.2", + "symfony/password-hasher": "^5.4|^6.0|^7.0", + "symfony/security-core": "^6.2|^7.0", + "symfony/security-csrf": "^5.4|^6.0|^7.0", + "symfony/security-http": "^6.3.6|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/console": "<5.4", + "symfony/framework-bundle": "<6.4", + "symfony/http-client": "<5.4", + "symfony/ldap": "<5.4", + "symfony/serializer": "<6.4", + "symfony/twig-bundle": "<5.4", + "symfony/validator": "<6.4" + }, + "require-dev": { + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/ldap": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/twig-bridge": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "twig/twig": "^2.13|^3.0.4", + "web-token/jwt-checker": "^3.1", + "web-token/jwt-signature-algorithm-ecdsa": "^3.1", + "web-token/jwt-signature-algorithm-eddsa": "^3.1", + "web-token/jwt-signature-algorithm-hmac": "^3.1", + "web-token/jwt-signature-algorithm-none": "^3.1", + "web-token/jwt-signature-algorithm-rsa": "^3.1" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\SecurityBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration of the Security component into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-bundle/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-28T15:49:46+00:00" + }, + { + "name": "symfony/security-core", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-core.git", + "reference": "bb10f630cf5b1819ff80aa3ad57a09c61268fc48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-core/zipball/bb10f630cf5b1819ff80aa3ad57a09c61268fc48", + "reference": "bb10f630cf5b1819ff80aa3ad57a09c61268fc48", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/event-dispatcher-contracts": "^2.5|^3", + "symfony/password-hasher": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/event-dispatcher": "<5.4", + "symfony/http-foundation": "<5.4", + "symfony/ldap": "<5.4", + "symfony/security-guard": "<5.4", + "symfony/translation": "<5.4.35|>=6.0,<6.3.12|>=6.4,<6.4.3|>=7.0,<7.0.3", + "symfony/validator": "<5.4" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "psr/container": "^1.1|^2.0", + "psr/log": "^1|^2|^3", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/ldap": "^5.4|^6.0|^7.0", + "symfony/string": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4.35|~6.3.12|^6.4.3|^7.0.3", + "symfony/validator": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Core\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - Core Library", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-core/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/security-csrf", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-csrf.git", + "reference": "e10257dd26f965d75e96bbfc27e46efd943f3010" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/e10257dd26f965d75e96bbfc27e46efd943f3010", + "reference": "e10257dd26f965d75e96bbfc27e46efd943f3010", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/security-core": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/http-foundation": "<5.4" + }, + "require-dev": { + "symfony/http-foundation": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Csrf\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - CSRF Library", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-csrf/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/security-http", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/security-http.git", + "reference": "d1962d08e02d620dccbaa28192498642500b5043" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/security-http/zipball/d1962d08e02d620dccbaa28192498642500b5043", + "reference": "d1962d08e02d620dccbaa28192498642500b5043", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-foundation": "^6.2|^7.0", + "symfony/http-kernel": "^6.3|^7.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "symfony/clock": "<6.3", + "symfony/event-dispatcher": "<5.4.9|>=6,<6.0.9", + "symfony/http-client-contracts": "<3.0", + "symfony/security-bundle": "<5.4", + "symfony/security-csrf": "<5.4" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.3|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^3.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/security-csrf": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "web-token/jwt-checker": "^3.1", + "web-token/jwt-signature-algorithm-ecdsa": "^3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Security\\Http\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Security Component - HTTP Integration", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/security-http/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0", + "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-12-26T14:02:43+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/416596166641f1f728b0a64f5b9dd07cceb410c1", + "reference": "416596166641f1f728b0a64f5b9dd07cceb410c1", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a way to profile code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:35:58+00:00" + }, + { + "name": "symfony/string", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "7a14736fb179876575464e4658fce0c304e8c15b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/7a14736fb179876575464e4658fce0c304e8c15b", + "reference": "7a14736fb179876575464e4658fce0c304e8c15b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-25T09:26:29+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "637c51191b6b184184bbf98937702bcf554f7d04" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/637c51191b6b184184bbf98937702bcf554f7d04", + "reference": "637c51191b6b184184bbf98937702bcf554f7d04", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T13:11:52+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.4.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "06450585bf65e978026bda220cdebca3f867fde7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/06450585bf65e978026bda220cdebca3f867fde7", + "reference": "06450585bf65e978026bda220cdebca3f867fde7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.4-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-12-26T14:02:43+00:00" + }, + { + "name": "symfony/twig-bridge", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/twig-bridge.git", + "reference": "bf6b411a5d9a0ce6ea43cca0fcf5f05f5196a957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/bf6b411a5d9a0ce6ea43cca0fcf5f05f5196a957", + "reference": "bf6b411a5d9a0ce6ea43cca0fcf5f05f5196a957", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/translation-contracts": "^2.5|^3", + "twig/twig": "^2.13|^3.0.4" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/console": "<5.4", + "symfony/form": "<6.3", + "symfony/http-foundation": "<5.4", + "symfony/http-kernel": "<6.4", + "symfony/mime": "<6.2", + "symfony/serializer": "<6.4", + "symfony/translation": "<5.4", + "symfony/workflow": "<5.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3|^4", + "league/html-to-markdown": "^5.0", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/asset-mapper": "^6.3|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/html-sanitizer": "^6.1|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", + "symfony/mime": "^6.2|^7.0", + "symfony/polyfill-intl-icu": "~1.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/security-acl": "^2.8|^3.0", + "symfony/security-core": "^5.4|^6.0|^7.0", + "symfony/security-csrf": "^5.4|^6.0|^7.0", + "symfony/security-http": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^6.1|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0", + "symfony/workflow": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", + "twig/cssinliner-extra": "^2.12|^3", + "twig/inky-extra": "^2.12|^3", + "twig/markdown-extra": "^2.12|^3" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\Bridge\\Twig\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides integration for Twig with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-30T08:32:12+00:00" + }, + { + "name": "symfony/twig-bundle", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/twig-bundle.git", + "reference": "2e63e50de2ade430191af0b5d21bfd6526fe3709" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/2e63e50de2ade430191af0b5d21bfd6526fe3709", + "reference": "2e63e50de2ade430191af0b5d21bfd6526fe3709", + "shasum": "" + }, + "require": { + "composer-runtime-api": ">=2.1", + "php": ">=8.1", + "symfony/config": "^6.1|^7.0", + "symfony/dependency-injection": "^6.1|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^6.2", + "symfony/twig-bridge": "^6.4", + "twig/twig": "^2.13|^3.0.4" + }, + "conflict": { + "symfony/framework-bundle": "<5.4", + "symfony/translation": "<5.4" + }, + "require-dev": { + "symfony/asset": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/form": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/web-link": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\TwigBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a tight integration of Twig into the Symfony full-stack framework", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/twig-bundle/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/uid", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/uid.git", + "reference": "1d31267211cc3a2fff32bcfc7c1818dac41b6fc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/uid/zipball/1d31267211cc3a2fff32bcfc7c1818dac41b6fc0", + "reference": "1d31267211cc3a2fff32bcfc7c1818dac41b6fc0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-uuid": "^1.15" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Uid\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Pineau", + "email": "lyrixx@lyrixx.info" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to generate and represent UIDs", + "homepage": "https://symfony.com", + "keywords": [ + "UID", + "ulid", + "uuid" + ], + "support": { + "source": "https://github.com/symfony/uid/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "0435a08f69125535336177c29d56af3abc1f69da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0435a08f69125535336177c29d56af3abc1f69da", + "reference": "0435a08f69125535336177c29d56af3abc1f69da", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", + "twig/twig": "^2.13|^3.0.4" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:53:30+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "a8c12b5448a5ac685347f5eeb2abf6a571ec16b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a8c12b5448a5ac685347f5eeb2abf6a571ec16b8", + "reference": "a8c12b5448a5ac685347f5eeb2abf6a571ec16b8", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "require-dev": { + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "symfony/web-profiler-bundle", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/web-profiler-bundle.git", + "reference": "e78f98da7b4f842bab89368d53c962f5b2f9e49c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/e78f98da7b4f842bab89368d53c962f5b2f9e49c", + "reference": "e78f98da7b4f842bab89368d53c962f5b2f9e49c", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "conflict": { + "symfony/form": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/twig-bundle": ">=7.0" + }, + "require-dev": { + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Symfony\\Bundle\\WebProfilerBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a development tool that gives detailed information about the execution of any request", + "homepage": "https://symfony.com", + "keywords": [ + "dev" + ], + "support": { + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-28T15:49:46+00:00" + }, + { + "name": "symfony/yaml", + "version": "v6.4.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "d75715985f0f94f978e3a8fa42533e10db921b90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d75715985f0f94f978e3a8fa42533e10db921b90", + "reference": "d75715985f0f94f978e3a8fa42533e10db921b90", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<5.4" + }, + "require-dev": { + "symfony/console": "^5.4|^6.0|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v6.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-23T14:51:35+00:00" + }, + { + "name": "terminal42/escargot", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/terminal42/escargot.git", + "reference": "2585a08cf3b68171a8445f9f0d0e1eb22ab6cccd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/terminal42/escargot/zipball/2585a08cf3b68171a8445f9f0d0e1eb22ab6cccd", + "reference": "2585a08cf3b68171a8445f9f0d0e1eb22ab6cccd", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "nyholm/psr7": "^1.1", + "php": "^8.1", + "psr/http-message": "^1.0 || ^2.0", + "psr/log": "^1.1 || ^2.0 || ^3.0", + "symfony/clock": "^6.2", + "symfony/dom-crawler": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/http-client": "^5.4 || ^6.0", + "webignition/robots-txt-file": "^3.0" + }, + "require-dev": { + "doctrine/dbal": "^3.6", + "fig/log-test": "^1.0", + "symfony/finder": "^5.4|| ^6.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0", + "terminal42/contao-build-tools": "@dev" + }, + "type": "library", + "autoload": { + "psr-4": { + "Terminal42\\Escargot\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Yanick Witschi", + "homepage": "https://github.com/toflar", + "role": "Developer" + } + ], + "description": "A web crawler or spider library based on Symfony components", + "homepage": "https://www.terminal42.ch", + "keywords": [ + "crawl", + "escargot", + "index", + "search", + "spider" + ], + "support": { + "issues": "https://github.com/terminal42/escargot/issues", + "source": "https://github.com/terminal42/escargot" + }, + "time": "2023-11-09T16:34:27+00:00" + }, + { + "name": "terminal42/service-annotation-bundle", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/terminal42/service-annotation-bundle.git", + "reference": "f05105b65825d40234efb581f19088da0d843f6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/terminal42/service-annotation-bundle/zipball/f05105b65825d40234efb581f19088da0d843f6e", + "reference": "f05105b65825d40234efb581f19088da0d843f6e", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1.6 || ^2.0", + "php": "^7.1 || ^8.0", + "symfony/dependency-injection": "^4.0 || ^5.0 || ^6.0", + "symfony/http-kernel": "^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "contao/easy-coding-standard": "^3.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Terminal42\\ServiceAnnotationBundle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "terminal42 gmbh", + "homepage": "https://www.terminal42.ch/" + } + ], + "description": "Add service tags from class annotations", + "support": { + "issues": "https://github.com/terminal42/service-annotation-bundle/issues", + "source": "https://github.com/terminal42/service-annotation-bundle" + }, + "funding": [ + { + "url": "https://github.com/sponsors/terminal42", + "type": "github" + }, + { + "url": "https://ko-fi.com/terminal42", + "type": "other" + } + ], + "time": "2023-03-29T06:10:00+00:00" + }, + { + "name": "thecodingmachine/safe", + "version": "v2.5.0", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/safe.git", + "reference": "3115ecd6b4391662b4931daac4eba6b07a2ac1f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/safe/zipball/3115ecd6b4391662b4931daac4eba6b07a2ac1f0", + "reference": "3115ecd6b4391662b4931daac4eba6b07a2ac1f0", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.5", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.2", + "thecodingmachine/phpstan-strict-rules": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "files": [ + "deprecated/apc.php", + "deprecated/array.php", + "deprecated/datetime.php", + "deprecated/libevent.php", + "deprecated/misc.php", + "deprecated/password.php", + "deprecated/mssql.php", + "deprecated/stats.php", + "deprecated/strings.php", + "lib/special_cases.php", + "deprecated/mysqli.php", + "generated/apache.php", + "generated/apcu.php", + "generated/array.php", + "generated/bzip2.php", + "generated/calendar.php", + "generated/classobj.php", + "generated/com.php", + "generated/cubrid.php", + "generated/curl.php", + "generated/datetime.php", + "generated/dir.php", + "generated/eio.php", + "generated/errorfunc.php", + "generated/exec.php", + "generated/fileinfo.php", + "generated/filesystem.php", + "generated/filter.php", + "generated/fpm.php", + "generated/ftp.php", + "generated/funchand.php", + "generated/gettext.php", + "generated/gmp.php", + "generated/gnupg.php", + "generated/hash.php", + "generated/ibase.php", + "generated/ibmDb2.php", + "generated/iconv.php", + "generated/image.php", + "generated/imap.php", + "generated/info.php", + "generated/inotify.php", + "generated/json.php", + "generated/ldap.php", + "generated/libxml.php", + "generated/lzf.php", + "generated/mailparse.php", + "generated/mbstring.php", + "generated/misc.php", + "generated/mysql.php", + "generated/network.php", + "generated/oci8.php", + "generated/opcache.php", + "generated/openssl.php", + "generated/outcontrol.php", + "generated/pcntl.php", + "generated/pcre.php", + "generated/pgsql.php", + "generated/posix.php", + "generated/ps.php", + "generated/pspell.php", + "generated/readline.php", + "generated/rpminfo.php", + "generated/rrd.php", + "generated/sem.php", + "generated/session.php", + "generated/shmop.php", + "generated/sockets.php", + "generated/sodium.php", + "generated/solr.php", + "generated/spl.php", + "generated/sqlsrv.php", + "generated/ssdeep.php", + "generated/ssh2.php", + "generated/stream.php", + "generated/strings.php", + "generated/swoole.php", + "generated/uodbc.php", + "generated/uopz.php", + "generated/url.php", + "generated/var.php", + "generated/xdiff.php", + "generated/xml.php", + "generated/xmlrpc.php", + "generated/yaml.php", + "generated/yaz.php", + "generated/zip.php", + "generated/zlib.php" + ], + "classmap": [ + "lib/DateTime.php", + "lib/DateTimeImmutable.php", + "lib/Exceptions/", + "deprecated/Exceptions/", + "generated/Exceptions/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHP core functions that throw exceptions instead of returning FALSE on error", + "support": { + "issues": "https://github.com/thecodingmachine/safe/issues", + "source": "https://github.com/thecodingmachine/safe/tree/v2.5.0" + }, + "time": "2023-04-05T11:54:14+00:00" + }, + { + "name": "toflar/cronjob-supervisor", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Toflar/cronjob-supervisor.git", + "reference": "64bc57465313581584ac6215247b94fb761cb70e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Toflar/cronjob-supervisor/zipball/64bc57465313581584ac6215247b94fb761cb70e", + "reference": "64bc57465313581584ac6215247b94fb761cb70e", + "shasum": "" + }, + "require": { + "php": "^8.1", + "symfony/filesystem": "^6.0", + "symfony/lock": "^6.0", + "symfony/process": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.2", + "terminal42/contao-build-tools": "@dev" + }, + "type": "library", + "autoload": { + "psr-4": { + "Toflar\\CronjobSupervisor\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Yanick Witschi", + "email": "yanick.witschi@terminal42.ch" + } + ], + "description": "A simple supervisor for processes that can be triggered using a minutely cronjob", + "support": { + "issues": "https://github.com/Toflar/cronjob-supervisor/issues", + "source": "https://github.com/Toflar/cronjob-supervisor/tree/1.0.0" + }, + "time": "2023-11-13T21:13:04+00:00" + }, + { + "name": "toflar/psr6-symfony-http-cache-store", + "version": "4.2.0", + "source": { + "type": "git", + "url": "https://github.com/Toflar/psr6-symfony-http-cache-store.git", + "reference": "9b3eb5b5f449a886b3ce202ddf3705e3d2ac79c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Toflar/psr6-symfony-http-cache-store/zipball/9b3eb5b5f449a886b3ce202ddf3705e3d2ac79c9", + "reference": "9b3eb5b5f449a886b3ce202ddf3705e3d2ac79c9", + "shasum": "" + }, + "require": { + "php": "^8.0", + "symfony/cache": "^6.0 || ^7.0", + "symfony/http-foundation": "^6.0 || ^7.0", + "symfony/http-kernel": "^6.0 || ^7.0", + "symfony/lock": "^6.0 || ^7.0", + "symfony/options-resolver": "^6.0 || ^7.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Toflar\\Psr6HttpCacheStore\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Yanick Witschi", + "email": "yanick.witschi@terminal42.ch" + } + ], + "description": "An alternative store implementation for Symfony's HttpCache reverse proxy that supports auto-pruning of expired entries and cache invalidation by tags.", + "support": { + "issues": "https://github.com/Toflar/psr6-symfony-http-cache-store/issues", + "source": "https://github.com/Toflar/psr6-symfony-http-cache-store/tree/4.2.0" + }, + "time": "2023-09-18T14:46:04+00:00" + }, + { + "name": "twig/extra-bundle", + "version": "v3.8.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/twig-extra-bundle.git", + "reference": "32807183753de0388c8e59f7ac2d13bb47311140" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/32807183753de0388c8e59f7ac2d13bb47311140", + "reference": "32807183753de0388c8e59f7ac2d13bb47311140", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/twig-bundle": "^5.4|^6.0|^7.0", + "twig/twig": "^3.0" + }, + "require-dev": { + "league/commonmark": "^1.0|^2.0", + "symfony/phpunit-bridge": "^6.4|^7.0", + "twig/cache-extra": "^3.0", + "twig/cssinliner-extra": "^2.12|^3.0", + "twig/html-extra": "^2.12|^3.0", + "twig/inky-extra": "^2.12|^3.0", + "twig/intl-extra": "^2.12|^3.0", + "twig/markdown-extra": "^2.12|^3.0", + "twig/string-extra": "^2.12|^3.0" + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Twig\\Extra\\TwigExtraBundle\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Symfony bundle for extra Twig extensions", + "homepage": "https://twig.symfony.com", + "keywords": [ + "bundle", + "extra", + "twig" + ], + "support": { + "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.8.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2023-11-21T14:02:01+00:00" + }, + { + "name": "twig/string-extra", + "version": "v3.8.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/string-extra.git", + "reference": "b0c9037d96baff79abe368dc092a59b726517548" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/string-extra/zipball/b0c9037d96baff79abe368dc092a59b726517548", + "reference": "b0c9037d96baff79abe368dc092a59b726517548", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/string": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^3.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Twig\\Extra\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + } + ], + "description": "A Twig extension for Symfony String", + "homepage": "https://twig.symfony.com", + "keywords": [ + "html", + "string", + "twig", + "unicode" + ], + "support": { + "source": "https://github.com/twigphp/string-extra/tree/v3.8.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2023-11-21T14:02:01+00:00" + }, + { + "name": "twig/twig", + "version": "v3.8.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.22" + }, + "require-dev": { + "psr/container": "^1.0|^2.0", + "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.8.0" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2023-11-21T18:54:41+00:00" + }, + { + "name": "ua-parser/uap-php", + "version": "v3.9.14", + "source": { + "type": "git", + "url": "https://github.com/ua-parser/uap-php.git", + "reference": "b796c5ea5df588e65aeb4e2c6cce3811dec4fed6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ua-parser/uap-php/zipball/b796c5ea5df588e65aeb4e2c6cce3811dec4fed6", + "reference": "b796c5ea5df588e65aeb4e2c6cce3811dec4fed6", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.1", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.33", + "phpunit/phpunit": "^8 || ^9", + "symfony/console": "^3.4 || ^4.2 || ^4.3 || ^5.0", + "symfony/filesystem": "^3.4 || ^4.2 || ^4.3 || ^5.0", + "symfony/finder": "^3.4 || ^4.2 || ^4.3 || ^5.0", + "symfony/yaml": "^3.4 || ^4.2 || ^4.3 || ^5.0", + "vimeo/psalm": "^3.12" + }, + "suggest": { + "symfony/console": "Required for CLI usage - ^3.4 || ^4.3 || ^5.0", + "symfony/filesystem": "Required for CLI usage - ^3.4 || ^4.3 || ^5.0", + "symfony/finder": "Required for CLI usage - ^3.4 || ^4.3 || ^5.0", + "symfony/yaml": "Required for CLI usage - ^3.4 || ^4.3 || ^5.0" + }, + "bin": [ + "bin/uaparser" + ], + "type": "library", + "autoload": { + "psr-4": { + "UAParser\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dave Olsen", + "email": "dmolsen@gmail.com" + }, + { + "name": "Lars Strojny", + "email": "lars@strojny.net" + } + ], + "description": "A multi-language port of Browserscope's user agent parser.", + "support": { + "issues": "https://github.com/ua-parser/uap-php/issues", + "source": "https://github.com/ua-parser/uap-php/tree/v3.9.14" + }, + "time": "2020-10-02T23:36:20+00:00" + }, + { + "name": "webignition/disallowed-character-terminated-string", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/webignition/disallowed-character-terminated-string.git", + "reference": "1c35b8bacbb2e76837c0aa8538dc2468a1f10e6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webignition/disallowed-character-terminated-string/zipball/1c35b8bacbb2e76837c0aa8538dc2468a1f10e6e", + "reference": "1c35b8bacbb2e76837c0aa8538dc2468a1f10e6e", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.3", + "phpunit/phpunit": "~8.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "webignition\\DisallowedCharacterTerminatedString\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jon Cram", + "email": "webignition@gmail.com" + } + ], + "description": "A string terminated by one or more disallowed characters", + "homepage": "https://github.com/webignition/disallowed-character-terminated-string", + "keywords": [ + "string", + "terminated" + ], + "support": { + "issues": "https://github.com/webignition/disallowed-character-terminated-string/issues", + "source": "https://github.com/webignition/disallowed-character-terminated-string/tree/master" + }, + "time": "2019-12-20T15:52:44+00:00" + }, + { + "name": "webignition/robots-txt-file", + "version": "3.0", + "source": { + "type": "git", + "url": "https://github.com/webignition/robots-txt-file.git", + "reference": "51bd7b1045348d94177cf6b21415385bf0923fa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webignition/robots-txt-file/zipball/51bd7b1045348d94177cf6b21415385bf0923fa6", + "reference": "51bd7b1045348d94177cf6b21415385bf0923fa6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=7.2.0", + "webignition/disallowed-character-terminated-string": ">=2,<3" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.3", + "phpunit/phpunit": "^8.0", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "webignition\\RobotsTxt\\": "src/", + "webignition\\RobotsTxt\\Tests\\": "tests/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jon Cram", + "email": "webignition@gmail.com" + } + ], + "description": "Models a robots.txt file", + "homepage": "https://github.com/webignition/robots-txt-file", + "keywords": [ + "parser", + "robots.txt" + ], + "support": { + "issues": "https://github.com/webignition/robots-txt-file/issues", + "source": "https://github.com/webignition/robots-txt-file/tree/3.0" + }, + "time": "2019-12-20T17:50:44+00:00" + }, + { + "name": "wikimedia/less.php", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/less.php.git", + "reference": "e238ad228d74b6ffd38209c799b34e9826909266" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/less.php/zipball/e238ad228d74b6ffd38209c799b34e9826909266", + "reference": "e238ad228d74b6ffd38209c799b34e9826909266", + "shasum": "" + }, + "require": { + "php": ">=7.2.9" + }, + "require-dev": { + "phpunit/phpunit": "7.5.14" + }, + "bin": [ + "bin/lessc" + ], + "type": "library", + "autoload": { + "psr-0": { + "Less": "lib/" + }, + "classmap": [ + "lessc.inc.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Josh Schmidt", + "homepage": "https://github.com/oyejorge" + }, + { + "name": "Matt Agar", + "homepage": "https://github.com/agar" + }, + { + "name": "Martin Jantošovič", + "homepage": "https://github.com/Mordred" + } + ], + "description": "PHP port of the Javascript version of LESS http://lesscss.org (Originally maintained by Josh Schmidt)", + "keywords": [ + "css", + "less", + "less.js", + "lesscss", + "php", + "stylesheet" + ], + "support": { + "source": "https://github.com/wikimedia/less.php/tree/1.8.2" + }, + "time": "2019-11-06T18:30:11+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "contao/conflicts": 20, + "contao/manager-bundle": 20, + "hofff/contao-navigation": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/.gitignore b/.gitignore index f7c6dec..0000e3b 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,3 @@ !/phpunit.xml.dist !/psalm.xml !/.github -!/.composer-require-checker.json From cf0dcb1a7a119e9fc2cdbcd611e1e0ea2daf496d Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:35:10 +0100 Subject: [PATCH 66/75] Fix PHP 8 warnings (Close #22, #23) --- src/QueryBuilder/PageQueryBuilder.php | 9 +++++++-- src/Renderer/NavigationRenderer.php | 24 +++++++++++++++--------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index 814856f..fa0ba0a 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -37,7 +37,6 @@ final class PageQueryBuilder extends BaseQueryBuilder 'robots' => true, 'cssClass' => true, 'accesskey' => true, - 'tabindex' => true, ]; private const ERROR_PAGE_TYPES = [ @@ -265,14 +264,20 @@ private function determineFields(): void return; } + $schemaManager = $this->connection->createSchemaManager(); + $table = $schemaManager->introspectTable('tl_page'); + if ($customFields === []) { $this->fields = array_keys(self::DEFAULT_FIELDS); + if ($table->hasColumn('tabindex')) { + $this->fields[] = 'tabindex'; + } + return; } $customFields = array_flip($customFields); - $table = $this->connection->createSchemaManager()->introspectTable('tl_page'); $fields = []; foreach ($table->getColumns() as $column) { diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index a7c9e40..bf11a5f 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -61,8 +61,8 @@ public function render( array $itemIds, array $stopLimit = [PHP_INT_MAX], int $hardLevel = PHP_INT_MAX, - ?int $activeId = null, - int $currentLevel = 1 + int|null $activeId = null, + int $currentLevel = 1, ): string { $this->moduleModel = $moduleModel; $this->items = $items; @@ -174,7 +174,7 @@ private function renderTree( } elseif ( $currentLevel >= $stopLevel && ! $item['isInTrail'] && $itemId !== $activeId - && $item['tid'] !== $activeId + && ($item['tid'] ?? null) !== $activeId ) { // we are at stop level and not trail and not active, never draw submenu $item['class'] .= ' submenu leaf'; @@ -206,8 +206,10 @@ private function renderTree( unset($item); } - $renderedItems[0]['class'] .= ' first'; - $renderedItems[count($renderedItems) - 1]['class'] .= ' last'; + if ($renderedItems !== []) { + $renderedItems[0]['class'] .= ' first'; + $renderedItems[count($renderedItems) - 1]['class'] .= ' last'; + } foreach ($renderedItems as &$item) { $item['class'] = ltrim($item['class']); @@ -293,12 +295,16 @@ private function compileNavigationItem(array $page, bool $forwardResolution = tr break; case 'root': + /** + * @psalm-suppress RiskyTruthyFalsyComparison + * @psalm-suppress PossiblyUndefinedArrayOffset: + */ if ( - ! $page['dns'] + ! ($page['dns'] ?? false) || preg_replace('/^www\./', '', $page['dns']) === preg_replace( '/^www\./', '', - Environment::get('httpHost') + (string) Environment::get('httpHost'), ) ) { $page['href'] = Environment::get('base'); @@ -322,7 +328,7 @@ private function compileNavigationItem(array $page, bool $forwardResolution = tr } /** @param array $page */ - private function generatePageUrl(array $page): ?string + private function generatePageUrl(array $page): string|null { $pageModel = PageModel::findByPk($page['id']); if ($pageModel) { @@ -392,7 +398,7 @@ private function getRedirectPage(array $page): array private function dispatchEvent(Event $event): void { - if ($this->moduleModel->hofff_navigation_disableHooks) { + if (! $this->moduleModel->hofff_navigation_disableHooks) { return; } From efe6c84e2890f34129bedc901edda1d7989afa86 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:35:29 +0100 Subject: [PATCH 67/75] Use stable 5.3 instance --- .ddev/contao/composer.json | 2 +- .ddev/contao/composer.lock | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/.ddev/contao/composer.json b/.ddev/contao/composer.json index 8d937a8..9e0ae28 100644 --- a/.ddev/contao/composer.json +++ b/.ddev/contao/composer.json @@ -5,7 +5,7 @@ "type": "project", "require": { "contao/conflicts": "@dev", - "contao/manager-bundle": "^5.3.x-dev", + "contao/manager-bundle": "^5.3", "hofff/contao-navigation": "@dev" }, "conflict": { diff --git a/.ddev/contao/composer.lock b/.ddev/contao/composer.lock index c7881a1..26bc3ac 100644 --- a/.ddev/contao/composer.lock +++ b/.ddev/contao/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "717cc1c2336faee42ac370641948f248", + "content-hash": "1b118b7e232f4ce3bbd395b7d5730fbc", "packages": [ { "name": "ausi/slug-generator", @@ -1118,16 +1118,16 @@ }, { "name": "contao/core-bundle", - "version": "5.x-dev", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/contao/core-bundle.git", - "reference": "4cffcff438214c009fc78684f78756be8a3c9822" + "reference": "3870d9cd16680cdd90b5048788bb53ba643a977e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/contao/core-bundle/zipball/4cffcff438214c009fc78684f78756be8a3c9822", - "reference": "4cffcff438214c009fc78684f78756be8a3c9822", + "url": "https://api.github.com/repos/contao/core-bundle/zipball/3870d9cd16680cdd90b5048788bb53ba643a977e", + "reference": "3870d9cd16680cdd90b5048788bb53ba643a977e", "shasum": "" }, "require": { @@ -1281,7 +1281,6 @@ "symfony/phpunit-bridge": "^6.4", "symfony/web-profiler-bundle": "^6.4" }, - "default-branch": true, "type": "symfony-bundle", "extra": { "contao-manager-plugin": "Contao\\CoreBundle\\ContaoManager\\Plugin" @@ -1329,7 +1328,7 @@ "type": "other" } ], - "time": "2024-02-16T14:28:16+00:00" + "time": "2024-02-16T11:16:22+00:00" }, { "name": "contao/image", @@ -1465,7 +1464,7 @@ }, { "name": "contao/manager-bundle", - "version": "5.x-dev", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/contao/manager-bundle.git", @@ -1524,7 +1523,6 @@ "phpunit/phpunit": "^9.5", "symfony/phpunit-bridge": "^6.4" }, - "default-branch": true, "bin": [ "bin/contao-console", "bin/contao-setup" @@ -3440,7 +3438,7 @@ "dist": { "type": "path", "url": "../..", - "reference": "7e3605812828abc41705c857fb765e2b4c117ded" + "reference": "d22619e0d8579d37749d31290521e445020b19b1" }, "require": { "contao/core-bundle": "^4.13 || ^5.3", @@ -12943,7 +12941,6 @@ "minimum-stability": "dev", "stability-flags": { "contao/conflicts": 20, - "contao/manager-bundle": 20, "hofff/contao-navigation": 20 }, "prefer-stable": true, From 27d084b952702dcca398c82eaec17bef786236db Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:46:21 +0100 Subject: [PATCH 68/75] Remove phpunit from test tools and adjust ignored files --- .ddev/.gitignore | 47 +++++++++++++++++++++++++++++++++++ .ddev/backup/database.sql.gz | Bin 0 -> 14619 bytes .editorconfig | 21 ++++++++++++++++ .gitattributes | 12 +++++++++ .phpcq.lock | 2 +- 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 .ddev/.gitignore create mode 100644 .ddev/backup/database.sql.gz create mode 100644 .editorconfig create mode 100644 .gitattributes diff --git a/.ddev/.gitignore b/.ddev/.gitignore new file mode 100644 index 0000000..fcd77f8 --- /dev/null +++ b/.ddev/.gitignore @@ -0,0 +1,47 @@ +#ddev-generated: Automatically generated ddev .gitignore. + +/**/*.example +/.dbimageBuild +/.dbimageExtra +/.ddev-docker-*.yaml +/.*downloads +/.global_commands +/.homeadditions +/.importdb* +/.sshimageBuild +/.venv +/.webimageBuild +/.webimageExtra +/apache/apache-site.conf +/commands/.gitattributes +/commands/db/mysql +/commands/host/launch +/commands/web/xdebug +/commands/web/live +/config.local.y*ml +/db_snapshots +/import-db +/import.yaml +/mutagen/mutagen.yml +/mutagen/.start-synced +/nginx_full/nginx-site.conf +/postgres/postgresql.conf +/providers/acquia.yaml +/providers/lagoon.yaml +/providers/platform.yaml +/providers/upsun.yaml +/sequelpro.spf +/settings/settings.ddev.py +/traefik/config/hofff-contao-navigation.yaml +/traefik/certs/hofff-contao-navigation.crt +/traefik/certs/hofff-contao-navigation.key +/xhprof/xhprof_prepend.php +/**/README.* +!/backup +/contao/vendor +/contao/assets +/contao/public +/contao/bin +/contao/system +/contao/var +/contao/.env.local diff --git a/.ddev/backup/database.sql.gz b/.ddev/backup/database.sql.gz new file mode 100644 index 0000000000000000000000000000000000000000..67c30933424a1bbbee54cfae9e42350e4213d562 GIT binary patch literal 14619 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 qlP09a%gPFTXPHW__Q|k7Sv;=J%=5.3.9","ext-xml":"*"}},"checksum":null,"signature":"https://github.com/phpmd/phpmd/releases/download/2.15.0/phpmd.phar.asc"}}},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpcpd/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}}},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phploc/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}}},"phpcs":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpcs/phpcs-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.9.0","url":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-simplexml":"*","ext-tokenizer":"*","ext-xmlwriter":"*"}},"checksum":null,"signature":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcs.phar.asc"},"phpcbf":{"version":"3.9.0","url":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-simplexml":"*","ext-tokenizer":"*","ext-xmlwriter":"*"}},"checksum":null,"signature":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcbf.phar.asc"}}},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/composer-normalize/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.42.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.42.0/composer-normalize.phar","requirements":{"php":{"php":"~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0","ext-json":"*"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.42.0/composer-normalize.phar.asc"}}},"phpunit":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpunit/phpunit-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0"},"tool":{"phpunit":"^6.0 || ^7.0 || ^8.0 || ^9.0"}},"checksum":{"type":"sha-512","value":"c73f15658e3ba62665f09492ec91c3a6a715760bfaa88473a987538439fff442540148e086e46a6aa18ce55a3ea2fbf76caaa581384cb84a38859fcc609ae7e4"},"tools":{"phpunit":{"version":"9.6.16","url":"https://phar.phpunit.de/phpunit-9.6.16.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-xml":"*","ext-xmlwriter":"*"}},"checksum":{"type":"sha-256","value":"891d46f06284db3695498aff5dfd6a944f835e07db2981295db2c2bcf6cfd338"},"signature":"https://phar.phpunit.de/phpunit-9.6.16.phar.asc"}}}},"tools":[]} \ No newline at end of file +{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.2.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/psalm/psalm-1.2.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0 || ^5.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"5.22.1","url":"https://github.com/vimeo/psalm/releases/download/5.22.1/psalm.phar","requirements":{"php":{"php":"^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/5.22.1/psalm.phar.asc"}},"composerLock":null},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/composer-require-checker/composer-require-checker-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"d5415bddfe024c5749d894034583882aee4e5c3e1087815d9fdd81cb5e71630f631a0e35de0ff84b97fbbf738c16ece5f83bd8c00695913eb846aa6f04577dc2"},"tools":{"composer-require-checker":{"version":"4.8.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.8.0/composer-require-checker.phar","requirements":{"php":{"php":"~8.2.0 || ~8.3.0","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.8.0/composer-require-checker.phar.asc"}},"composerLock":null},"phpmd":{"api-version":"1.0.0","version":"1.0.2.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpmd/phpmd-1.0.2.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"f22280a6dec8dbdd2ec1d83b294f23237fe32c34f4a298e52038e0a7a0074d541635b2b488b1a6098a42d8418a6cd8eb804406ea82b91e362be2b5d11a0915b0"},"tools":{"phpmd":{"version":"2.15.0","url":"https://github.com/phpmd/phpmd/releases/download/2.15.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":"https://github.com/phpmd/phpmd/releases/download/2.15.0/phpmd.phar.asc"}},"composerLock":null},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpcpd/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}},"composerLock":null},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phploc/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}},"composerLock":null},"phpcs":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/phpcs/phpcs-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.9.0","url":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-simplexml":"*","ext-tokenizer":"*","ext-xmlwriter":"*"}},"checksum":null,"signature":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcs.phar.asc"},"phpcbf":{"version":"3.9.0","url":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-simplexml":"*","ext-tokenizer":"*","ext-xmlwriter":"*"}},"checksum":null,"signature":"https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/download/3.9.0/phpcbf.phar.asc"}},"composerLock":null},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/plugin/composer-normalize/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.42.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.42.0/composer-normalize.phar","requirements":{"php":{"php":"~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0","ext-json":"*"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.42.0/composer-normalize.phar.asc"}},"composerLock":null}},"tools":[]} \ No newline at end of file From 469803d97c3582e33779bd1a70b69294d5188887 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 14:47:11 +0100 Subject: [PATCH 69/75] Update build matrix --- .github/workflows/diagnostics.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/diagnostics.yml b/.github/workflows/diagnostics.yml index 23471a3..b981ac4 100644 --- a/.github/workflows/diagnostics.yml +++ b/.github/workflows/diagnostics.yml @@ -17,13 +17,13 @@ jobs: fail-fast: false matrix: include: - - php: '7.4' - phpcq_install: 'install' + - php: '8.1' + phpcq_install: 'update' phpcq_flags: '' - - php: '8.0' + - php: '8.2' phpcq_install: 'update' phpcq_flags: '' - - php: '8.1' + - php: '8.3' phpcq_install: 'update' phpcq_flags: '' From f3ff5cbd8ba24efba2b8a480a63167974c65caca Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 15:08:31 +0100 Subject: [PATCH 70/75] Fix code style issues after rebasing --- src/Migration/BackboneNavigationMigration.php | 7 +++--- src/QueryBuilder/PageQueryBuilder.php | 24 +++++++++---------- src/Renderer/NavigationRenderer.php | 10 ++++---- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Migration/BackboneNavigationMigration.php b/src/Migration/BackboneNavigationMigration.php index a5b3985..f71bc45 100644 --- a/src/Migration/BackboneNavigationMigration.php +++ b/src/Migration/BackboneNavigationMigration.php @@ -7,6 +7,7 @@ use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; +use Doctrine\DBAL\Schema\Column; use function is_int; use function sprintf; @@ -67,7 +68,7 @@ public function run(): MigrationResult $this->renameNavigationModules(); $affectedFields = $this->determineAffectedFields(); - $table = $this->connection->getSchemaManager()->listTableDetails('tl_module'); + $table = $this->connection->createSchemaManager()->introspectTable('tl_module'); foreach ($affectedFields as $oldName => $newName) { $this->renameField($table->getColumn(self::OLD_PREFIX . $oldName), $newName); } @@ -122,8 +123,8 @@ private function renameField(Column $column, string $newName): void sprintf( 'ALTER TABLE tl_module CHANGE %s %s', $column->getName(), - $platform->getColumnDeclarationSQL(self::NEW_PREFIX . $newName, $column->toArray()) - ) + $platform->getColumnDeclarationSQL(self::NEW_PREFIX . $newName, $column->toArray()), + ), ); } } diff --git a/src/QueryBuilder/PageQueryBuilder.php b/src/QueryBuilder/PageQueryBuilder.php index fa0ba0a..894803b 100644 --- a/src/QueryBuilder/PageQueryBuilder.php +++ b/src/QueryBuilder/PageQueryBuilder.php @@ -64,9 +64,9 @@ function (QueryBuilder $queryBuilder): void { $queryBuilder ->select( ...array_map( - fn (string $field) => ($field !== '*') ? $this->connection->quoteIdentifier($field) : $field, - $this->fields - ) + fn (string $field) => $field !== '*' ? $this->connection->quoteIdentifier($field) : $field, + $this->fields, + ), ) ->andWhere('type != :rootType') ->setParameter('rootType', 'root') @@ -105,8 +105,8 @@ function (QueryBuilder $queryBuilder): void { ->select( ...array_map( fn (string $field) => $this->connection->quoteIdentifier($field), - ['id', 'pid', 'protected', 'groups'] - ) + ['id', 'pid', 'protected', 'groups'], + ), ); $this @@ -139,8 +139,8 @@ function (QueryBuilder $queryBuilder): void { $queryBuilder->select( ...array_map( fn (string $field) => $this->connection->quoteIdentifier($field), - ['id', 'pid', 'protected', 'groups'] - ) + ['id', 'pid', 'protected', 'groups'], + ), ); $this @@ -169,8 +169,8 @@ function (QueryBuilder $queryBuilder): void { ->select( ...array_map( fn (string $field) => $this->connection->quoteIdentifier($field), - ['id', 'pid', 'protected', 'groups'] - ) + ['id', 'pid', 'protected', 'groups'], + ), ) ->where('id IN (:ids)'); }, @@ -191,8 +191,8 @@ function (QueryBuilder $queryBuilder): void { ->select( ...array_map( fn (string $field) => $this->connection->quoteIdentifier($field), - $this->fields - ) + $this->fields, + ), ) ->where('id IN (:rootIds)'); }, @@ -215,7 +215,7 @@ static function (QueryBuilder $queryBuilder): void { }, ); - $query->setParameter('ids', $pageIds, Connection::PARAM_STR_ARRAY); + $query->setParameter('ids', $pageIds, ArrayParameterType::STRING); return $query; } diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index bf11a5f..e2d1ff8 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -146,26 +146,27 @@ private function renderTree( $containsActive = true; if ($item['href'] === Environment::get('request')) { - $item['isActive'] = true; // nothing else (active class is set in template) - $item['isInTrail'] = false; + $item['isActive'] = true; // nothing else (active class is set in template) } else { - $item['isActive'] = false; // nothing else (active class is set in template) $item['isInTrail'] = true; } } else { // do not flatten if/else + /** @psalm-suppress RiskyTruthyFalsyComparison */ if (isset($item['tid']) && $item['tid'] === $activeId) { if ($item['href'] === Environment::get('request')) { - $item['isActive'] = true; // nothing else (active class is set in template) + $item['isActive'] = true; // nothing else (active class is set in template) } else { $item['isInTrail'] = true; } } } + /** @psalm-suppress RiskyTruthyFalsyComparison */ if ($item['isInTrail']) { $item['class'] .= ' trail'; } + /** @psalm-suppress RiskyTruthyFalsyComparison */ if (! isset($this->items->subItems[$itemId])) { $item['class'] .= ' leaf'; } elseif ($currentLevel >= $hardLevel) { @@ -196,6 +197,7 @@ private function renderTree( if ($containsActive) { foreach ($renderedItems as &$item) { + /** @psalm-suppress RiskyTruthyFalsyComparison */ if ($item['isActive']) { continue; } From b5f8bb695347ef58d744a3157d216f352563172b Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 15:11:00 +0100 Subject: [PATCH 71/75] Add readme (Close #15) --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..6306296 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Advanced navigation module for Contao CMS + +## Requirements + + - Contao `4.13 || ^5.3` + - PHP `8.1` From a81bcd053f8385c82886b26e52f730a59c715e71 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 15:17:26 +0100 Subject: [PATCH 72/75] Bump github actions tools --- .github/workflows/diagnostics.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/diagnostics.yml b/.github/workflows/diagnostics.yml index b981ac4..27699ef 100644 --- a/.github/workflows/diagnostics.yml +++ b/.github/workflows/diagnostics.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Pull source - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup PHP with PECL extension uses: shivammathur/setup-php@v2 @@ -38,7 +38,7 @@ jobs: coverage: xdebug2 - name: Cache composer cache directory - uses: actions/cache@v1 + uses: actions/cache@v4 env: cache-name: composer-cache-dir-${{ matrix.php }} with: @@ -49,7 +49,7 @@ jobs: run: composer install - name: Cache vendor directory of phpcq tool runner - uses: actions/cache@v1 + uses: actions/cache@v4 env: cache-name: vendor-${{ matrix.php }} with: @@ -68,7 +68,7 @@ jobs: run: $GITHUB_WORKSPACE/vendor/bin/phpcq run -o github-action -o default ${{ matrix.phpcq_flags }} -v - name: Upload build directory to artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 if: ${{ success() }} || ${{ failure() }} with: name: phpcq-builds-php-${{ matrix.php }} From 35cbdf3e77924c31d4ba3a91e2eb1d5eab79fdd5 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 15:19:13 +0100 Subject: [PATCH 73/75] Drop php 8.3 build --- .github/workflows/diagnostics.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/diagnostics.yml b/.github/workflows/diagnostics.yml index 27699ef..733cff3 100644 --- a/.github/workflows/diagnostics.yml +++ b/.github/workflows/diagnostics.yml @@ -23,9 +23,6 @@ jobs: - php: '8.2' phpcq_install: 'update' phpcq_flags: '' - - php: '8.3' - phpcq_install: 'update' - phpcq_flags: '' steps: - name: Pull source From 9ef0cd385e4a2a79b27812c660411b5243e31011 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 15:54:31 +0100 Subject: [PATCH 74/75] Fix hook disabling --- src/Renderer/NavigationRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Renderer/NavigationRenderer.php b/src/Renderer/NavigationRenderer.php index e2d1ff8..4463608 100644 --- a/src/Renderer/NavigationRenderer.php +++ b/src/Renderer/NavigationRenderer.php @@ -400,7 +400,7 @@ private function getRedirectPage(array $page): array private function dispatchEvent(Event $event): void { - if (! $this->moduleModel->hofff_navigation_disableHooks) { + if ($this->moduleModel->hofff_navigation_disableHooks) { return; } From f1df87e9c4f5df456d2f3dc99edc03b901b3a638 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 19 Feb 2024 15:56:53 +0100 Subject: [PATCH 75/75] Prepare release 2.0.0 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 07f776f..126ec27 100644 --- a/composer.json +++ b/composer.json @@ -68,8 +68,8 @@ }, "extra": { "branch-alias": { - "dev-develop": "2.0.x-dev", - "dev-master": "1.9.x-dev" + "dev-develop": "2.1.x-dev", + "dev-master": "2.0.x-dev" }, "contao-manager-plugin": "Hofff\\Contao\\Navigation\\ContaoManager\\Plugin" }