├── .gitignore ├── .php_cs.dist ├── Builder ├── Item.php ├── ItemInterface.php ├── ItemProcess.php ├── ItemProcessInterface.php ├── Menu.php └── MenuInterface.php ├── DependencyInjection ├── Configuration.php └── PdMenuExtension.php ├── Event └── PdMenuEvent.php ├── LICENSE ├── Locator └── MenuLocator.php ├── PdMenuBundle.php ├── README.md ├── Render ├── RenderInterface.php └── TwigRender.php ├── Resources ├── config │ └── services.yml └── views │ └── Default │ ├── menu.html.twig │ └── menuBase.html.twig ├── Twig └── MenuExtension.php └── composer.json /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | /composer.lock 3 | .php_cs.cache 4 | -------------------------------------------------------------------------------- /.php_cs.dist: -------------------------------------------------------------------------------- 1 | 9 | @link https://github.com/appaydin/pd-menu 10 | COMMENT; 11 | 12 | $finder = PhpCsFixer\Finder::create() 13 | ->in(__DIR__) 14 | ; 15 | 16 | return PhpCsFixer\Config::create() 17 | ->setRiskyAllowed(true) 18 | ->setRules([ 19 | '@Symfony' => true, 20 | '@Symfony:risky' => true, 21 | 'array_syntax' => ['syntax' => 'short'], 22 | 'header_comment' => ['header' => $fileHeaderComment, 'separate' => 'both', 'commentType' => 'PHPDoc'], 23 | 'linebreak_after_opening_tag' => true, 24 | 'mb_str_functions' => true, 25 | 'no_php4_constructor' => true, 26 | 'no_useless_else' => true, 27 | 'no_useless_return' => true, 28 | 'ordered_imports' => true, 29 | 'php_unit_strict' => true, 30 | 'phpdoc_order' => true, 31 | 'semicolon_after_instruction' => true, 32 | 'strict_comparison' => true, 33 | 'strict_param' => true, 34 | 'blank_line_after_namespace' => true, 35 | 'class_definition' => true, 36 | 'multiline_comment_opening_closing' => true, 37 | 'single_line_comment_style' => true, 38 | 'single_blank_line_before_namespace' => true, 39 | 'phpdoc_trim' => true, 40 | 'no_extra_consecutive_blank_lines' => true 41 | ]) 42 | ->setFinder($finder) 43 | ->setCacheFile(__DIR__.'.php_cs.cache') 44 | ; 45 | -------------------------------------------------------------------------------- /Builder/Item.php: -------------------------------------------------------------------------------- 1 | 9 | * @link https://github.com/appaydin/pd-menu 10 | */ 11 | 12 | namespace Pd\MenuBundle\Builder; 13 | 14 | /** 15 | * Menu Item Properties. 16 | * 17 | * @author Ramazan APAYDIN 18 | */ 19 | class Item implements ItemInterface 20 | { 21 | protected $id; 22 | protected string $label = ''; 23 | protected string $labelAfterHtml = ''; 24 | protected string $link = ''; 25 | protected string $linkAfterHtml = ''; 26 | protected $order; 27 | protected array $route = []; 28 | protected array $linkAttr = []; 29 | protected array $listAttr = []; 30 | protected array $childAttr = []; 31 | protected array $labelAttr = []; 32 | protected array $extra = []; 33 | protected array $roles = []; 34 | 35 | /** 36 | * @var ItemInterface[] 37 | */ 38 | protected array $child = []; 39 | protected $parent; 40 | protected bool $event; 41 | 42 | public function __construct(string $id, $event) 43 | { 44 | $this->id = $id; 45 | $this->event = $event; 46 | } 47 | 48 | public function isEvent(): bool 49 | { 50 | return (int)$this->event; 51 | } 52 | 53 | public function getId(): ?string 54 | { 55 | return $this->id; 56 | } 57 | 58 | public function setId($id = null): ItemInterface 59 | { 60 | $this->id = $id; 61 | 62 | return $this; 63 | } 64 | 65 | public function getLabel(): string 66 | { 67 | return $this->label; 68 | } 69 | 70 | public function setLabel(string $label): ItemInterface 71 | { 72 | $this->label = $label; 73 | 74 | return $this; 75 | } 76 | 77 | public function getLabelAfterHtml(): string 78 | { 79 | return $this->labelAfterHtml; 80 | } 81 | 82 | public function setLabelAfterHtml(string $html): ItemInterface 83 | { 84 | $this->labelAfterHtml = $html; 85 | 86 | return $this; 87 | } 88 | 89 | public function getLink(): string 90 | { 91 | return $this->link; 92 | } 93 | 94 | public function setLink(string $link): ItemInterface 95 | { 96 | $this->link = $link; 97 | 98 | return $this; 99 | } 100 | 101 | public function getLinkAfterHtml(): string 102 | { 103 | return $this->linkAfterHtml; 104 | } 105 | 106 | public function setLinkAfterHtml(string $html): ItemInterface 107 | { 108 | $this->linkAfterHtml = $html; 109 | 110 | return $this; 111 | } 112 | 113 | public function getOrder(): int 114 | { 115 | return $this->order; 116 | } 117 | 118 | public function setOrder(int $order): ItemInterface 119 | { 120 | $this->order = $order; 121 | 122 | return $this; 123 | } 124 | 125 | public function getRoute(): array 126 | { 127 | return $this->route; 128 | } 129 | 130 | public function setRoute(string $route, array $params = []): ItemInterface 131 | { 132 | $this->route = [ 133 | 'name' => $route, 134 | 'params' => $params, 135 | ]; 136 | 137 | return $this; 138 | } 139 | 140 | public function getLinkAttr(): array 141 | { 142 | return $this->linkAttr; 143 | } 144 | 145 | public function setLinkAttr(array $linkAttr): ItemInterface 146 | { 147 | $this->linkAttr = array_merge($this->linkAttr, $linkAttr); 148 | 149 | return $this; 150 | } 151 | 152 | public function getListAttr(): array 153 | { 154 | return $this->listAttr; 155 | } 156 | 157 | public function setListAttr(array $listAttr): ItemInterface 158 | { 159 | $this->listAttr = array_merge($this->listAttr, $listAttr); 160 | 161 | return $this; 162 | } 163 | 164 | public function getChildAttr(): array 165 | { 166 | return $this->childAttr; 167 | } 168 | 169 | public function setChildAttr(array $childAttr): ItemInterface 170 | { 171 | $this->childAttr = array_merge($this->childAttr, $childAttr); 172 | 173 | return $this; 174 | } 175 | 176 | public function getLabelAttr(): array 177 | { 178 | return $this->labelAttr; 179 | } 180 | 181 | public function setLabelAttr(array $labelAttr): ItemInterface 182 | { 183 | $this->labelAttr = array_merge($this->labelAttr, $labelAttr); 184 | 185 | return $this; 186 | } 187 | 188 | public function getExtra(string $name, $default = false) 189 | { 190 | if (\is_array($this->extra) && isset($this->extra[$name])) { 191 | return $this->extra[$name]; 192 | } 193 | 194 | return $default; 195 | } 196 | 197 | public function setExtra(string $name, $value): ItemInterface 198 | { 199 | if (\is_array($this->extra)) { 200 | $this->extra[$name] = $value; 201 | } else { 202 | $this->extra = [$name => $value]; 203 | } 204 | 205 | return $this; 206 | } 207 | 208 | public function getRoles(): array 209 | { 210 | return $this->roles; 211 | } 212 | 213 | public function setRoles(array $roles): ItemInterface 214 | { 215 | $this->roles = array_merge($this->roles, $roles); 216 | 217 | return $this; 218 | } 219 | 220 | public function getChild(): array 221 | { 222 | return $this->child; 223 | } 224 | 225 | public function setChild(array $child): ItemInterface 226 | { 227 | $this->child = $child; 228 | 229 | return $this; 230 | } 231 | 232 | public function addChild($child, $order = null): ItemInterface 233 | { 234 | // Create New Item 235 | if (!$child instanceof ItemInterface) { 236 | $child = new self($child, $this->event); 237 | } 238 | 239 | // Child Set Parent & ID 240 | $child 241 | ->setOrder($order ?? \count($this->child)) 242 | ->setParent($this); 243 | 244 | // Add Child This 245 | $this->child[$child->getId()] = $child; 246 | 247 | return $child; 248 | } 249 | 250 | public function addChildParent($child, $order = null): ItemInterface 251 | { 252 | return $this->parent->addChild($child, $order); 253 | } 254 | 255 | public function getParent(): ?ItemInterface 256 | { 257 | return $this->parent; 258 | } 259 | 260 | public function setParent(ItemInterface $item): ItemInterface 261 | { 262 | if ($item === $this) { 263 | throw new \InvalidArgumentException('Item cannot be a child of itself'); 264 | } 265 | 266 | $this->parent = $item; 267 | 268 | return $this; 269 | } 270 | 271 | public function isRoot(): bool 272 | { 273 | return null === $this->parent; 274 | } 275 | 276 | public function getLevel(): int 277 | { 278 | return $this->parent ? $this->parent->getLevel() + 1 : 0; 279 | } 280 | 281 | public function offsetExists($childId) 282 | { 283 | return isset($this->child[$childId]); 284 | } 285 | 286 | public function offsetGet($childId) 287 | { 288 | return $this->child[$childId]; 289 | } 290 | 291 | public function offsetSet($childId, $order) 292 | { 293 | return $this->addChild($childId, $order); 294 | } 295 | 296 | public function offsetUnset($childId) 297 | { 298 | if ($this->offsetExists($childId)) { 299 | unset($this->child[$childId]); 300 | } 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /Builder/ItemInterface.php: -------------------------------------------------------------------------------- 1 | 9 | * @link https://github.com/appaydin/pd-menu 10 | */ 11 | 12 | namespace Pd\MenuBundle\Builder; 13 | 14 | /** 15 | * Menu Item Interface. 16 | * 17 | * @author Ramazan APAYDIN 18 | */ 19 | interface ItemInterface extends \ArrayAccess 20 | { 21 | /** 22 | * Menu Created Event. 23 | */ 24 | public function isEvent(): bool; 25 | 26 | /** 27 | * Get Item Array ID | Order ID. 28 | */ 29 | public function getId(): ?string; 30 | 31 | /** 32 | * Set Item Array ID | Order ID. 33 | */ 34 | public function setId($id = null): self; 35 | 36 | /** 37 | * Get Menu Name. 38 | */ 39 | public function getLabel(): string; 40 | 41 | /** 42 | * Change Name Menu Item. 43 | */ 44 | public function setLabel(string $label): self; 45 | 46 | /** 47 | * Get Label After HTML. 48 | */ 49 | public function getLabelAfterHtml(): string; 50 | 51 | /** 52 | * Label After Append HTML. 53 | */ 54 | public function setLabelAfterHtml(string $html): self; 55 | 56 | /** 57 | * Get Menu Item URL. 58 | */ 59 | public function getLink(): string; 60 | 61 | /** 62 | * Change Menu URL. 63 | */ 64 | public function setLink(string $link): self; 65 | 66 | /** 67 | * Get Link After HTML. 68 | */ 69 | public function getLinkAfterHtml(): string; 70 | 71 | /** 72 | * Label Link Append HTML. 73 | */ 74 | public function setLinkAfterHtml(string $html): self; 75 | 76 | /** 77 | * Get Order Number. 78 | */ 79 | public function getOrder(): int; 80 | 81 | /** 82 | * Set Order Number. 83 | */ 84 | public function setOrder(int $order): self; 85 | 86 | /** 87 | * Get Menu Route Name. 88 | */ 89 | public function getRoute(): array; 90 | 91 | /** 92 | * Change Menu Route. 93 | */ 94 | public function setRoute(string $route, array $params = []): self; 95 | 96 | /** 97 | * Get Link Attributes "". 98 | */ 99 | public function getLinkAttr(): array; 100 | 101 | /** 102 | * Set Link Attributes "". 103 | */ 104 | public function setLinkAttr(array $linkAttr): self; 105 | 106 | /** 107 | * Get List Attributes "
  • ". 108 | */ 109 | public function getListAttr(): array; 110 | 111 | /** 112 | * Set List Attributes "
  • ". 113 | */ 114 | public function setListAttr(array $listAttr): self; 115 | 116 | /** 117 | * Get Child List Attributes "