Taxonomy.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Grav\Common;
  3. use Grav\Common\Config\Config;
  4. use Grav\Common\Page\Collection;
  5. use Grav\Common\Page\Page;
  6. /**
  7. * The Taxonomy object is a singleton that holds a reference to a 'taxonomy map'. This map is
  8. * constructed as a multidimensional array.
  9. *
  10. * uses the taxonomy defined in the site.yaml file and is built when the page objects are recursed.
  11. * Basically every time a page is found that has taxonomy references, an entry to the page is stored in
  12. * the taxonomy map. The map has the following format:
  13. *
  14. * [taxonomy_type][taxonomy_value][page_path]
  15. *
  16. * For example:
  17. *
  18. * [category][blog][path/to/item1]
  19. * [tag][grav][path/to/item1]
  20. * [tag][grav][path/to/item2]
  21. * [tag][dog][path/to/item3]
  22. *
  23. * @author RocketTheme
  24. * @license MIT
  25. */
  26. class Taxonomy
  27. {
  28. protected $taxonomy_map;
  29. protected $grav;
  30. /**
  31. * Constructor that resets the map
  32. */
  33. public function __construct(Grav $grav)
  34. {
  35. $this->taxonomy_map = array();
  36. $this->grav = $grav;
  37. }
  38. /**
  39. * Takes an individual page and processes the taxonomies configured in its header. It
  40. * then adds those taxonomies to the map
  41. *
  42. * @param Page $page the page to process
  43. * @param array $page_taxonomy
  44. */
  45. public function addTaxonomy(Page $page, $page_taxonomy = null)
  46. {
  47. if (!$page_taxonomy) {
  48. $page_taxonomy = $page->taxonomy();
  49. }
  50. if (!$page->published() || empty($page_taxonomy)) {
  51. return;
  52. }
  53. /** @var Config $config */
  54. $config = $this->grav['config'];
  55. if ($config->get('site.taxonomies')) {
  56. foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
  57. if (isset($page_taxonomy[$taxonomy])) {
  58. foreach ((array) $page_taxonomy[$taxonomy] as $item) {
  59. $this->taxonomy_map[$taxonomy][(string) $item][$page->path()] = array('slug' => $page->slug());
  60. }
  61. }
  62. }
  63. }
  64. }
  65. /**
  66. * Returns a new Page object with the sub-pages containing all the values set for a
  67. * particular taxonomy.
  68. *
  69. * @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
  70. * @param string $operator can be 'or' or 'and' (defaults to 'or')
  71. * @return Collection Collection object set to contain matches found in the taxonomy map
  72. */
  73. public function findTaxonomy($taxonomies, $operator = 'and')
  74. {
  75. $matches = [];
  76. $results = [];
  77. foreach ((array)$taxonomies as $taxonomy => $items) {
  78. foreach ((array) $items as $item) {
  79. if (isset($this->taxonomy_map[$taxonomy][$item])) {
  80. $matches[] = $this->taxonomy_map[$taxonomy][$item];
  81. }
  82. }
  83. }
  84. if (strtolower($operator) == 'or') {
  85. foreach ($matches as $match) {
  86. $results = array_merge($results, $match);
  87. }
  88. } else {
  89. $results = $matches ? array_pop($matches) : [];
  90. foreach ($matches as $match) {
  91. $results = array_intersect_key($results, $match);
  92. }
  93. }
  94. return new Collection($results, ['taxonomies' => $taxonomies]);
  95. }
  96. /**
  97. * Gets and Sets the taxonomy map
  98. *
  99. * @param array $var the taxonomy map
  100. * @return array the taxonomy map
  101. */
  102. public function taxonomy($var = null)
  103. {
  104. if ($var) {
  105. $this->taxonomy_map = $var;
  106. }
  107. return $this->taxonomy_map;
  108. }
  109. }