/** * Create and initialize pagination. * * @param Collection $collection */ public function __construct(Collection $collection) { require_once __DIR__ . '/paginationpage.php'; /** @var Uri $uri */ $uri = self::getGrav()['uri']; $config = self::getGrav()['config']; $this->current = $uri->currentPage(); // get params $url_params = explode('/', ltrim($uri->params(), '/')); foreach ($url_params as $key => $value) { if (strpos($value, 'page' . $config->get('system.param_sep')) !== false) { unset($url_params[$key]); } } $this->url_params = '/' . implode('/', $url_params); // check for empty params if ($this->url_params == '/') { $this->url_params = ''; } $params = $collection->params(); $this->items_per_page = $params['limit']; $this->page_count = ceil($collection->count() / $this->items_per_page); for ($x = 1; $x <= $this->page_count; $x++) { $this->items[$x] = new PaginationPage($x, '/page' . $config->get('system.param_sep') . $x); } }
/** * Display random page. */ public function onPageInitialized() { /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $filters = (array) $this->config->get('plugins.comic.filters'); $operator = $this->config->get('plugins.comic.filter_combinator', 'and'); if (count($filters)) { $collection = new Collection(); $collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray()); if (count($collection)) { unset($this->grav['page']); $page = $collection->random()->current(); if ($this->config->get('plugins.comic.redirect', true)) { $this->grav->redirect($page->url(true)); } else { // override the modified time $page->modified(time()); $this->grav['page'] = $page; // Convince the URI object that it is this random page... $uri = $this->grav['uri']; $uri->url = $uri->base() . $page->url(); $uri->init(); } } } }
/** * Set needed variables to display breadcrumbs. */ public function onTwigSiteVariables() { /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $pages = $this->grav['pages']; // Get current datetime $start_date = time(); $archives = array(); // get the plugin filters setting $filters = (array) $this->config->get('plugins.archives.filters'); $operator = $this->config->get('plugins.archives.filter_combinator'); if (count($filters) > 0) { $collection = new Collection(); $collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray()); // reorder the collection based on settings $collection = $collection->order($this->config->get('plugins.archives.order.by'), $this->config->get('plugins.archives.order.dir')); $date_format = $this->config->get('plugins.archives.date_display_format'); // loop over new collection of pages that match filters foreach ($collection as $page) { // update the start date if the page date is older $start_date = $page->date() < $start_date ? $page->date() : $start_date; $archives[date($date_format, $page->date())][] = $page; } } // slice the array to the limit you want $archives = array_slice($archives, 0, intval($this->config->get('plugins.archives.limit'))); // add the archives_start date to the twig variables $this->grav['twig']->twig_vars['archives_show_count'] = $this->config->get('plugins.archives.show_count'); $this->grav['twig']->twig_vars['archives_data'] = $archives; }
/** Build a collection of pages that belong to the same group*/ private function buildGroupCollection($config) { // use taxonomy to build the collection $taxonomy = $this->grav['taxonomy']; $filters = (array) $config->get('filters'); $operator = $config->get('filter_combinator', 'or'); $collection = new Collection(); $collection->append($taxonomy->findTaxonomy($filters, $operator)->toArray()); // use a configured sorting order $collection = $collection->order($config->get('order.by'), $config->get('order.dir')); return $collection; }
/** * Build search results. */ public function onPagesInitialized() { /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $filters = (array) $this->config->get('plugins.simplesearch.filters'); $operator = $this->config->get('plugins.simplesearch.filter_combinator', 'and'); $this->collection = new Collection(); $this->collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray()); /** @var Page $page */ foreach ($this->collection as $page) { foreach ($this->query as $query) { $query = trim($query); if (stripos($page->content(), $query) === false && stripos($page->title(), $query) === false) { $this->collection->remove($page); } } } }
/** * Build search results. */ public function onPagesInitialized() { /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $filters = (array) $this->config->get('plugins.simplesearch.filters'); $operator = $this->config->get('plugins.simplesearch.filter_combinator', 'and'); $this->collection = new Collection(); $this->collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray()); $extras = []; /** @var Page $page */ foreach ($this->collection as $page) { foreach ($this->query as $query) { $query = trim($query); if (stripos($page->content(), $query) === false && stripos($page->title(), $query) === false) { $this->collection->remove($page); continue; } if ($page->modular()) { $this->collection->remove($page); $parent = $page->parent(); $extras[$parent->path()] = ['slug' => $parent->slug()]; } } } if (!empty($extras)) { $this->collection->append($extras); } // use a configured sorting order $this->collection = $this->collection->order($this->config->get('order.by'), $this->config->get('order.dir')); // create the search page $page = new Page(); $page->init(new \SplFileInfo(__DIR__ . '/pages/simplesearch.md')); // override the template is set in the config $template_override = $this->config->get('plugins.simplesearch.template'); if ($template_override) { $page->template($template_override); } // allows us to redefine the page service without triggering RuntimeException: Cannot override frozen service // "page" issue unset($this->grav['page']); $this->grav['page'] = $page; }
/** * @param string $value * * @return mixed * @internal */ protected function evaluate($value) { // Parse command. if (is_string($value)) { // Format: @command.param $cmd = $value; $params = array(); } elseif (is_array($value) && count($value) == 1 && !is_int(key($value))) { // Format: @command.param: { attr1: value1, attr2: value2 } $cmd = (string) key($value); $params = (array) current($value); } else { $result = []; foreach ($value as $key => $val) { if (is_int($key)) { $result = $result + $this->evaluate($val)->toArray(); } else { $result = $result + $this->evaluate([$key => $val])->toArray(); } } return new Collection($result); } // We only evaluate commands which start with @ if (empty($cmd) || $cmd[0] != '@') { return $value; } /** @var Pages $pages */ $pages = self::getGrav()['pages']; $parts = explode('.', $cmd); $current = array_shift($parts); $results = new Collection(); switch ($current) { case '@self': if (!empty($parts)) { switch ($parts[0]) { case 'modular': // @self.modular: false (alternative to @self.children) if (!empty($params) && $params[0] === false) { $results = $this->children()->nonModular(); break; } $results = $this->children()->modular(); break; case 'children': $results = $this->children()->nonModular(); break; case 'parent': $collection = new Collection(); $results = $collection->addPage($this->parent()); break; case 'siblings': $results = $this->parent()->children()->remove($this->path()); break; case 'descendants': $results = $pages->all($this)->remove($this->path())->nonModular(); break; } } $results = $results->published(); break; case '@page': $page = null; if (!empty($params)) { $page = $this->find($params[0]); } // safety check in case page is not found if (!isset($page)) { return $results; } // Handle a @page.descendants if (!empty($parts)) { switch ($parts[0]) { case 'self': $results = new Collection(); $results = $results->addPage($page); break; case 'descendants': $results = $pages->all($page)->remove($page->path()); break; case 'children': $results = $page->children(); break; } } else { $results = $page->children(); } $results = $results->nonModular()->published(); break; case '@root': if (!empty($parts) && $parts[0] == 'descendants') { $results = $pages->all($pages->root())->nonModular()->published(); } else { $results = $pages->root()->children()->nonModular()->published(); } break; case '@taxonomy': // Gets a collection of pages by using one of the following formats: // @taxonomy.category: blog // @taxonomy.category: [ blog, featured ] // @taxonomy: { category: [ blog, featured ], level: 1 } /** @var Taxonomy $taxonomy_map */ $taxonomy_map = self::getGrav()['taxonomy']; if (!empty($parts)) { $params = [implode('.', $parts) => $params]; } $results = $taxonomy_map->findTaxonomy($params)->published(); break; } return $results; }
/** * Get all pages * * @param \Grav\Common\Page\Page $current * @return \Grav\Common\Page\Collection */ public function all(Page $current = null) { $all = new Collection(); $current = $current ?: $this->root(); if ($current->routable()) { $all[$current->path()] = ['slug' => $current->slug()]; } foreach ($current->children() as $next) { $all->append($this->all($next)); } return $all; }
/** * Set needed variables to display breadcrumbs. */ public function onTwigSiteVariables() { $page = $this->grav['page']; // If a page exists merge the configs if ($page) { $this->config->set('plugins.archives', $this->mergeConfig($page)); } /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $taxonomies = []; $find_taxonomy = []; $pages = $this->grav['pages']; // Get current datetime $start_date = time(); $archives = array(); // get the plugin filters setting $filters = (array) $this->config->get('plugins.archives.filters'); $operator = $this->config->get('plugins.archives.filter_combinator'); $new_approach = false; $collection = null; if (!$filters || count($filters) == 1 && !reset($filters)) { $collection = $pages->all(); } else { foreach ($filters as $key => $filter) { // flatten item if it's wrapped in an array if (is_int($key)) { if (is_array($filter)) { $key = key($filter); $filter = $filter[$key]; } else { $key = $filter; } } // see if the filter uses the new 'items-type' syntax if ($key === '@self' || $key === 'self@') { $new_approach = true; } elseif ($key === '@taxonomy' || $key === 'taxonomy@') { $taxonomies = $filter === false ? false : array_merge($taxonomies, (array) $filter); } else { $find_taxonomy[$key] = $filter; } } if ($new_approach) { $collection = $page->children(); } else { $collection = new Collection(); $collection->append($taxonomy_map->findTaxonomy($find_taxonomy, $operator)->toArray()); } } // reorder the collection based on settings $collection = $collection->order($this->config->get('plugins.archives.order.by'), $this->config->get('plugins.archives.order.dir')); $date_format = $this->config->get('plugins.archives.date_display_format'); // loop over new collection of pages that match filters foreach ($collection as $page) { // update the start date if the page date is older $start_date = $page->date() < $start_date ? $page->date() : $start_date; $archives[date($date_format, $page->date())][] = $page; } // slice the array to the limit you want $archives = array_slice($archives, 0, intval($this->config->get('plugins.archives.limit')), is_string(reset($archives)) ? false : true); // add the archives_start date to the twig variables $this->grav['twig']->twig_vars['archives_show_count'] = $this->config->get('plugins.archives.show_count'); $this->grav['twig']->twig_vars['archives_data'] = $archives; }
/** * Build search results. */ public function onPagesInitialized() { $page = $this->grav['page']; // If a page exists merge the configs if ($page) { $this->config->set('plugins.simplesearch', $this->mergeConfig($page)); } /** @var Uri $uri */ $uri = $this->grav['uri']; $query = $uri->param('query') ?: $uri->query('query'); $route = $this->config->get('plugins.simplesearch.route'); // performance check if ($route && $query && $route == $uri->path()) { $this->enable(['onTwigSiteVariables' => ['onTwigSiteVariables', 0]]); } else { return; } $this->query = explode(',', $query); /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $taxonomies = []; $filters = (array) $this->config->get('plugins.simplesearch.filters'); $operator = $this->config->get('plugins.simplesearch.filter_combinator', 'and'); // see if the filter uses the new 'items-type' syntax $new_approach = false; foreach ($filters as $filter) { $filter_saved = $filter; if (is_array($filter)) { $filter = key($filter); } if (Utils::startsWith($filter, '@')) { if ($filter == '@self') { $new_approach = true; } if ($filter == '@taxonomy') { $taxonomies = $filter_saved[$filter]; } } } if ($new_approach) { $params = $page->header()->content; $params['query'] = $this->config->get('plugins.simplesearch.query'); $this->collection = $page->collection($params, false); } else { $this->collection = new Collection(); $this->collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray()); } $extras = []; /** @var Page $cpage */ foreach ($this->collection as $cpage) { foreach ($this->query as $query) { $query = trim($query); $taxonomy_match = false; if (!empty($taxonomies)) { $page_taxonomies = $cpage->taxonomy(); foreach ((array) $taxonomies as $taxonomy) { if (array_key_exists($taxonomy, $page_taxonomies)) { $taxonomy_values = implode('|', $page_taxonomies[$taxonomy]); if (stripos($taxonomy_values, $query) !== false) { $taxonomy_match = true; break; } } } } if ($taxonomy_match === false && stripos($cpage->content(), $query) === false && stripos($cpage->title(), $query) === false) { $this->collection->remove($cpage); continue; } if ($cpage->modular()) { $this->collection->remove($cpage); $parent = $cpage->parent(); $extras[$parent->path()] = ['slug' => $parent->slug()]; } } } if (!empty($extras)) { $this->collection->append($extras); } // use a configured sorting order if not already done if (!$new_approach) { $this->collection = $this->collection->order($this->config->get('plugins.simplesearch.order.by'), $this->config->get('plugins.simplesearch.order.dir')); } // if page doesn't have settings set, create a page if (!isset($page->header()->simplesearch)) { // create the search page $page = new Page(); $page->init(new \SplFileInfo(__DIR__ . '/pages/simplesearch.md')); // override the template is set in the config $template_override = $this->config->get('plugins.simplesearch.template'); if ($template_override) { $page->template($template_override); } // fix RuntimeException: Cannot override frozen service "page" issue unset($this->grav['page']); $this->grav['page'] = $page; } }
/** * Get a collection of pages in the current context. * * @param string|array $params * @param boolean $pagination * @return Collection * @throws \InvalidArgumentException */ public function collection($params = 'content', $pagination = true) { if (is_string($params)) { $params = (array) $this->value('header.' . $params); } elseif (!is_array($params)) { throw new \InvalidArgumentException('Argument should be either header variable name or array of parameters'); } if (!isset($params['items'])) { return array(); } $collection = $this->evaluate($params['items']); if (!$collection instanceof Collection) { $collection = new Collection(); } $collection->setParams($params); // TODO: MOVE THIS INTO SOMEWHERE ELSE? /** @var Uri $uri */ $uri = self::getGrav()['uri']; /** @var Config $config */ $config = self::getGrav()['config']; foreach ((array) $config->get('site.taxonomies') as $taxonomy) { if ($uri->param($taxonomy)) { $items = explode(',', $uri->param($taxonomy)); $collection->setParams(['taxonomies' => [$taxonomy => $items]]); foreach ($collection as $page) { if ($page->modular()) { continue; } foreach ($items as $item) { if (empty($page->taxonomy[$taxonomy]) || !in_array($item, $page->taxonomy[$taxonomy])) { $collection->remove(); } } } } } // TODO: END OF MOVE if (isset($params['dateRange'])) { $start = isset($params['dateRange']['start']) ? $params['dateRange']['start'] : 0; $end = isset($params['dateRange']['end']) ? $params['dateRange']['end'] : false; $field = isset($params['dateRange']['field']) ? $params['dateRange']['field'] : false; $collection->dateRange($start, $end, $field); } if (isset($params['order'])) { $by = isset($params['order']['by']) ? $params['order']['by'] : 'default'; $dir = isset($params['order']['dir']) ? $params['order']['dir'] : 'asc'; $custom = isset($params['order']['custom']) ? $params['order']['custom'] : null; $collection->order($by, $dir, $custom); } /** @var Grav $grav */ $grav = self::getGrav()['grav']; // New Custom event to handle things like pagination. $grav->fireEvent('onCollectionProcessed', new Event(['collection' => $collection])); // Slice and dice the collection if pagination is required if ($pagination) { $params = $collection->params(); $limit = isset($params['limit']) ? $params['limit'] : 0; $start = !empty($params['pagination']) ? ($uri->currentPage() - 1) * $limit : 0; if ($limit && $collection->count() > $limit) { $collection->slice($start, $limit); } } return $collection; }
/** * Build search results. */ public function onPagesInitialized() { $page = $this->grav['page']; // If a page exists merge the configs if ($page) { $this->config->set('plugins.simplesearch', $this->mergeConfig($page)); } /** @var Uri $uri */ $uri = $this->grav['uri']; $query = $uri->param('query') ?: $uri->query('query'); $route = $this->config->get('plugins.simplesearch.route'); // performance check for query if (empty($query)) { return; } // Support `route: '@self'` syntax if ($route === '@self') { $route = $page . route(); $this->config->set('plugins.simplesearch.route', $route); } // performance check for route if (!($route && $route == $uri->path())) { return; } // Explode query into multiple strings $this->query = explode(',', $query); /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $taxonomies = []; $find_taxonomy = []; $filters = (array) $this->config->get('plugins.simplesearch.filters'); $operator = $this->config->get('plugins.simplesearch.filter_combinator', 'and'); $new_approach = false; if (!$filters || $query === false || count($filters) == 1 && !reset($filters)) { /** @var \Grav\Common\Page\Pages $pages */ $pages = $this->grav['pages']; $this->collection = $pages->all(); } else { foreach ($filters as $key => $filter) { // flatten item if it's wrapped in an array if (is_int($key)) { if (is_array($filter)) { $key = key($filter); $filter = $filter[$key]; } else { $key = $filter; } } // see if the filter uses the new 'items-type' syntax if ($key === '@self' || $key === 'self@') { $new_approach = true; } elseif ($key === '@taxonomy' || $key === 'taxonomy@') { $taxonomies = $filter === false ? false : array_merge($taxonomies, (array) $filter); } else { $find_taxonomy[$key] = $filter; } } if ($new_approach) { $params = $page->header()->content; $params['query'] = $this->config->get('plugins.simplesearch.query'); $this->collection = $page->collection($params, false); } else { $this->collection = new Collection(); $this->collection->append($taxonomy_map->findTaxonomy($find_taxonomy, $operator)->toArray()); } } $extras = []; if ($query) { foreach ($this->collection as $cpage) { foreach ($this->query as $query) { $query = trim($query); if ($this->notFound($query, $cpage, $taxonomies)) { $this->collection->remove($cpage); continue; } if ($cpage->modular()) { $this->collection->remove($cpage); $parent = $cpage->parent(); $extras[$parent->path()] = ['slug' => $parent->slug()]; } } } } if (!empty($extras)) { $this->collection->append($extras); } // use a configured sorting order if not already done if (!$new_approach) { $this->collection = $this->collection->order($this->config->get('plugins.simplesearch.order.by'), $this->config->get('plugins.simplesearch.order.dir')); } // if page doesn't have settings set, create a page if (!isset($page->header()->simplesearch)) { // create the search page $page = new Page(); $page->init(new \SplFileInfo(__DIR__ . '/pages/simplesearch.md')); // override the template is set in the config $template_override = $this->config->get('plugins.simplesearch.template'); if ($template_override) { $page->template($template_override); } // fix RuntimeException: Cannot override frozen service "page" issue unset($this->grav['page']); $this->grav['page'] = $page; } }
/** * @param Collection $collection * @param $orderBy * @param string $orderDir * @param null $orderManual * @return array * @internal */ public function sortCollection(Collection $collection, $orderBy, $orderDir = 'asc', $orderManual = null) { $items = $collection->toArray(); $lookup = md5(serialize($items)); if (!isset($this->sort[$lookup][$orderBy])) { $this->buildSort($lookup, $items, $orderBy, $orderManual); } $sort = $this->sort[$lookup][$orderBy]; if ($orderDir != 'asc') { $sort = array_reverse($sort); } return $sort; }
/** * Set needed variables to display archive plus block. */ public function onTwigSiteVariables() { /** @var Cache $cache */ $cache = $this->grav['cache']; // Emulate Archives plugin; temporarily enable it to for rendering $this->config->set('plugins.archives.enabled', true); $cache_id = md5('archive_plus' . $cache->getKey()); $config = $cache->fetch($cache_id); if ($config === false) { /** @var Taxonomy $taxonomy_map */ $taxonomy_map = $this->grav['taxonomy']; $pages = $this->grav['pages']; // Get current datetime $start_date = time(); // Initialize variables $archives = []; // Get plugin filters settings $filters = (array) $this->config->get('plugins.archive_plus.filters'); $operator = $this->config->get('plugins.archive_plus.filter_combinator'); if (count($filters) > 0) { $collection = new Collection(); $collection->append($taxonomy_map->findTaxonomy($filters, $operator)->toArray()); // reorder the collection based on settings $collection = $collection->order($this->config->get('plugins.archive_plus.order.by'), $this->config->get('plugins.archive_plus.order.dir')); // Loop over new collection of pages that match filters foreach ($collection as $page) { // Update the start date if the page date is older $start_date = $page->date() < $start_date ? $page->date() : $start_date; list($year, $month) = explode(' ', date('Y n', $page->date())); $archives[$year][$month][] = $page; } } // Limit output of archive block depending on number of items, // number of months or years to display $user_limits = (array) $this->config->get('plugins.archive_plus.limit'); $limits = array_fill_keys(array('items', 'month', 'year'), 0); $show_more = count($archives) > $user_limits['year'] ? true : false; if ($user_limits['year'] > 0) { $archives = array_slice($archives, 0, $user_limits['year'], true); } // Limit items in the output based on plugin settings foreach ($archives as $year => &$months) { $num = count($months); if ($limits['month'] >= $user_limits['month'] || $limits['items'] >= $user_limits['items']) { unset($archives[$year]); $show_more = true; continue; } elseif ($limits['month'] + $num > $user_limits['month']) { $length = $user_limits['month'] - $limits['month']; $months = array_slice($months, 0, $length, true); $show_more = true; } $limits['month'] += $num; foreach ($months as $month => &$pages) { $num = count($pages); if ($limits['items'] > $user_limits['items']) { unset($archives[$year][$month]); $show_more = true; } elseif ($limits['items'] + $num > $user_limits['items']) { $length = $user_limits['items'] - $limits['items']; $pages = array_slice($pages, 0, $length, true); if ($length == 0) { unset($archives[$year][$month]); } $limits['items'] += $num; $limits['month'] = $user_limits['month'] + 1; $show_more = true; } $limits['items'] += $num; } } // Get configurations of Archive Plus plugin $config = (array) $this->config->get('plugins.archive_plus'); $config['data'] = $archives; $config['show_more'] = $show_more; $cache->save($cache_id, $config); } // Add Archive Plus configurations to the twig variables $this->grav['twig']->twig_vars['archive_plus'] = $config; // Inject built-in CSS if desired if ($this->config->get('plugins.archive_plus.built_in_css')) { $this->grav['assets']->add('plugin://archive_plus/assets/css/archive_plus.css'); } }
private function parseChildren(Collection $children) { $modules = $children->modular(); if (count($modules) == 0) { return array(); } $configurations = array(); foreach ($children as $child) { $header = $child->header(); if (property_exists($header, "gravstrap")) { $gravstrapComponents = $this->addModulePageToGravstrap($header->gravstrap, $child); $configurations = array_merge($configurations, $gravstrapComponents); } } return $configurations; }