DefaultMenuItem.php

DefaultMenuItem

Namespace

Drupal\ooe\Menu

File

lib/Drupal/ooe/Menu/DefaultMenuItem.php
View source
  1. <?php
  2. /**
  3. * @file
  4. * DefaultMenuItem
  5. */
  6. namespace Drupal\ooe\Menu;
  7. use Drupal\ooe\Module\DefaultModuleHelper;
  8. // <img src="http://drupal7demo.webel.com.au/system/files/DefaultMenuItem.imp_.jpg"/>
  9. // Webel: Feature Request: Would like to be able
  10. // to include links to images in Class/Interface/Namespace docs
  11. // https://drupal.org/node/2201079
  12. /**
  13. * Default implementation of a menu item (without a page or form controller).
  14. *
  15. * UML:
  16. * @link http://drupal7demo.webel.com.au/node/1017 DefaultMenuItem @endlink
  17. *
  18. * @author darrenkelly
  19. */
  20. class DefaultMenuItem extends DefaultModuleHelper implements IMenuItem {
  21. /**
  22. * The title of the menu item.
  23. *
  24. * @var string
  25. */
  26. private $title;
  27. /**
  28. * Sets (or resets) the title of the menu item.
  29. *
  30. * @param string $title
  31. * The title of the menu item.
  32. *
  33. * @return IMenuItem
  34. * This.
  35. */
  36. final public function setTitle($title) {
  37. // @todo check is_string.
  38. $this->title = $title;
  39. return $this;
  40. }
  41. /*
  42. public function __construct($title) {
  43. $this->setTitle($title);
  44. } */
  45. /**
  46. * Constructor.
  47. *
  48. * @param string $module
  49. * The module machine name. Required.
  50. * @param string $title
  51. * The menu title. Required.
  52. *
  53. * @param string $path
  54. * The path portion of the menu item's URL. Required.
  55. */
  56. public function __construct($module, $title, $path) {
  57. parent::__construct($module);
  58. $this->setTitle($title);
  59. $this->setPath($path);
  60. }
  61. /**
  62. * The path portion of the menu item's URL.
  63. *
  64. * @var string
  65. */
  66. private $path;
  67. /**
  68. * The path portion of the menu item's URL.
  69. *
  70. * @return string
  71. * The path portion of the menu item's URL.
  72. */
  73. final public function getPath() {
  74. return $this->path;
  75. }
  76. /**
  77. * Sets the menu path portion of the menu item's URL.
  78. *
  79. * Usually not needed, prefer inject via the constructor.
  80. *
  81. * @param string $path
  82. * (Required.)
  83. *
  84. * @return IMenuItem
  85. * This.
  86. */
  87. final public function setPath($path) {
  88. // @todo check is present and is_string.
  89. $this->path = $path;
  90. return $this;
  91. }
  92. /**
  93. * From hook_menu(): 'The untranslated description of the menu item.'
  94. *
  95. * @var string
  96. */
  97. private $description;
  98. /**
  99. * Sets 'The untranslated description of the menu item'.
  100. *
  101. * @see hook_menu()
  102. *
  103. * @param string $description
  104. * 'The untranslated description of the menu item.'
  105. *
  106. * @return IMenuItem
  107. * This.
  108. */
  109. final public function setDescription($description) {
  110. // @todo check is_string.
  111. $this->description = $description;
  112. return $this;
  113. }
  114. /**
  115. * An array of arguments to pass to the access callback function.
  116. *
  117. * From hook_menu():
  118. * 'An array of arguments to pass to the access callback function ...
  119. * If the access callback is inherited ... ,
  120. * the access arguments will be inherited with it,
  121. * unless overridden in the child menu item.'
  122. *
  123. * @var string[]
  124. */
  125. protected $accessArguments;
  126. /**
  127. * Sets the access arguments.
  128. *
  129. * From hook_menu():
  130. * 'An array of arguments to pass to the access callback function ...
  131. * If the access callback is inherited ... ,
  132. * the access arguments will be inherited with it,
  133. * unless overridden in the child menu item.'
  134. *
  135. * @param string[] $accessArguments
  136. * An array of arguments to pass to the access callback function'
  137. *
  138. * @return IMenuItem
  139. * This.
  140. */
  141. public function setAccessArguments(array $accessArguments) {
  142. // @todo checks.
  143. $this->accessArguments = $accessArguments;
  144. return $this;
  145. }
  146. /**
  147. * The access callback.
  148. *
  149. * The access callback can carry either a string representing
  150. * a callback function returning TRUE or FALSE, or a boolean TRUE/FALSE;
  151. * there are dedicated setters provided here for handling each case.
  152. *
  153. * The numeric option is not (yet) supported here, and mostly not needed
  154. * since will be cast to boolean anyway.
  155. *
  156. * From hook_menu():
  157. *
  158. * '"access callback": A function returning TRUE if the user has access
  159. * rights to this menu item, and FALSE if not.
  160. * It can also be a boolean constant instead of a function,
  161. * and you can also use numeric values (will be cast to boolean).
  162. * Defaults to user_access() unless a value is inherited from the
  163. * parent menu item; only MENU_DEFAULT_LOCAL_TASK items can inherit
  164. * access callbacks. To use the user_access() default callback,
  165. * you must specify the permission to check as 'access arguments''
  166. *
  167. * @var string|bool
  168. */
  169. protected $accessCallback;
  170. /**
  171. * Sets the access callback to a string representing a callback function.
  172. *
  173. * For forcing it to a boolean TRUE or FALSE please use
  174. * @link IMenuItem::forceAccessCallbackTRUE @endlink() OR
  175. * @link IMenuItem::forceAccessCallbackFALSE @endlink().
  176. *
  177. * Integer values are not supported (yet) and mostly not needed.
  178. *
  179. * @todo Check whether callback function or method exists.
  180. *
  181. * @param string $accessCallback
  182. * A non-empty access callback string.
  183. *
  184. * @return IMenuItem
  185. * This.
  186. */
  187. public function setAccessCallback($accessCallback) {
  188. if (empty($accessCallback) || !is_string($accessCallback)) {
  189. throw new \Exception('$accessCallback' . "($accessCallback)" . ' must be a non-null string representing a callback function !');
  190. }
  191. $this->accessCallback = $accessCallback;
  192. return $this;
  193. }
  194. /**
  195. * Forces the access callback to be TRUE.
  196. *
  197. * @see IMenuItem::forceAccessCallbackFALSE()
  198. *
  199. * @see IMenuItem::setAccessCallback(string)
  200. *
  201. * @return IMenuItem
  202. * This.
  203. */
  204. final public function forceAccessCallbackTRUE() {
  205. $this->accessCallback = TRUE;
  206. return $this;
  207. }
  208. /**
  209. * Forces the access callback to be FALSE.
  210. *
  211. * @see IMenuItem::forceAccessCallbackTRUE()
  212. *
  213. * @see IMenuItem::setAccessCallback(string)
  214. *
  215. * @return IMenuItem
  216. * This.
  217. */
  218. final public function forceAccessCallbackFALSE() {
  219. $this->accessCallback = FALSE;
  220. return $this;
  221. }
  222. /**
  223. * An array of arguments to pass to the page callback.
  224. *
  225. * From hook_menu():
  226. * '"page arguments": An array of arguments to pass to the page callback
  227. * function, with path component substitution ...'
  228. *
  229. * @var string[]
  230. */
  231. protected $pageArguments;
  232. // NB: @var string[] not caught by PEAR PHP_UML !
  233. /**
  234. * Sets the page arguments.
  235. *
  236. * From hook_menu():
  237. * '"page arguments": An array of arguments to pass to the page callback
  238. * function, with path component substitution ...'
  239. *
  240. * @param string[] $pageArguments
  241. * An array of page argument strings.
  242. *
  243. * @return IMenuItem
  244. * This.
  245. */
  246. public function setPageArguments(array $pageArguments) {
  247. // @todo check that every array element is a string !
  248. $this->pageArguments = $pageArguments;
  249. return $this;
  250. }
  251. /**
  252. * From hook_menu():
  253. * '"page callback": The function to call to display a web page when
  254. * the user visits the path. If omitted, the parent menu item's callback
  255. * will be used instead.'
  256. *
  257. * @var string
  258. */
  259. protected $pageCallback;
  260. // NO! private//permit force set in subclasses
  261. // public function setPageCallback(callable $pageCallback) {
  262. // //http://www.php.net/manual/en/language.types.callable.php
  263. // Difficult to combine with Drupal callback string approach.
  264. /**
  265. * Sets the page callback.
  266. *
  267. * From hook_menu():
  268. * '"page callback": The function to call to display a web page when
  269. * the user visits the path. If omitted, the parent menu item's callback
  270. * will be used instead.'
  271. *
  272. * @param string $pageCallback
  273. * A non-empty string representing the page callback.
  274. *
  275. * @return IMenuItem
  276. * This.
  277. */
  278. public function setPageCallback($pageCallback) {
  279. if (empty($pageCallback) || !is_string($pageCallback)) {
  280. throw new \Exception('$pageCallback must be a non-null string representing a callback function !');
  281. }
  282. $this->pageCallback = $pageCallback;
  283. return $this;
  284. }
  285. /**
  286. * The bitmask of flags describing properties of the menu item.
  287. *
  288. * Specific setters are provided here for these.
  289. *
  290. * From hook_menu(): '"type":
  291. * A bitmask of flags describing properties of the menu item.
  292. *
  293. * 'Many shortcut bitmasks are provided as constants in menu.inc:
  294. *
  295. * - MENU_NORMAL_ITEM: Normal menu items show up in the menu tree
  296. * and can be moved/hidden by the administrator.
  297. * - MENU_CALLBACK: Callbacks simply register a path so that the
  298. * correct information is generated when the path is accessed.
  299. * - MENU_SUGGESTED_ITEM: Modules may "suggest" menu items
  300. * that the administrator may enable.
  301. * - MENU_LOCAL_ACTION: Local actions are menu items that describe
  302. * actions on the parent item such as adding a new user or block,
  303. * and are rendered in the action-links list in your theme.
  304. * - MENU_LOCAL_TASK: Local tasks are menu items that describe
  305. * different displays of data, and are generally rendered as tabs.
  306. * - MENU_DEFAULT_LOCAL_TASK: Every set of local tasks should
  307. * provide one "default" task, which should display the same page
  308. * as the parent item.
  309. *
  310. * If the "type" element is omitted, MENU_NORMAL_ITEM is assumed.'
  311. *
  312. * Visit also
  313. * @link https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_menu/7 Menu item types @endlink
  314. *
  315. * @var int
  316. */
  317. private $type = MENU_NORMAL_ITEM;
  318. /**
  319. * Sets the bitmask of flags describing properties of the menu item.
  320. *
  321. * Specific setters are provided here for all of these.
  322. *
  323. * From hook_menu():
  324. * '"type": A bitmask of flags describing properties of the menu item.'
  325. *
  326. * 'Many shortcut bitmasks are provided as constants in menu.inc:
  327. *
  328. * - MENU_NORMAL_ITEM: Normal menu items show up in the menu tree
  329. * and can be moved/hidden by the administrator .
  330. * - MENU_CALLBACK: Callbacks simply register a path so that the
  331. * correct information is generated when the path is accessed.
  332. * - MENU_SUGGESTED_ITEM: Modules may "suggest" menu items
  333. * that the administrator may enable.
  334. * - MENU_LOCAL_ACTION: Local actions are menu items that describe
  335. * actions on the parent item such as adding a new user or block,
  336. * and are rendered in the action-links list in your theme.
  337. * - MENU_LOCAL_TASK: Local tasks are menu items that describe
  338. * different displays of data, and are generally rendered as tabs.
  339. * - MENU_DEFAULT_LOCAL_TASK: Every set of local tasks should
  340. * provide one "default" task, which should display the same page
  341. * as the parent item.
  342. *
  343. * If the "type" element is omitted, MENU_NORMAL_ITEM is assumed.'
  344. *
  345. * Visit also
  346. * @link https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_menu/7 Menu item types @endlink
  347. *
  348. * @todo Check against valid Drupal menu item bitmask combinations.
  349. *
  350. * @param int $typeBitmask
  351. * A non empty type bitmask that is a valid
  352. * combination of Drupal menu bitmask types.
  353. *
  354. * @return IMenuItem
  355. * This.
  356. */
  357. final public function setType($typeBitmask = MENU_NORMAL_ITEM) {
  358. if (empty($typeBitmask) || !is_int($typeBitmask)) {
  359. throw new \Exception('The $typeBitmask' . "($typeBitmask)" . ' is not a valid bitmask combination');
  360. }
  361. $this->type = $typeBitmask;
  362. return $this;
  363. }
  364. /**
  365. * Sets the menu type to be a MENU_DEFAULT_LOCAL_TASK (if TRUE).
  366. *
  367. * If TRUE, sets the menu type to be a MENU_DEFAULT_LOCAL_TASK
  368. * the first (default) of a set of menu tabs,
  369. * or reverts to a MENU_NORMAL_ITEM if FALSE.
  370. *
  371. * From hook_menu(): 'MENU_DEFAULT_LOCAL_TASK: Every set of local tasks
  372. * should provide one "default" task, which should display the same
  373. * page as the parent item'.
  374. *
  375. * @param bool $isTypeDefaultLocalTask
  376. * Whether the type should be set to MENU_DEFAULT_LOCAL_TASK.
  377. *
  378. * @return IMenuItem
  379. * This.
  380. */
  381. final public function setTypeDefaultLocalTask($isTypeDefaultLocalTask = TRUE) {
  382. if (!is_bool($isTypeDefaultLocalTask)) {
  383. throw new \Exception('$isTypeDefaultLocalTask must be a bool !');
  384. }
  385. if ($isTypeDefaultLocalTask) {
  386. $this->type = MENU_DEFAULT_LOCAL_TASK;
  387. }
  388. else {
  389. $this->type = MENU_NORMAL_ITEM;
  390. }
  391. return $this;
  392. }
  393. /**
  394. * Sets the menu type to be a MENU_LOCAL_TASK (if TRUE).
  395. *
  396. * If TRUE, sets the menu type to be a MENU_LOCAL_TASK,
  397. * one of a set of menu tabs,
  398. * or reverts to a MENU_NORMAL_ITEM if FALSE.
  399. *
  400. * From hook_menu():
  401. * 'MENU_LOCAL_TASK: Local tasks are menu items that describe
  402. * different displays of data, and are generally rendered as tabs.'
  403. *
  404. * @param bool $isTypeLocalTask
  405. * Whether the type should be set to MENU_LOCAL_TASK.
  406. *
  407. * @return IMenuItem
  408. * This.
  409. */
  410. final public function setTypeLocalTask($isTypeLocalTask = TRUE) {
  411. if (!is_bool($isTypeLocalTask)) {
  412. throw new \Exception('$isTypeLocalTask must be a bool !');
  413. }
  414. if ($isTypeLocalTask) {
  415. $this->type = MENU_LOCAL_TASK;
  416. }
  417. else {
  418. $this->type = MENU_NORMAL_ITEM;
  419. }
  420. return $this;
  421. }
  422. /**
  423. * Sets the menu type to be a MENU_LOCAL_ACTION (if TRUE).
  424. *
  425. * If TRUE, sets the menu type to be a MENU_LOCAL_ACTION,
  426. * one of a set of menu tabs,
  427. * or reverts to a MENU_NORMAL_ITEM if FALSE.
  428. *
  429. * From hook_menu():
  430. * 'MENU_LOCAL_ACTION: Local actions are menu items that describe
  431. * actions on the parent item such as adding a new user or block,
  432. * and are rendered in the action-links list in your theme.'
  433. *
  434. * @param bool $isTypeLocalAction
  435. * Whether the type should be set to MENU_LOCAL_ACTION.
  436. *
  437. * @return IMenuItem
  438. * This.
  439. */
  440. final public function setTypeLocalAction($isTypeLocalAction = TRUE) {
  441. if (!is_bool($isTypeLocalAction)) {
  442. throw new \Exception('$isTypeLocalAction must be a bool !');
  443. }
  444. if ($isTypeLocalAction) {
  445. $this->type = MENU_LOCAL_ACTION;
  446. }
  447. else {
  448. $this->type = MENU_NORMAL_ITEM;
  449. }
  450. return $this;
  451. }
  452. /**
  453. * Sets the menu type to be a MENU_SUGGESTED_ITEM (if TRUE).
  454. *
  455. * If TRUE, sets the menu type to be a MENU_SUGGESTED_ITEM,
  456. * or reverts to a MENU_NORMAL_ITEM if FALSE.
  457. *
  458. * From hook_menu(): 'MENU_SUGGESTED_ITEM: Modules may "suggest"
  459. * menu items that the administrator may enable.'
  460. *
  461. * From MENU_SUGGESTED_ITEM:
  462. * 'They act just as callbacks do until enabled,
  463. * at which time they act like normal items.'
  464. *
  465. * @param bool $isTypeSuggestedItem
  466. * Whether the type should be set to MENU_SUGGESTED_ITEM.
  467. *
  468. * @return IMenuItem
  469. * This.
  470. */
  471. final public function setTypeSuggestedItem($isTypeSuggestedItem = TRUE) {
  472. if (!is_bool($isTypeSuggestedItem)) {
  473. throw new \Exception('$isTypeSuggestedItem must be a bool !');
  474. }
  475. if ($isTypeSuggestedItem) {
  476. $this->type = MENU_SUGGESTED_ITEM;
  477. }
  478. else {
  479. $this->type = MENU_NORMAL_ITEM;
  480. }
  481. return $this;
  482. }
  483. /**
  484. * Sets the menu type to be a MENU_NORMAL_ITEM menu item (if TRUE).
  485. *
  486. * If TRUE, sets the menu type to be a MENU_NORMAL_ITEM menu item;
  487. * Ignored if FALSE.
  488. *
  489. * From hook_menu():
  490. * 'MENU_NORMAL_ITEM: Normal menu items show up in the menu tree
  491. * and can be moved/hidden by the administrator.'
  492. *
  493. * @param bool $isTypeNormal
  494. * Whether the type should be set to MENU_NORMAL_ITEM.
  495. *
  496. * @return IMenuItem
  497. * This.
  498. */
  499. final public function setTypeNormal($isTypeNormal = TRUE) {
  500. if (!is_bool($isTypeNormal)) {
  501. throw new \Exception('$isTypeNormal must be a bool !');
  502. }
  503. if ($isTypeNormal) {
  504. $this->type = MENU_NORMAL_ITEM;
  505. }
  506. //else $this->type = MENU_NORMAL_ITEM; //IGNORE
  507. return $this;
  508. }
  509. /**
  510. * Sets the menu type to be a MENU_CALLBACK menu item (if TRUE).
  511. *
  512. * If TRUE, sets the menu type to be a MENU_CALLBACK menu item;
  513. * Ignored if FALSE.
  514. *
  515. * From hook_menu(): 'MENU_CALLBACK: Callbacks simply
  516. * register a path so that the
  517. * correct information is generated when the path is accessed.'
  518. *
  519. * @param bool $isTypeCallback
  520. * Whether the type should be set to MENU_CALLBACK.
  521. *
  522. * @return IMenuItem
  523. * This.
  524. */
  525. final public function setTypeCallback($isTypeCallback = TRUE) {
  526. if (!is_bool($isTypeCallback)) {
  527. throw new \Exception('$isTypeCallback must be a bool !');
  528. }
  529. if ($isTypeCallback) {
  530. $this->type = MENU_CALLBACK;
  531. }
  532. //else $this->type = MENU_CALLBACK; //IGNORE
  533. return $this;
  534. }
  535. /**
  536. * Builds and returns a valid Drupal menu item array for hook_menu().
  537. *
  538. * @return array
  539. * A valid Drupal menu item array for hook_menu().
  540. */
  541. public function get() {
  542. $get = array(
  543. 'title' => $this->title,
  544. 'page callback' => $this->pageCallback,
  545. 'type' => $this->type,
  546. );
  547. if (!empty($this->accessArguments)) {
  548. $get['access arguments'] = $this->accessArguments;
  549. }
  550. if (!empty($this->accessCallback)) {
  551. $get['access callback'] = $this->accessCallback;
  552. }
  553. if (!empty($this->weight)) {
  554. $get['weight'] = $this->weight;
  555. }
  556. if (!empty($this->isExpanded)) {
  557. $get['expanded'] = $this->isExpanded;
  558. }
  559. if (!empty($this->menuName)) {
  560. $get['menu_name'] = $this->menuName;
  561. }
  562. if (!empty($this->description)) {
  563. $get['description'] = $this->description;
  564. }
  565. $pageArgsTmp = $this->getPageArgumentsDecorated();
  566. //dpm($pageArgsTmp,'pageArgTmp');//DEBUG
  567. //dpr($pageArgsTmp,'pageArgTmp');
  568. if (!empty($pageArgsTmp)) {
  569. $get['page arguments'] = $pageArgsTmp;
  570. }
  571. //dpm($get,'DefaultMenuItem:get');//DEBUG
  572. return $get;
  573. }
  574. /**
  575. * By default just the pageArguments as set, if any.
  576. *
  577. * Can be overridden for special cases to insert additional args
  578. * (such as needed for page controller menu items).
  579. *
  580. * @return array
  581. * The page arguments (possibly decorated).
  582. */
  583. protected function getPageArgumentsDecorated() {
  584. return $this->pageArguments;
  585. }
  586. /**
  587. * An integer that determines the relative position of items in the menu.
  588. *
  589. * From hook_menu():
  590. * '"weight": An integer that determines the relative position of items
  591. * in the menu; higher-weighted items sink. Defaults to 0. Menu items
  592. * with the same weight are ordered alphabetically.'
  593. *
  594. * @var int
  595. */
  596. private $weight;
  597. /**
  598. * Sets the menu item weight.
  599. *
  600. * From hook_menu();
  601. * '"weight": An integer that determines the relative position of items
  602. * in the menu; higher-weighted items sink. Defaults to 0.
  603. * Menu items with the same weight are ordered alphabetically.'
  604. *
  605. * @param int $weight
  606. * An integer that determines the relative position of items in the menu
  607. *
  608. * @return IMenuItem
  609. * This.
  610. */
  611. final public function setWeight($weight) {
  612. if (!is_int($weight)) {
  613. throw new \Exception('$weight must be an integer !');
  614. }
  615. $this->weight = $weight;
  616. return $this;
  617. }
  618. /**
  619. * The name of a custom menu this should appear in.
  620. *
  621. * Only required to be set if other than the Navigation menu.
  622. *
  623. * From hook_menu():
  624. * 'Optional. Set this to a custom menu if you
  625. * don't want your item to be placed in Navigation.' *
  626. *
  627. * @var string
  628. */
  629. private $menuName;
  630. /**
  631. * The machine name of the menu for this.
  632. *
  633. * From hook_menu(): 'Optional. Set this to a custom menu
  634. * if you don't want your item to be placed in Navigation.'
  635. *
  636. * CAUTION: this is only safe to use if the
  637. * name of an already created menu is known !
  638. *
  639. * @todo Query database to check whether this is a valid, existing menu name.
  640. *
  641. * @param string $menuName
  642. * The name of a custom menu (other than Navigation) this should appear in.
  643. *
  644. * @return IMenuItem
  645. * This.
  646. */
  647. final public function setMenuName($menuName) {
  648. if (empty($menu_name) || !is_string($menuName)) {
  649. throw new \Exception('$menuName must be a non empty string !');
  650. }
  651. $this->menuName = $menuName;
  652. return $this;
  653. }
  654. /**
  655. * Whether the menu item is expanded.
  656. *
  657. * From hook_menu():
  658. * 'Optional. If set to TRUE, and if a menu link is provided for this menu
  659. * item
  660. * (as a result of other properties), then the menu link is always expanded,
  661. * equivalent to its 'always expanded' checkbox being set in the UI.'
  662. *
  663. * @var bool
  664. */
  665. private $isExpanded;
  666. /**
  667. * Sets whether the menu item is expanded.
  668. *
  669. * From hook_menu():
  670. * 'Optional. If set to TRUE, and if a menu link
  671. * is provided for this menu item
  672. * (as a result of other properties), then the menu link is always expanded,
  673. * equivalent to its 'always expanded' checkbox being set in the UI.'
  674. *
  675. * @param bool $isExpanded
  676. * Whether the menu item is expanded.
  677. * @return IMenuItem
  678. * This.
  679. */
  680. final public function setExpanded($isExpanded) {
  681. if (!is_bool($isExpanded)) {
  682. throw new \Exception('$isExpanded must be a bool !');
  683. }
  684. $this->isExpanded = $isExpanded;
  685. return $this;
  686. }
  687. }

Classes

Namesort descending Description
DefaultMenuItem Default implementation of a menu item (without a page or form controller).