123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- <?php
- /**
- * @package Grav\Common
- *
- * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
- * @license MIT License; see LICENSE file for details.
- */
- namespace Grav\Common;
- use Grav\Common\Config\Config;
- use Grav\Common\Page\Collection;
- use Grav\Common\Page\Interfaces\PageInterface;
- /**
- * The Taxonomy object is a singleton that holds a reference to a 'taxonomy map'. This map is
- * constructed as a multidimensional array.
- *
- * uses the taxonomy defined in the site.yaml file and is built when the page objects are recursed.
- * Basically every time a page is found that has taxonomy references, an entry to the page is stored in
- * the taxonomy map. The map has the following format:
- *
- * [taxonomy_type][taxonomy_value][page_path]
- *
- * For example:
- *
- * [category][blog][path/to/item1]
- * [tag][grav][path/to/item1]
- * [tag][grav][path/to/item2]
- * [tag][dog][path/to/item3]
- */
- class Taxonomy
- {
- protected $taxonomy_map;
- protected $grav;
- /**
- * Constructor that resets the map
- *
- * @param Grav $grav
- */
- public function __construct(Grav $grav)
- {
- $this->taxonomy_map = [];
- $this->grav = $grav;
- }
- /**
- * Takes an individual page and processes the taxonomies configured in its header. It
- * then adds those taxonomies to the map
- *
- * @param PageInterface $page the page to process
- * @param array $page_taxonomy
- */
- public function addTaxonomy(PageInterface $page, $page_taxonomy = null)
- {
- if (!$page_taxonomy) {
- $page_taxonomy = $page->taxonomy();
- }
- if (empty($page_taxonomy) || !$page->published()) {
- return;
- }
- /** @var Config $config */
- $config = $this->grav['config'];
- if ($config->get('site.taxonomies')) {
- foreach ((array)$config->get('site.taxonomies') as $taxonomy) {
- if (isset($page_taxonomy[$taxonomy])) {
- foreach ((array)$page_taxonomy[$taxonomy] as $item) {
- $this->taxonomy_map[$taxonomy][(string)$item][$page->path()] = ['slug' => $page->slug()];
- }
- }
- }
- }
- }
- /**
- * Returns a new Page object with the sub-pages containing all the values set for a
- * particular taxonomy.
- *
- * @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
- * @param string $operator can be 'or' or 'and' (defaults to 'and')
- *
- * @return Collection Collection object set to contain matches found in the taxonomy map
- */
- public function findTaxonomy($taxonomies, $operator = 'and')
- {
- $matches = [];
- $results = [];
- foreach ((array)$taxonomies as $taxonomy => $items) {
- foreach ((array)$items as $item) {
- if (isset($this->taxonomy_map[$taxonomy][$item])) {
- $matches[] = $this->taxonomy_map[$taxonomy][$item];
- } else {
- $matches[] = [];
- }
- }
- }
- if (strtolower($operator) === 'or') {
- foreach ($matches as $match) {
- $results = array_merge($results, $match);
- }
- } else {
- $results = $matches ? array_pop($matches) : [];
- foreach ($matches as $match) {
- $results = array_intersect_key($results, $match);
- }
- }
- return new Collection($results, ['taxonomies' => $taxonomies]);
- }
- /**
- * Gets and Sets the taxonomy map
- *
- * @param array $var the taxonomy map
- *
- * @return array the taxonomy map
- */
- public function taxonomy($var = null)
- {
- if ($var) {
- $this->taxonomy_map = $var;
- }
- return $this->taxonomy_map;
- }
- /**
- * Gets item keys per taxonomy
- *
- * @param string $taxonomy taxonomy name
- *
- * @return array keys of this taxonomy
- */
- public function getTaxonomyItemKeys($taxonomy)
- {
- return isset($this->taxonomy_map[$taxonomy]) ? array_keys($this->taxonomy_map[$taxonomy]) : [];
- }
- }
|