From 89bf6bcfcdd239023852c4f5b52d87d754688e43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 27 Aug 2018 16:25:28 +0200 Subject: [PATCH 1/3] Migrating towards a framework agnostic library --- .gitignore | 3 + composer.json | 27 ++--- discovery.json | 3 + phpcs.xml.dist | 21 ++++ phpstan.neon | 5 + src/Mouf/Html/Widgets/Menu/Menu.php | 21 ++-- src/Mouf/Html/Widgets/Menu/MenuInterface.php | 6 +- src/Mouf/Html/Widgets/Menu/MenuItem.php | 99 ++++++++++--------- .../Html/Widgets/Menu/MenuItemInterface.php | 23 +++-- .../Html/Widgets/Menu/MenuItemStyleIcon.php | 27 +++-- src/Mouf/Html/Widgets/Menu/MenuItemTarget.php | 5 +- .../Menu/MenuRendererServiceProvider.php | 20 ++++ src/install.php | 24 ----- 13 files changed, 158 insertions(+), 126 deletions(-) create mode 100644 .gitignore create mode 100644 discovery.json create mode 100644 phpcs.xml.dist create mode 100644 phpstan.neon create mode 100644 src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php delete mode 100644 src/install.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e59110 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/vendor +/mouf +/composer.lock \ No newline at end of file diff --git a/composer.json b/composer.json index 4f6a333..99281c7 100644 --- a/composer.json +++ b/composer.json @@ -19,21 +19,26 @@ ], "require" : { "mouf/utils.common.conditioninterface" : "2.*", - "php" : ">=5.3.0", - "mouf/html.renderer" : "~1.0" + "php" : ">=7.1", + "mouf/html.renderer" : "^2", + "thecodingmachine/funky": "^1" + }, + "require-dev": { + "phpstan/phpstan": "^0.10.3", + "thecodingmachine/phpstan-strict-rules": "^0.10.3", + "squizlabs/php_codesniffer": "^3.3.1", + "mouf/utils.i18n.fine.translation-interface": "^4" + }, + "scripts": { + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "phpstan": "phpstan analyse src -c phpstan.neon --level=5 --no-progress -vvv" }, "autoload" : { "psr-0" : { "Mouf" : "src/" } }, - "extra" : { - "mouf" : { - "install" : [{ - "file" : "src/install.php", - "type" : "file" - } - ] - } - } + "minimum-stability": "dev", + "prefer-stable": true } \ No newline at end of file diff --git a/discovery.json b/discovery.json new file mode 100644 index 0000000..891b9d4 --- /dev/null +++ b/discovery.json @@ -0,0 +1,3 @@ +{ + "Interop\\Container\\ServiceProviderInterface": "Mouf\\Html\\Widgets\\Menu\\MenuRendererServiceProvider" +} diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..480486b --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,21 @@ + + + Expressive Skeleton coding standard + + + + + + + + + + src + + + + + + + + \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..1205a7f --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,5 @@ +parameters: + ignoreErrors: + - "#you should not use the \\$_REQUEST superglobal#" +includes: + - vendor/thecodingmachine/phpstan-strict-rules/phpstan-strict-rules.neon \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/Menu.php b/src/Mouf/Html/Widgets/Menu/Menu.php index 709ae73..e470c50 100644 --- a/src/Mouf/Html/Widgets/Menu/Menu.php +++ b/src/Mouf/Html/Widgets/Menu/Menu.php @@ -43,7 +43,7 @@ class Menu implements MenuInterface, HtmlElementInterface { * * @param array $children */ - public function __construct($children=null) { + public function __construct(array $children = []) { $this->children = $children; } @@ -51,15 +51,15 @@ public function __construct($children=null) { * Returns a list of children elements for the menu (if there are some). * @return array */ - public function getChildren() { - if ($this->sorted == false && $this->children) { + public function getChildren(): array { + if ($this->sorted === false && $this->children !== []) { // First, let's make 2 arrays: the array of children with a priority, and the array without. $childrenWithPriorities = array(); $childrenWithoutPriorities = array(); foreach ($this->children as $child) { /* @var $child MenuItemInterface */ $priority = $child->getPriority(); - if ($priority === null || $priority === "") { + if ($priority === null) { $childrenWithoutPriorities[] = $child; } else { $childrenWithPriorities[] = $child; @@ -73,14 +73,14 @@ public function getChildren() { return $this->children; } - public function compareMenuItems(MenuItem $item1, MenuItem $item2) { + public function compareMenuItems(MenuItem $item1, MenuItem $item2): int { $priority1 = $item1->getPriority(); $priority2 = $item2->getPriority(); /*if ($priority1 === null && $priority2 === null) { // If no priority is set, let's keep the default ordering (which happens is usort by always returning positive numbers...) return 1; }*/ - return $priority1 - $priority2; + return $priority1 <=> $priority2; } /** @@ -89,7 +89,7 @@ public function compareMenuItems(MenuItem $item1, MenuItem $item2) { * @Property * @param array $children */ - public function setChildren(array $children) { + public function setChildren(array $children): void { $this->sorted = false; $this->children = $children; } @@ -99,7 +99,7 @@ public function setChildren(array $children) { * * @param MenuItem $child */ - public function addChild(MenuItem $child) { + public function addChild(MenuItem $child): void { $this->sorted = false; $this->children[] = $child; } @@ -110,7 +110,7 @@ public function addChild(MenuItem $child) { * @Property * @param ConditionInterface $displayCondition */ - public function setDisplayCondition(ConditionInterface $displayCondition) { + public function setDisplayCondition(ConditionInterface $displayCondition): void { $this->displayCondition = $displayCondition; } @@ -120,7 +120,7 @@ public function setDisplayCondition(ConditionInterface $displayCondition) { * * @return bool */ - public function isHidden() { + public function isHidden(): bool { if ($this->displayCondition == null) { return false; } @@ -128,4 +128,3 @@ public function isHidden() { } } -?> \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuInterface.php b/src/Mouf/Html/Widgets/Menu/MenuInterface.php index 1dbe5d8..15d1547 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuInterface.php @@ -21,14 +21,12 @@ interface MenuInterface { * Returns a list of children elements for the menu (if there are some). * @return array */ - function getChildren(); + function getChildren(): array; /** * If this function returns true, the menu item should not be displayed. * * @return bool */ - function isHidden(); + function isHidden(): bool; } - -?> \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuItem.php b/src/Mouf/Html/Widgets/Menu/MenuItem.php index b1308bf..dd754fc 100644 --- a/src/Mouf/Html/Widgets/Menu/MenuItem.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItem.php @@ -10,6 +10,7 @@ use Mouf\Utils\I18n\Fine\Translate\LanguageTranslationInterface; use Mouf\Html\HtmlElement\HtmlElementInterface; use Mouf\Html\Renderer\Renderable; +use Mouf\Utils\I18n\Fine\TranslatorInterface; /** * This class represent a menu item. @@ -71,7 +72,7 @@ class MenuItem implements MenuItemInterface, HtmlElementInterface { /** * The translation service to use (if any) to translate the label text. * - * @var LanguageTranslationInterface + * @var TranslatorInterface|null */ private $translationService; @@ -108,8 +109,12 @@ class MenuItem implements MenuItemInterface, HtmlElementInterface { * @var array */ private $additionalStyles = array(); - - /** + /** + * @var string + */ + private $rootUrl; + + /** * Constructor. * * @Important @@ -117,17 +122,18 @@ class MenuItem implements MenuItemInterface, HtmlElementInterface { * @param string $url The link for the menu (relative to the root url), unless it starts with / or http:// or https:// or # or ?. * @param array $children */ - public function __construct($label=null, $url=null, $children=array()) { + public function __construct(string $label=null, string $url=null, array $children=[], string $rootUrl = '/') { $this->label = $label; $this->url = $url; $this->children = $children; - } + $this->rootUrl = $rootUrl; + } /** * Returns the label for the menu item. * @return string */ - public function getLabel() { + public function getLabel(): string { if ($this->translationService) { return $this->translationService->getTranslation($this->label); } else { @@ -140,7 +146,7 @@ public function getLabel() { * * @param string $label */ - public function setLabel($label) { + public function setLabel(string $label): void { $this->label = $label; } @@ -148,16 +154,16 @@ public function setLabel($label) { * Returns the URL for this menu (or null if this menu is not a link). * @return string */ - public function getUrl() { + public function getUrl(): string { return $this->url; } /** * The link for the menu (relative to the root url), unless it starts with / or http:// or https://. * - * @param string $url + * @param string|null $url */ - public function setUrl($url) { + public function setUrl(?string $url): self { $this->url = $url; return $this; } @@ -168,15 +174,15 @@ public function setUrl($url) { * @see MenuItemInterface::getChildren() * @return array */ - public function getChildren() { - if ($this->sorted == false && $this->children) { + public function getChildren(): array { + if ($this->sorted === false && $this->children !== []) { // First, let's make 2 arrays: the array of children with a priority, and the array without. $childrenWithPriorities = array(); $childrenWithoutPriorities = array(); foreach ($this->children as $child) { /* @var $child MenuItemInterface */ $priority = $child->getPriority(); - if ($priority === null || $priority === "") { + if ($priority === null) { $childrenWithoutPriorities[] = $child; } else { $childrenWithPriorities[] = $child; @@ -192,14 +198,14 @@ public function getChildren() { private $sorted = false; - public function compareMenuItems(MenuItem $item1, MenuItem $item2) { + public function compareMenuItems(MenuItem $item1, MenuItem $item2): int { $priority1 = $item1->getPriority(); $priority2 = $item2->getPriority(); /*if ($priority1 === null && $priority2 === null) { // If no priority is set, let's keep the default ordering (which happens is usort by always returning positive numbers...) return 1; }*/ - return $priority1 - $priority2; + return $priority1 <=> $priority2; } /** @@ -207,7 +213,7 @@ public function compareMenuItems(MenuItem $item1, MenuItem $item2) { * * @param array $children */ - public function setChildren(array $children) { + public function setChildren(array $children): self { $this->sorted = false; $this->children = $children; return $this; @@ -218,7 +224,7 @@ public function setChildren(array $children) { * * @param MenuItemInterface $menuItem */ - public function addMenuItem(MenuItemInterface $menuItem) { + public function addMenuItem(MenuItemInterface $menuItem): void { $this->sorted = false; $this->children[] = $menuItem; } @@ -227,7 +233,7 @@ public function addMenuItem(MenuItemInterface $menuItem) { * Returns true if the menu is in active state (if we are on the page for this menu). * @return bool */ - public function isActive() { + public function isActive(): bool { if ($this->isActive) { return true; } @@ -271,7 +277,7 @@ public function isActive() { * * @param bool $isActive */ - public function setIsActive($isActive) { + public function setIsActive(bool $isActive): self { $this->isActive = $isActive; return $this; } @@ -280,16 +286,16 @@ public function setIsActive($isActive) { * Enables the menu item (activates it). * */ - public function enable() { + public function enable(): self { $this->isActive = true; return $this; } /** * Returns true if the menu should be in extended state (if we can see the children directly). - * @return bool + * @return bool|null */ - public function isExtended() { + public function isExtended(): ?bool { return $this->isExtended; } @@ -299,7 +305,7 @@ public function isExtended() { * * @param bool $isExtended */ - public function setIsExtended($isExtended = true) { + public function setIsExtended(bool $isExtended = true): self { $this->isExtended = $isExtended; return $this; } @@ -308,7 +314,7 @@ public function setIsExtended($isExtended = true) { * Returns an optional CSS class to apply to the menu item. * @return string */ - public function getCssClass() { + public function getCssClass(): string { return $this->cssClass; } @@ -318,7 +324,7 @@ public function getCssClass() { * * @param string $cssClass */ - public function setCssClass($cssClass) { + public function setCssClass(string $cssClass): self { $this->cssClass = $cssClass; return $this; } @@ -326,9 +332,9 @@ public function setCssClass($cssClass) { /** * Level of priority used to order the menu items. * - * @param float $priority + * @param float|null $priority */ - public function setPriority($priority) { + public function setPriority(?float $priority): self { $this->priority = $priority; return $this; } @@ -337,7 +343,7 @@ public function setPriority($priority) { * Returns the level of priority. It is used to order the menu items. * @return float */ - public function getPriority() { + public function getPriority(): ?float { return $this->priority; } @@ -345,15 +351,15 @@ public function getPriority() { * Returns the list of additionnal style * @return array */ - public function getAdditionalStyles() { + public function getAdditionalStyles(): array { return $this->additionalStyles; } /** * Returns the one of additionnal style - * @return array + * @return MenuItemStyleInterface */ - public function getAdditionalStyleByType($type) { + public function getAdditionalStyleByType(string $type): MenuItemStyleInterface { $return = null; if($this->additionalStyles) { foreach ($this->additionalStyles as $additionalStyle) { @@ -361,7 +367,7 @@ public function getAdditionalStyleByType($type) { if($return === null) $return = $additionalStyle; else - throw new \Exception("MenuItem: There are many instance of $type, please use getAdditionalStylesByType function to get all instance"); + throw new \LogicException("MenuItem: There are many instance of $type, please use getAdditionalStylesByType function to get all instance"); } } } @@ -372,7 +378,7 @@ public function getAdditionalStyleByType($type) { * Returns the list of additionnal style * @return array */ - public function getAdditionalStylesByType($type) { + public function getAdditionalStylesByType(string $type): array { $return = array(); if($this->additionalStyles) { foreach ($this->additionalStyles as $additionalStyle) { @@ -389,7 +395,7 @@ public function getAdditionalStylesByType($type) { * * @param array $menuItemStyleInterface */ - public function setAdditionalStyles($menuItemStyleInterface) { + public function setAdditionalStyles(array $menuItemStyleInterface): self { $this->additionalStyles = $menuItemStyleInterface; return $this; } @@ -401,7 +407,7 @@ public function setAdditionalStyles($menuItemStyleInterface) { * * @return bool */ - public function isSeparator() { + public function isSeparator(): bool { return false; } @@ -410,8 +416,8 @@ public function isSeparator() { * * @return bool */ - public function isHidden() { - if ($this->displayCondition == null) { + public function isHidden(): bool { + if ($this->displayCondition === null) { return false; } return !$this->displayCondition->isOk(); @@ -421,9 +427,9 @@ public function isHidden() { * If any translation service is set, it will be used to translate the label. * Otherwise, the label is displayed "as-is". * - * @param LanguageTranslationInterface $translationService + * @param TranslatorInterface $translationService */ - public function setTranslationService(LanguageTranslationInterface $translationService) { + public function setTranslationService(TranslatorInterface $translationService): self { $this->translationService = $translationService; return $this; } @@ -434,7 +440,7 @@ public function setTranslationService(LanguageTranslationInterface $translationS * * @param ConditionInterface $displayCondition */ - public function setDisplayCondition(ConditionInterface $displayCondition) { + public function setDisplayCondition(ConditionInterface $displayCondition): self { $this->displayCondition = $displayCondition; return $this; } @@ -446,7 +452,7 @@ public function setDisplayCondition(ConditionInterface $displayCondition) { * * @param array $propagatedUrlParameters */ - public function setPropagatedUrlParameters($propagatedUrlParameters) { + public function setPropagatedUrlParameters(array $propagatedUrlParameters): self { $this->propagatedUrlParameters = $propagatedUrlParameters; return $this; } @@ -456,7 +462,7 @@ public function setPropagatedUrlParameters($propagatedUrlParameters) { * Returns the absolute URL, with parameters if required. * @return string */ - public function getLink() { + public function getLink(): ?string { if ($this->url === null) { return null; } @@ -467,7 +473,7 @@ public function getLink() { if (is_array($this->propagatedUrlParameters)) { foreach ($this->propagatedUrlParameters as $parameter) { if (isset($_REQUEST[$parameter])) { - $params[$parameter] = \get($parameter); + $params[$parameter] = $_REQUEST($parameter); } } } @@ -488,7 +494,7 @@ public function getLink() { return $link; } - private function getLinkWithoutParams() { + private function getLinkWithoutParams(): string { if (strpos($this->url, "/") === 0 || strpos($this->url, "javascript:") === 0 || strpos($this->url, "http://") === 0 @@ -498,7 +504,7 @@ private function getLinkWithoutParams() { return $this->url; } - return ROOT_URL.$this->url; + return $this->rootUrl.$this->url; } /** @@ -506,9 +512,8 @@ private function getLinkWithoutParams() { * * @param bool $activateBasedOnUrl */ - public function setActivateBasedOnUrl($activateBasedOnUrl = true) { + public function setActivateBasedOnUrl(bool $activateBasedOnUrl = true): self { $this->activateBasedOnUrl = $activateBasedOnUrl; return $this; } } -?> \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php b/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php index 0254843..11e0275 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php @@ -21,37 +21,37 @@ interface MenuItemInterface /*extends MenuInterface*/ { * Returns the label for the menu item. * @return string */ - function getLabel(); + public function getLabel(): string; /** * Returns the URL for this menu (or null if this menu is not a link). * @return string */ - function getUrl(); + public function getUrl(): ?string; /** * Returns a list of children elements for the menu (if there are some). * @return array */ - function getChildren(); + public function getChildren(): array; /** * Returns true if the menu is in active state (if we are on the page for this menu). * @return bool */ - function isActive(); + public function isActive(): bool; /** * Returns true if the menu should be in extended state (if we can see the children directly). * @return bool */ - function isExtended(); + public function isExtended(): ?bool; /** * Returns an optional CSS class to apply to the menu item. * @return string */ - function getCssClass(); + public function getCssClass(): string; /** * Returns true if this menu item is a separator. @@ -60,26 +60,25 @@ function getCssClass(); * * @return bool */ - function isSeparator(); + public function isSeparator(): bool; /** * If this function returns true, the menu item should not be displayed. * * @return bool */ - function isHidden(); + public function isHidden(): bool; /** * Returns the level of priority. It is used to order the menu items. - * @return float + * @return float|null */ - function getPriority(); + public function getPriority(): ?float; /** * Returns the list of additionnal style * @return array */ - function getAdditionalStyles(); + public function getAdditionalStyles(): array; } -?> \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php b/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php index 96678c4..88844f8 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php @@ -22,29 +22,28 @@ class MenuItemStyleIcon implements MenuItemStyleInterface { * @var string */ private $url; - + /** + * @var string + */ + private $rootUrl; + + public function __construct(string $url, string $rootUrl = '/') + { + $this->url = $url; + $this->rootUrl = $rootUrl; + } + /** * Returns the URL for this menu (or null if this menu is not a link). * @return string */ - public function getUrl() { + public function getUrl(): string { if (strpos($this->url, "/") === 0 || strpos($this->url, "javascript:") === 0 || strpos($this->url, "http://") === 0 || strpos($this->url, "https://") === 0) { return $this->url; } - return ROOT_URL.$this->url; + return $this->rootUrl.$this->url; } - - /** - * The link for the menu (relative to the root url), unless it starts with / or http:// or https://. - * - * @Property - * @param string $url - */ - public function setUrl($url) { - $this->url = $url; - } } -?> \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php b/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php index 09e57a1..fa9150c 100644 --- a/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php @@ -23,7 +23,7 @@ class MenuItemTarget implements MenuItemStyleInterface { */ public $target; - public function __construct($target = "_blank") { + public function __construct(string $target = "_blank") { $this->target = $target; } @@ -31,8 +31,7 @@ public function __construct($target = "_blank") { * Returns the target html attribute or null if not set. * @return string */ - public function getTarget() { + public function getTarget(): string { return $this->target; } } -?> \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php b/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php new file mode 100644 index 0000000..c31a66f --- /dev/null +++ b/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php @@ -0,0 +1,20 @@ +rewriteMouf(); - -// Finally, let's continue the install -InstallUtils::continueInstall(isset($_REQUEST['selfedit']) && $_REQUEST['selfedit'] == 'true'); -?> \ No newline at end of file From 54a89de6775b3b613087b9bcf355044b04221d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 27 Aug 2018 16:26:41 +0200 Subject: [PATCH 2/3] Adding Travis --- .travis.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e262f81 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: php +matrix: + include: + - php: 7.2 + env: PREFER_LOWEST="" + - php: 7.1 + env: PREFER_LOWEST="" +# - php: 7.1 +# env: PREFER_LOWEST="--prefer-lowest" + +before_script: +- composer update $PREFER_LOWEST --no-interaction +- mkdir -p build/logs +script: +- composer cs-check +- composer phpstan From e108fb7b821b37c9da47f8db32d8e8c6390eb399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 27 Aug 2018 16:28:40 +0200 Subject: [PATCH 3/3] PSR-2 --- src/Mouf/Html/Widgets/Menu/Menu.php | 225 ++-- src/Mouf/Html/Widgets/Menu/MenuInterface.php | 33 +- src/Mouf/Html/Widgets/Menu/MenuItem.php | 988 +++++++++--------- .../Html/Widgets/Menu/MenuItemInterface.php | 116 +- .../Html/Widgets/Menu/MenuItemStyleIcon.php | 48 +- .../Widgets/Menu/MenuItemStyleInterface.php | 11 +- src/Mouf/Html/Widgets/Menu/MenuItemTarget.php | 39 +- .../Menu/MenuRendererServiceProvider.php | 1 - .../Html/Widgets/Menu/MenuStyleInterface.php | 11 +- 9 files changed, 757 insertions(+), 715 deletions(-) diff --git a/src/Mouf/Html/Widgets/Menu/Menu.php b/src/Mouf/Html/Widgets/Menu/Menu.php index e470c50..b7a88ac 100644 --- a/src/Mouf/Html/Widgets/Menu/Menu.php +++ b/src/Mouf/Html/Widgets/Menu/Menu.php @@ -1,7 +1,7 @@ - */ - private $children; - - /** - * This condition must be matched to display the menu. - * Otherwise, the menu is not displayed. - * The displayCondition is optional. If no condition is set, the menu will always be displayed. - * - * @var ConditionInterface - */ - private $displayCondition; - - private $sorted = false; - - /** - * Constructor. - * - * @param array $children - */ - public function __construct(array $children = []) { - $this->children = $children; - } +class Menu implements MenuInterface, HtmlElementInterface +{ + use Renderable; + + /** + * The children menu item of this menu (if any). + * + * @var array + */ + private $children; + + /** + * This condition must be matched to display the menu. + * Otherwise, the menu is not displayed. + * The displayCondition is optional. If no condition is set, the menu will always be displayed. + * + * @var ConditionInterface + */ + private $displayCondition; + + private $sorted = false; + + /** + * Constructor. + * + * @param array $children + */ + public function __construct(array $children = []) + { + $this->children = $children; + } - /** - * Returns a list of children elements for the menu (if there are some). - * @return array - */ - public function getChildren(): array { - if ($this->sorted === false && $this->children !== []) { - // First, let's make 2 arrays: the array of children with a priority, and the array without. - $childrenWithPriorities = array(); - $childrenWithoutPriorities = array(); - foreach ($this->children as $child) { - /* @var $child MenuItemInterface */ - $priority = $child->getPriority(); - if ($priority === null) { - $childrenWithoutPriorities[] = $child; - } else { - $childrenWithPriorities[] = $child; - } - } - - usort($childrenWithPriorities, array($this, "compareMenuItems")); - $this->children = array_merge($childrenWithPriorities, $childrenWithoutPriorities); - $this->sorted = true; - } - return $this->children; - } + /** + * Returns a list of children elements for the menu (if there are some). + * @return array + */ + public function getChildren(): array + { + if ($this->sorted === false && $this->children !== []) { + // First, let's make 2 arrays: the array of children with a priority, and the array without. + $childrenWithPriorities = array(); + $childrenWithoutPriorities = array(); + foreach ($this->children as $child) { + /* @var $child MenuItemInterface */ + $priority = $child->getPriority(); + if ($priority === null) { + $childrenWithoutPriorities[] = $child; + } else { + $childrenWithPriorities[] = $child; + } + } + + usort($childrenWithPriorities, array($this, "compareMenuItems")); + $this->children = array_merge($childrenWithPriorities, $childrenWithoutPriorities); + $this->sorted = true; + } + return $this->children; + } - public function compareMenuItems(MenuItem $item1, MenuItem $item2): int { - $priority1 = $item1->getPriority(); - $priority2 = $item2->getPriority(); - /*if ($priority1 === null && $priority2 === null) { - // If no priority is set, let's keep the default ordering (which happens is usort by always returning positive numbers...) - return 1; - }*/ - return $priority1 <=> $priority2; - } - - /** - * The children menu item of this menu (if any). - * - * @Property - * @param array $children - */ - public function setChildren(array $children): void { - $this->sorted = false; - $this->children = $children; - } - - /** - * Adds one child menu item to this menu item. - * - * @param MenuItem $child - */ - public function addChild(MenuItem $child): void { - $this->sorted = false; - $this->children[] = $child; - } - - /** - * If set, this display condition is tested. If it returns false, the menu will be hidden. - * - * @Property - * @param ConditionInterface $displayCondition - */ - public function setDisplayCondition(ConditionInterface $displayCondition): void { - $this->displayCondition = $displayCondition; - } - + public function compareMenuItems(MenuItem $item1, MenuItem $item2): int + { + $priority1 = $item1->getPriority(); + $priority2 = $item2->getPriority(); + /*if ($priority1 === null && $priority2 === null) { + // If no priority is set, let's keep the default ordering (which happens is usort by always returning positive numbers...) + return 1; + }*/ + return $priority1 <=> $priority2; + } + + /** + * The children menu item of this menu (if any). + * + * @Property + * @param array $children + */ + public function setChildren(array $children): void + { + $this->sorted = false; + $this->children = $children; + } + + /** + * Adds one child menu item to this menu item. + * + * @param MenuItem $child + */ + public function addChild(MenuItem $child): void + { + $this->sorted = false; + $this->children[] = $child; + } + + /** + * If set, this display condition is tested. If it returns false, the menu will be hidden. + * + * @Property + * @param ConditionInterface $displayCondition + */ + public function setDisplayCondition(ConditionInterface $displayCondition): void + { + $this->displayCondition = $displayCondition; + } + - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ - public function isHidden(): bool { - if ($this->displayCondition == null) { - return false; - } - return !$this->displayCondition->isOk(); - } - + /** + * If this function returns true, the menu item should not be displayed. + * + * @return bool + */ + public function isHidden(): bool + { + if ($this->displayCondition == null) { + return false; + } + return !$this->displayCondition->isOk(); + } } diff --git a/src/Mouf/Html/Widgets/Menu/MenuInterface.php b/src/Mouf/Html/Widgets/Menu/MenuInterface.php index 15d1547..7eb9962 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuInterface.php @@ -1,7 +1,7 @@ - */ - function getChildren(): array; - - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ - function isHidden(): bool; +interface MenuInterface +{ + + /** + * Returns a list of children elements for the menu (if there are some). + * @return array + */ + public function getChildren(): array; + + /** + * If this function returns true, the menu item should not be displayed. + * + * @return bool + */ + public function isHidden(): bool; } diff --git a/src/Mouf/Html/Widgets/Menu/MenuItem.php b/src/Mouf/Html/Widgets/Menu/MenuItem.php index dd754fc..f5c389c 100644 --- a/src/Mouf/Html/Widgets/Menu/MenuItem.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItem.php @@ -1,7 +1,7 @@ - */ - private $children; - - /** - * The CSS class for the menu, if any. - * Use of this property depends on the menu implementation. - * - * @var string - */ - private $cssClass; - - /** - * A list of parameters that are propagated by the link. - * For instance, if the parameter "mode" is set to 42 on the page (because the URL is http://mywebsite/myurl?mode=42), - * then if you choose to propagate the "mode" parameter, the menu link will have "mode=42" as a parameter. - * - * @var array - */ - private $propagatedUrlParameters; - - /** - * This condition must be matched to display the menu. - * Otherwise, the menu is not displayed. - * The displayCondition is optional. If no condition is set, the menu will always be displayed. - * - * @var ConditionInterface - */ - private $displayCondition; - - /** - * The translation service to use (if any) to translate the label text. - * - * @var TranslatorInterface|null - */ - private $translationService; - - /** - * Whether the menu is in an active state or not. - * - * @var bool - */ - private $isActive; - - /** - * Whether the menu is extended or not. - * This should not have an effect if the menu has no child. - * - * @var bool - */ - private $isExtended; +class MenuItem implements MenuItemInterface, HtmlElementInterface +{ + use Renderable; + + /** + * The text for the menu item + * + * @var string + */ + private $label; + + /** + * The link for the menu (relative to the root url), unless it starts with / or http:// or https:// or # or ?. + * + * @var string + */ + private $url; + + /** + * The children menu item of this menu (if any). + * + * @var array + */ + private $children; + + /** + * The CSS class for the menu, if any. + * Use of this property depends on the menu implementation. + * + * @var string + */ + private $cssClass; + + /** + * A list of parameters that are propagated by the link. + * For instance, if the parameter "mode" is set to 42 on the page (because the URL is http://mywebsite/myurl?mode=42), + * then if you choose to propagate the "mode" parameter, the menu link will have "mode=42" as a parameter. + * + * @var array + */ + private $propagatedUrlParameters; + + /** + * This condition must be matched to display the menu. + * Otherwise, the menu is not displayed. + * The displayCondition is optional. If no condition is set, the menu will always be displayed. + * + * @var ConditionInterface + */ + private $displayCondition; + + /** + * The translation service to use (if any) to translate the label text. + * + * @var TranslatorInterface|null + */ + private $translationService; + + /** + * Whether the menu is in an active state or not. + * + * @var bool + */ + private $isActive; + + /** + * Whether the menu is extended or not. + * This should not have an effect if the menu has no child. + * + * @var bool + */ + private $isExtended; - /** - * Level of priority used to order the menu items. - * - * @var float - */ - private $priority; - - /** - * If the URL of the current page matches the URL of the link, the link will be considered as "active". - * - * @var bool - */ - private $activateBasedOnUrl = true; - - /** - * @var array - */ - private $additionalStyles = array(); + /** + * Level of priority used to order the menu items. + * + * @var float + */ + private $priority; + + /** + * If the URL of the current page matches the URL of the link, the link will be considered as "active". + * + * @var bool + */ + private $activateBasedOnUrl = true; + + /** + * @var array + */ + private $additionalStyles = array(); /** * @var string */ private $rootUrl; /** - * Constructor. - * - * @Important - * @param string $label The text for the menu item - * @param string $url The link for the menu (relative to the root url), unless it starts with / or http:// or https:// or # or ?. - * @param array $children - */ - public function __construct(string $label=null, string $url=null, array $children=[], string $rootUrl = '/') { - $this->label = $label; - $this->url = $url; - $this->children = $children; + * Constructor. + * + * @Important + * @param string $label The text for the menu item + * @param string $url The link for the menu (relative to the root url), unless it starts with / or http:// or https:// or # or ?. + * @param array $children + */ + public function __construct(string $label = null, string $url = null, array $children = [], string $rootUrl = '/') + { + $this->label = $label; + $this->url = $url; + $this->children = $children; $this->rootUrl = $rootUrl; } - /** - * Returns the label for the menu item. - * @return string - */ - public function getLabel(): string { - if ($this->translationService) { - return $this->translationService->getTranslation($this->label); - } else { - return $this->label; - } - } - - /** - * The label for this menu item. - * - * @param string $label - */ - public function setLabel(string $label): void { - $this->label = $label; - } - - /** - * Returns the URL for this menu (or null if this menu is not a link). - * @return string - */ - public function getUrl(): string { - return $this->url; - } - - /** - * The link for the menu (relative to the root url), unless it starts with / or http:// or https://. - * - * @param string|null $url - */ - public function setUrl(?string $url): self { - $this->url = $url; - return $this; - } - - /** - * Returns a list of children elements for the menu (if there are some). - * - * @see MenuItemInterface::getChildren() - * @return array - */ - public function getChildren(): array { - if ($this->sorted === false && $this->children !== []) { - // First, let's make 2 arrays: the array of children with a priority, and the array without. - $childrenWithPriorities = array(); - $childrenWithoutPriorities = array(); - foreach ($this->children as $child) { - /* @var $child MenuItemInterface */ - $priority = $child->getPriority(); - if ($priority === null) { - $childrenWithoutPriorities[] = $child; - } else { - $childrenWithPriorities[] = $child; - } - } - - usort($childrenWithPriorities, array($this, "compareMenuItems")); - $this->children = array_merge($childrenWithPriorities, $childrenWithoutPriorities); - $this->sorted = true; - } - return $this->children; - } - - private $sorted = false; - - public function compareMenuItems(MenuItem $item1, MenuItem $item2): int { - $priority1 = $item1->getPriority(); - $priority2 = $item2->getPriority(); - /*if ($priority1 === null && $priority2 === null) { - // If no priority is set, let's keep the default ordering (which happens is usort by always returning positive numbers...) - return 1; - }*/ - return $priority1 <=> $priority2; - } - - /** - * The children menu item of this menu (if any). - * - * @param array $children - */ - public function setChildren(array $children): self { - $this->sorted = false; - $this->children = $children; - return $this; - } + /** + * Returns the label for the menu item. + * @return string + */ + public function getLabel(): string + { + if ($this->translationService) { + return $this->translationService->getTranslation($this->label); + } else { + return $this->label; + } + } + + /** + * The label for this menu item. + * + * @param string $label + */ + public function setLabel(string $label): void + { + $this->label = $label; + } + + /** + * Returns the URL for this menu (or null if this menu is not a link). + * @return string + */ + public function getUrl(): string + { + return $this->url; + } + + /** + * The link for the menu (relative to the root url), unless it starts with / or http:// or https://. + * + * @param string|null $url + */ + public function setUrl(?string $url): self + { + $this->url = $url; + return $this; + } + + /** + * Returns a list of children elements for the menu (if there are some). + * + * @see MenuItemInterface::getChildren() + * @return array + */ + public function getChildren(): array + { + if ($this->sorted === false && $this->children !== []) { + // First, let's make 2 arrays: the array of children with a priority, and the array without. + $childrenWithPriorities = array(); + $childrenWithoutPriorities = array(); + foreach ($this->children as $child) { + /* @var $child MenuItemInterface */ + $priority = $child->getPriority(); + if ($priority === null) { + $childrenWithoutPriorities[] = $child; + } else { + $childrenWithPriorities[] = $child; + } + } + + usort($childrenWithPriorities, array($this, "compareMenuItems")); + $this->children = array_merge($childrenWithPriorities, $childrenWithoutPriorities); + $this->sorted = true; + } + return $this->children; + } + + private $sorted = false; + + public function compareMenuItems(MenuItem $item1, MenuItem $item2): int + { + $priority1 = $item1->getPriority(); + $priority2 = $item2->getPriority(); + /*if ($priority1 === null && $priority2 === null) { + // If no priority is set, let's keep the default ordering (which happens is usort by always returning positive numbers...) + return 1; + }*/ + return $priority1 <=> $priority2; + } + + /** + * The children menu item of this menu (if any). + * + * @param array $children + */ + public function setChildren(array $children): self + { + $this->sorted = false; + $this->children = $children; + return $this; + } - /** - * Adds a menu item as a child of this menu item. - * - * @param MenuItemInterface $menuItem - */ - public function addMenuItem(MenuItemInterface $menuItem): void { - $this->sorted = false; - $this->children[] = $menuItem; - } - - /** - * Returns true if the menu is in active state (if we are on the page for this menu). - * @return bool - */ - public function isActive(): bool { - if ($this->isActive) { - return true; - } - // TODO: really compare URLs instead of performin a strpos. - // We can do this using the parse_url function - //var_dump(parse_url(ROOT_URL.$this->url)); - - //$requestUrl = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')); - - //error_log($_SERVER['REQUEST_URI'].' - '.$requestUrl.' - '.ROOT_URL.$this->url); - if($this->activateBasedOnUrl && $this->url !== null) { - $urlParts = parse_url($_SERVER['REQUEST_URI']); - $menuUrlParts = parse_url($this->getLinkWithoutParams()); - - if (isset($menuUrlParts['path'])) { - $menuUrl = $menuUrlParts['path']; - } else { - $menuUrl = '/'; - } - - if (isset($urlParts['path'])) { - $requestUrl = $urlParts['path']; - } else { - $requestUrl = '/'; - } - - if($requestUrl == $menuUrl) { - return true; - } - } - /* - if ($this->activateBasedOnUrl && $this->url && strpos($_SERVER['REQUEST_URI'], ROOT_URL.$this->url) !== false) { - return true; - } - */ - return false; - } - - /** - * Set the active state of the menu. - * - * @param bool $isActive - */ - public function setIsActive(bool $isActive): self { - $this->isActive = $isActive; - return $this; - } - - /** - * Enables the menu item (activates it). - * - */ - public function enable(): self { - $this->isActive = true; - return $this; - } - - /** - * Returns true if the menu should be in extended state (if we can see the children directly). - * @return bool|null - */ - public function isExtended(): ?bool { - return $this->isExtended; - } + /** + * Adds a menu item as a child of this menu item. + * + * @param MenuItemInterface $menuItem + */ + public function addMenuItem(MenuItemInterface $menuItem): void + { + $this->sorted = false; + $this->children[] = $menuItem; + } + + /** + * Returns true if the menu is in active state (if we are on the page for this menu). + * @return bool + */ + public function isActive(): bool + { + if ($this->isActive) { + return true; + } + // TODO: really compare URLs instead of performin a strpos. + // We can do this using the parse_url function + //var_dump(parse_url(ROOT_URL.$this->url)); + + //$requestUrl = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')); + + //error_log($_SERVER['REQUEST_URI'].' - '.$requestUrl.' - '.ROOT_URL.$this->url); + if ($this->activateBasedOnUrl && $this->url !== null) { + $urlParts = parse_url($_SERVER['REQUEST_URI']); + $menuUrlParts = parse_url($this->getLinkWithoutParams()); + + if (isset($menuUrlParts['path'])) { + $menuUrl = $menuUrlParts['path']; + } else { + $menuUrl = '/'; + } + + if (isset($urlParts['path'])) { + $requestUrl = $urlParts['path']; + } else { + $requestUrl = '/'; + } + + if ($requestUrl == $menuUrl) { + return true; + } + } + /* + if ($this->activateBasedOnUrl && $this->url && strpos($_SERVER['REQUEST_URI'], ROOT_URL.$this->url) !== false) { + return true; + } + */ + return false; + } + + /** + * Set the active state of the menu. + * + * @param bool $isActive + */ + public function setIsActive(bool $isActive): self + { + $this->isActive = $isActive; + return $this; + } + + /** + * Enables the menu item (activates it). + * + */ + public function enable(): self + { + $this->isActive = true; + return $this; + } + + /** + * Returns true if the menu should be in extended state (if we can see the children directly). + * @return bool|null + */ + public function isExtended(): ?bool + { + return $this->isExtended; + } - /** - * Whether the menu is extended or not. - * This should not have an effect if the menu has no child. - * - * @param bool $isExtended - */ - public function setIsExtended(bool $isExtended = true): self { - $this->isExtended = $isExtended; - return $this; - } - - /** - * Returns an optional CSS class to apply to the menu item. - * @return string - */ - public function getCssClass(): string { - return $this->cssClass; - } + /** + * Whether the menu is extended or not. + * This should not have an effect if the menu has no child. + * + * @param bool $isExtended + */ + public function setIsExtended(bool $isExtended = true): self + { + $this->isExtended = $isExtended; + return $this; + } + + /** + * Returns an optional CSS class to apply to the menu item. + * @return string + */ + public function getCssClass(): string + { + return $this->cssClass; + } - /** - * An optional CSS class to apply to the menu item. - * Use of this property depends on the menu implementation. - * - * @param string $cssClass - */ - public function setCssClass(string $cssClass): self { - $this->cssClass = $cssClass; - return $this; - } + /** + * An optional CSS class to apply to the menu item. + * Use of this property depends on the menu implementation. + * + * @param string $cssClass + */ + public function setCssClass(string $cssClass): self + { + $this->cssClass = $cssClass; + return $this; + } - /** - * Level of priority used to order the menu items. - * - * @param float|null $priority - */ - public function setPriority(?float $priority): self { - $this->priority = $priority; - return $this; - } + /** + * Level of priority used to order the menu items. + * + * @param float|null $priority + */ + public function setPriority(?float $priority): self + { + $this->priority = $priority; + return $this; + } - /** - * Returns the level of priority. It is used to order the menu items. - * @return float - */ - public function getPriority(): ?float { - return $this->priority; - } + /** + * Returns the level of priority. It is used to order the menu items. + * @return float + */ + public function getPriority(): ?float + { + return $this->priority; + } - /** - * Returns the list of additionnal style - * @return array - */ - public function getAdditionalStyles(): array { - return $this->additionalStyles; - } + /** + * Returns the list of additionnal style + * @return array + */ + public function getAdditionalStyles(): array + { + return $this->additionalStyles; + } - /** - * Returns the one of additionnal style - * @return MenuItemStyleInterface - */ - public function getAdditionalStyleByType(string $type): MenuItemStyleInterface { - $return = null; - if($this->additionalStyles) { - foreach ($this->additionalStyles as $additionalStyle) { - if($additionalStyle instanceof $type) { - if($return === null) - $return = $additionalStyle; - else - throw new \LogicException("MenuItem: There are many instance of $type, please use getAdditionalStylesByType function to get all instance"); - } - } - } - return $return; - } + /** + * Returns the one of additionnal style + * @return MenuItemStyleInterface + */ + public function getAdditionalStyleByType(string $type): MenuItemStyleInterface + { + $return = null; + if ($this->additionalStyles) { + foreach ($this->additionalStyles as $additionalStyle) { + if ($additionalStyle instanceof $type) { + if ($return === null) { + $return = $additionalStyle; + } else { + throw new \LogicException("MenuItem: There are many instance of $type, please use getAdditionalStylesByType function to get all instance"); + } + } + } + } + return $return; + } - /** - * Returns the list of additionnal style - * @return array - */ - public function getAdditionalStylesByType(string $type): array { - $return = array(); - if($this->additionalStyles) { - foreach ($this->additionalStyles as $additionalStyle) { - if($additionalStyle instanceof $type) { - $return[] = $additionalStyle; - } - } - } - return $return; - } - - /** - * Add menu item style. - * - * @param array $menuItemStyleInterface - */ - public function setAdditionalStyles(array $menuItemStyleInterface): self { - $this->additionalStyles = $menuItemStyleInterface; - return $this; - } - - /** - * Returns true if this menu item is a separator. - * A separator is a special case of menu item that is juste here to separate menu items with a bar. - * It has no label, no URL, etc... - * - * @return bool - */ - public function isSeparator(): bool { - return false; - } - - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ - public function isHidden(): bool { - if ($this->displayCondition === null) { - return false; - } - return !$this->displayCondition->isOk(); - } + /** + * Returns the list of additionnal style + * @return array + */ + public function getAdditionalStylesByType(string $type): array + { + $return = array(); + if ($this->additionalStyles) { + foreach ($this->additionalStyles as $additionalStyle) { + if ($additionalStyle instanceof $type) { + $return[] = $additionalStyle; + } + } + } + return $return; + } + + /** + * Add menu item style. + * + * @param array $menuItemStyleInterface + */ + public function setAdditionalStyles(array $menuItemStyleInterface): self + { + $this->additionalStyles = $menuItemStyleInterface; + return $this; + } + + /** + * Returns true if this menu item is a separator. + * A separator is a special case of menu item that is juste here to separate menu items with a bar. + * It has no label, no URL, etc... + * + * @return bool + */ + public function isSeparator(): bool + { + return false; + } + + /** + * If this function returns true, the menu item should not be displayed. + * + * @return bool + */ + public function isHidden(): bool + { + if ($this->displayCondition === null) { + return false; + } + return !$this->displayCondition->isOk(); + } - /** - * If any translation service is set, it will be used to translate the label. - * Otherwise, the label is displayed "as-is". - * - * @param TranslatorInterface $translationService - */ - public function setTranslationService(TranslatorInterface $translationService): self { - $this->translationService = $translationService; - return $this; - } + /** + * If any translation service is set, it will be used to translate the label. + * Otherwise, the label is displayed "as-is". + * + * @param TranslatorInterface $translationService + */ + public function setTranslationService(TranslatorInterface $translationService): self + { + $this->translationService = $translationService; + return $this; + } - /** - * If set, this display condition is tested. If it returns false, the menu will be hidden. - * - * @param ConditionInterface $displayCondition - */ - public function setDisplayCondition(ConditionInterface $displayCondition): self { - $this->displayCondition = $displayCondition; - return $this; - } - - /** - * A list of parameters that are propagated by the link. - * For instance, if the parameter "mode" is set to 42 on the page (because the URL is http://mywebsite/myurl?mode=42), - * then if you choose to propagate the "mode" parameter, the menu link will have "mode=42" as a parameter. - * - * @param array $propagatedUrlParameters - */ - public function setPropagatedUrlParameters(array $propagatedUrlParameters): self { - $this->propagatedUrlParameters = $propagatedUrlParameters; - return $this; - } - - - /** - * Returns the absolute URL, with parameters if required. - * @return string - */ - public function getLink(): ?string { - if ($this->url === null) { - return null; - } - $link = $this->getLinkWithoutParams(); - - $params = array(); - // First, get the list of all parameters to be propagated - if (is_array($this->propagatedUrlParameters)) { - foreach ($this->propagatedUrlParameters as $parameter) { - if (isset($_REQUEST[$parameter])) { - $params[$parameter] = $_REQUEST($parameter); - } - } - } - - if (!empty($params)) { - if (strpos($link, "?") === FALSE) { - $link .= "?"; - } else { - $link .= "&"; - } - $paramsAsStrArray = array(); - foreach ($params as $key=>$value) { - $paramsAsStrArray[] = urlencode($key).'='.urlencode($value); - } - $link .= implode("&", $paramsAsStrArray); - } - - return $link; - } - - private function getLinkWithoutParams(): string { - if (strpos($this->url, "/") === 0 - || strpos($this->url, "javascript:") === 0 - || strpos($this->url, "http://") === 0 - || strpos($this->url, "https://") === 0 - || strpos($this->url, "?") === 0 - || strpos($this->url, "#") === 0) { - return $this->url; - } - - return $this->rootUrl.$this->url; - } - - /** - * If the URL of the current page matches the URL of the link, the link will be considered as "active". - * - * @param bool $activateBasedOnUrl - */ - public function setActivateBasedOnUrl(bool $activateBasedOnUrl = true): self { - $this->activateBasedOnUrl = $activateBasedOnUrl; - return $this; - } + /** + * If set, this display condition is tested. If it returns false, the menu will be hidden. + * + * @param ConditionInterface $displayCondition + */ + public function setDisplayCondition(ConditionInterface $displayCondition): self + { + $this->displayCondition = $displayCondition; + return $this; + } + + /** + * A list of parameters that are propagated by the link. + * For instance, if the parameter "mode" is set to 42 on the page (because the URL is http://mywebsite/myurl?mode=42), + * then if you choose to propagate the "mode" parameter, the menu link will have "mode=42" as a parameter. + * + * @param array $propagatedUrlParameters + */ + public function setPropagatedUrlParameters(array $propagatedUrlParameters): self + { + $this->propagatedUrlParameters = $propagatedUrlParameters; + return $this; + } + + + /** + * Returns the absolute URL, with parameters if required. + * @return string + */ + public function getLink(): ?string + { + if ($this->url === null) { + return null; + } + $link = $this->getLinkWithoutParams(); + + $params = array(); + // First, get the list of all parameters to be propagated + if (is_array($this->propagatedUrlParameters)) { + foreach ($this->propagatedUrlParameters as $parameter) { + if (isset($_REQUEST[$parameter])) { + $params[$parameter] = $_REQUEST($parameter); + } + } + } + + if (!empty($params)) { + if (strpos($link, "?") === false) { + $link .= "?"; + } else { + $link .= "&"; + } + $paramsAsStrArray = array(); + foreach ($params as $key => $value) { + $paramsAsStrArray[] = urlencode($key).'='.urlencode($value); + } + $link .= implode("&", $paramsAsStrArray); + } + + return $link; + } + + private function getLinkWithoutParams(): string + { + if (strpos($this->url, "/") === 0 + || strpos($this->url, "javascript:") === 0 + || strpos($this->url, "http://") === 0 + || strpos($this->url, "https://") === 0 + || strpos($this->url, "?") === 0 + || strpos($this->url, "#") === 0) { + return $this->url; + } + + return $this->rootUrl.$this->url; + } + + /** + * If the URL of the current page matches the URL of the link, the link will be considered as "active". + * + * @param bool $activateBasedOnUrl + */ + public function setActivateBasedOnUrl(bool $activateBasedOnUrl = true): self + { + $this->activateBasedOnUrl = $activateBasedOnUrl; + return $this; + } } diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php b/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php index 11e0275..74143b7 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php @@ -1,7 +1,7 @@ - */ + + /** + * Returns a list of children elements for the menu (if there are some). + * @return array + */ public function getChildren(): array; - - /** - * Returns true if the menu is in active state (if we are on the page for this menu). - * @return bool - */ + + /** + * Returns true if the menu is in active state (if we are on the page for this menu). + * @return bool + */ public function isActive(): bool; - - /** - * Returns true if the menu should be in extended state (if we can see the children directly). - * @return bool - */ + + /** + * Returns true if the menu should be in extended state (if we can see the children directly). + * @return bool + */ public function isExtended(): ?bool; - - /** - * Returns an optional CSS class to apply to the menu item. - * @return string - */ + + /** + * Returns an optional CSS class to apply to the menu item. + * @return string + */ public function getCssClass(): string; - - /** - * Returns true if this menu item is a separator. - * A separator is a special case of menu item that is juste here to separate menu items with a bar. - * It has no label, no URL, etc... - * - * @return bool - */ + + /** + * Returns true if this menu item is a separator. + * A separator is a special case of menu item that is juste here to separate menu items with a bar. + * It has no label, no URL, etc... + * + * @return bool + */ public function isSeparator(): bool; - - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ + + /** + * If this function returns true, the menu item should not be displayed. + * + * @return bool + */ public function isHidden(): bool; - - /** - * Returns the level of priority. It is used to order the menu items. - * @return float|null - */ - public function getPriority(): ?float; - - /** - * Returns the list of additionnal style - * @return array - */ + + /** + * Returns the level of priority. It is used to order the menu items. + * @return float|null + */ + public function getPriority(): ?float; + + /** + * Returns the list of additionnal style + * @return array + */ public function getAdditionalStyles(): array; } - diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php b/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php index 88844f8..cf27177 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php @@ -1,7 +1,7 @@ rootUrl = $rootUrl; } - /** - * Returns the URL for this menu (or null if this menu is not a link). - * @return string - */ - public function getUrl(): string { - if (strpos($this->url, "/") === 0 - || strpos($this->url, "javascript:") === 0 - || strpos($this->url, "http://") === 0 - || strpos($this->url, "https://") === 0) { - return $this->url; - } - return $this->rootUrl.$this->url; - } + /** + * Returns the URL for this menu (or null if this menu is not a link). + * @return string + */ + public function getUrl(): string + { + if (strpos($this->url, "/") === 0 + || strpos($this->url, "javascript:") === 0 + || strpos($this->url, "http://") === 0 + || strpos($this->url, "https://") === 0) { + return $this->url; + } + return $this->rootUrl.$this->url; + } } diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemStyleInterface.php b/src/Mouf/Html/Widgets/Menu/MenuItemStyleInterface.php index 1b27ef0..0661c92 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemStyleInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemStyleInterface.php @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php b/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php index fa9150c..a29b2a6 100644 --- a/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemTarget.php @@ -1,7 +1,7 @@ target = $target; } - - /** - * Returns the target html attribute or null if not set. - * @return string - */ - public function getTarget(): string { + + /** + * Returns the target html attribute or null if not set. + * @return string + */ + public function getTarget(): string + { return $this->target; - } + } } diff --git a/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php b/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php index c31a66f..c0269a4 100644 --- a/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php +++ b/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php @@ -3,7 +3,6 @@ namespace Mouf\Html\Widgets\Menu; - use Mouf\Html\Renderer\AbstractPackageRendererServiceProvider; class MenuRendererServiceProvider extends AbstractPackageRendererServiceProvider diff --git a/src/Mouf/Html/Widgets/Menu/MenuStyleInterface.php b/src/Mouf/Html/Widgets/Menu/MenuStyleInterface.php index 70f4aee..a9ede32 100644 --- a/src/Mouf/Html/Widgets/Menu/MenuStyleInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuStyleInterface.php @@ -1,7 +1,7 @@ \ No newline at end of file