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/.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 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..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($children=null) { - $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() { - 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 === "") { - $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) { - $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) { - $this->sorted = false; - $this->children = $children; - } - - /** - * Adds one child menu item to this menu item. - * - * @param MenuItem $child - */ - public function addChild(MenuItem $child) { - $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) { - $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() { - 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(); + } } -?> \ 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..7eb9962 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuInterface.php @@ -1,7 +1,7 @@ - */ - function getChildren(); - - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ - function isHidden(); +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; } - -?> \ 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..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 LanguageTranslationInterface - */ - 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(); - - /** - * 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($label=null, $url=null, $children=array()) { - $this->label = $label; - $this->url = $url; - $this->children = $children; - } + /** + * 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; - /** - * Returns the label for the menu item. - * @return string - */ - public function getLabel() { - 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($label) { - $this->label = $label; - } - - /** - * Returns the URL for this menu (or null if this menu is not a link). - * @return string - */ - public function getUrl() { - return $this->url; - } - - /** - * The link for the menu (relative to the root url), unless it starts with / or http:// or https://. - * - * @param string $url - */ - public function setUrl($url) { - $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() { - 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 === "") { - $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) { - $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) { - $this->sorted = false; - $this->children = $children; - return $this; - } + /** + * 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; + } - /** - * Adds a menu item as a child of this menu item. - * - * @param MenuItemInterface $menuItem - */ - public function addMenuItem(MenuItemInterface $menuItem) { - $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() { - 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($isActive) { - $this->isActive = $isActive; - return $this; - } - - /** - * Enables the menu item (activates it). - * - */ - public function enable() { - $this->isActive = true; - return $this; - } - - /** - * Returns true if the menu should be in extended state (if we can see the children directly). - * @return bool - */ - public function isExtended() { - return $this->isExtended; - } + /** + * 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; + } - /** - * 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($isExtended = true) { - $this->isExtended = $isExtended; - return $this; - } - - /** - * Returns an optional CSS class to apply to the menu item. - * @return string - */ - public function getCssClass() { - return $this->cssClass; - } + /** + * 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; + } - /** - * 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($cssClass) { - $this->cssClass = $cssClass; - return $this; - } + /** + * 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; + } - /** - * Level of priority used to order the menu items. - * - * @param float $priority - */ - public function setPriority($priority) { - $this->priority = $priority; - 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; + } - /** - * Returns the level of priority. It is used to order the menu items. - * @return float - */ - public function getPriority() { - return $this->priority; - } + /** + * 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 list of additionnal style - * @return array - */ - public function getAdditionalStyles() { - return $this->additionalStyles; - } + /** + * Returns the level of priority. It is used to order the menu items. + * @return float + */ + public function getPriority(): ?float + { + return $this->priority; + } - /** - * Returns the one of additionnal style - * @return array - */ - public function getAdditionalStyleByType($type) { - $return = null; - if($this->additionalStyles) { - foreach ($this->additionalStyles as $additionalStyle) { - if($additionalStyle instanceof $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"); - } - } - } - return $return; - } + /** + * 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 getAdditionalStylesByType($type) { - $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($menuItemStyleInterface) { - $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() { - return false; - } - - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ - public function isHidden() { - if ($this->displayCondition == null) { - return false; - } - return !$this->displayCondition->isOk(); - } + /** + * 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; + } - /** - * If any translation service is set, it will be used to translate the label. - * Otherwise, the label is displayed "as-is". - * - * @param LanguageTranslationInterface $translationService - */ - public function setTranslationService(LanguageTranslationInterface $translationService) { - $this->translationService = $translationService; - return $this; - } + /** + * 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 set, this display condition is tested. If it returns false, the menu will be hidden. - * - * @param ConditionInterface $displayCondition - */ - public function setDisplayCondition(ConditionInterface $displayCondition) { - $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($propagatedUrlParameters) { - $this->propagatedUrlParameters = $propagatedUrlParameters; - return $this; - } - - - /** - * Returns the absolute URL, with parameters if required. - * @return string - */ - public function getLink() { - 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] = \get($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() { - 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 ROOT_URL.$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($activateBasedOnUrl = true) { - $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; + } } -?> \ 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..74143b7 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemInterface.php @@ -1,7 +1,7 @@ - */ - function getChildren(); - - /** - * Returns true if the menu is in active state (if we are on the page for this menu). - * @return bool - */ - function isActive(); - - /** - * Returns true if the menu should be in extended state (if we can see the children directly). - * @return bool - */ - function isExtended(); - - /** - * Returns an optional CSS class to apply to the menu item. - * @return string - */ - function getCssClass(); - - /** - * 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 - */ - function isSeparator(); - - /** - * If this function returns true, the menu item should not be displayed. - * - * @return bool - */ - function isHidden(); - - /** - * Returns the level of priority. It is used to order the menu items. - * @return float - */ - function getPriority(); - - /** - * Returns the list of additionnal style - * @return array - */ - function getAdditionalStyles(); + /** + * Returns the URL for this menu (or null if this menu is not a link). + * @return string + */ + public function getUrl(): ?string; + + /** + * 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 + */ + public function isActive(): 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 + */ + 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 + */ + public function isSeparator(): 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 + */ + 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..cf27177 100755 --- a/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php +++ b/src/Mouf/Html/Widgets/Menu/MenuItemStyleIcon.php @@ -1,7 +1,7 @@ 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; - } - - /** - * 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; - } +class MenuItemStyleIcon implements MenuItemStyleInterface +{ + + /** + * The link for the icon (relative to the root url), unless it starts with / or http:// or https://. + * + * @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(): 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; + } } -?> \ No newline at end of file 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 09e57a1..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() { + + /** + * Returns the target html attribute or null if not set. + * @return string + */ + 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..c0269a4 --- /dev/null +++ b/src/Mouf/Html/Widgets/Menu/MenuRendererServiceProvider.php @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/src/install.php b/src/install.php deleted file mode 100644 index ea17e22..0000000 --- a/src/install.php +++ /dev/null @@ -1,24 +0,0 @@ -rewriteMouf(); - -// Finally, let's continue the install -InstallUtils::continueInstall(isset($_REQUEST['selfedit']) && $_REQUEST['selfedit'] == 'true'); -?> \ No newline at end of file