TreeIterator.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Collection\Iterator;
  16. use Cake\Collection\CollectionTrait;
  17. use RecursiveIterator;
  18. use RecursiveIteratorIterator;
  19. /**
  20. * A Recursive iterator used to flatten nested structures and also exposes
  21. * all Collection methods
  22. */
  23. class TreeIterator extends RecursiveIteratorIterator
  24. {
  25. use CollectionTrait;
  26. /**
  27. * The iteration mode
  28. *
  29. * @var int
  30. */
  31. protected $_mode;
  32. /**
  33. * Constructor
  34. *
  35. * @param \RecursiveIterator $items The iterator to flatten.
  36. * @param int $mode Iterator mode.
  37. * @param int $flags Iterator flags.
  38. */
  39. public function __construct(RecursiveIterator $items, $mode = RecursiveIteratorIterator::SELF_FIRST, $flags = 0)
  40. {
  41. parent::__construct($items, $mode, $flags);
  42. $this->_mode = $mode;
  43. }
  44. /**
  45. * Returns another iterator which will return the values ready to be displayed
  46. * to a user. It does so by extracting one property from each of the elements
  47. * and prefixing it with a spacer so that the relative position in the tree
  48. * can be visualized.
  49. *
  50. * Both $valuePath and $keyPath can be a string with a property name to extract
  51. * or a dot separated path of properties that should be followed to get the last
  52. * one in the path.
  53. *
  54. * Alternatively, $valuePath and $keyPath can be callable functions. They will get
  55. * the current element as first parameter, the current iteration key as second
  56. * parameter, and the iterator instance as third argument.
  57. *
  58. * ### Example
  59. *
  60. * ```
  61. * $printer = (new Collection($treeStructure))->listNested()->printer('name');
  62. * ```
  63. *
  64. * Using a closure:
  65. *
  66. * ```
  67. * $printer = (new Collection($treeStructure))
  68. * ->listNested()
  69. * ->printer(function ($item, $key, $iterator) {
  70. * return $item->name;
  71. * });
  72. * ```
  73. *
  74. * @param string|callable $valuePath The property to extract or a callable to return
  75. * the display value
  76. * @param string|callable|null $keyPath The property to use as iteration key or a
  77. * callable returning the key value.
  78. * @param string $spacer The string to use for prefixing the values according to
  79. * their depth in the tree
  80. * @return \Cake\Collection\Iterator\TreePrinter
  81. */
  82. public function printer($valuePath, $keyPath = null, $spacer = '__')
  83. {
  84. if (!$keyPath) {
  85. $counter = 0;
  86. $keyPath = function () use (&$counter) {
  87. return $counter++;
  88. };
  89. }
  90. return new TreePrinter(
  91. $this->getInnerIterator(),
  92. $valuePath,
  93. $keyPath,
  94. $spacer,
  95. $this->_mode
  96. );
  97. }
  98. }