Skip to content

Instantly share code, notes, and snippets.

@Sogl
Last active October 8, 2022 13:39
Show Gist options
  • Save Sogl/bb66e73417811e418ba7f17c1a93babf to your computer and use it in GitHub Desktop.
Save Sogl/bb66e73417811e418ba7f17c1a93babf to your computer and use it in GitHub Desktop.
Grav CMS Flex plugin
<?php
namespace Grav\Plugin\SoglFlex;
use Grav\Common\Cache;
use Grav\Common\Grav;
use Grav\Common\Page\Interfaces\PageInterface;
class Flextagslist
{
/**
* @var array
*/
protected $flextagslist;
/** @var array */
protected $taxonomy_map;
/**
* Get taxonomy list with all tags of the site.
*
* @return array
*/
public function get()
{
if (null === $this->flextagslist) {
//collection name + fields with selectize
$this->addTaxonomies('therapies', ['tags']);
$this->flextagslist = $this->build($this->taxonomy_map);
}
return $this->flextagslist;
}
/**
* @internal
* @param array $taxonomylist
* @return array
*/
protected function build(array $flextagslist)
{
/** @var Cache $cache */
$cache = Grav::instance()['cache'];
$hash = hash('md5', serialize($flextagslist));
$list = [];
if ($taxonomy = $cache->fetch($hash)) {
return $taxonomy;
}
foreach ($flextagslist as $taxonomyName => $taxonomyValue) {
$partial = [];
foreach ($taxonomyValue as $key => $value) {
if (is_array($value)) {
$key = (string)$key;
$taxonomyValue[$key] = count($value);
$partial[$key] = count($value);
} else {
$partial[(string)$value] = 1;
}
}
arsort($partial);
$list[$taxonomyName] = $partial;
}
$cache->save($hash, $list);
return $list;
}
/**
* Takes an individual page and processes the taxonomies configured in its header. It
* then adds those taxonomies to the map
*
* @param ... $taxonomies the page to process
* @param array|null $page_taxonomy
*/
protected function addTaxonomies($collectionName, $taxonomies, $page_taxonomy = null)
{
$flex = Grav::instance()['flex'] ?? null;
$collection = $flex ? $flex->getCollection($collectionName)->filterBy(['published' => true]) : null;
if (!$collection) {
return [];
}
$objects = $collection->toArray();
foreach ($taxonomies as $taxonomy) {
// Skip invalid taxonomies.
if (!\is_string($taxonomy)) {
continue;
}
foreach ($objects as $object) {
$currentTax = $object->getProperty($taxonomy) ?? null;
foreach ((array)$currentTax as $item) {
$this->iterateTaxonomy($object, $taxonomy, '', $item);
}
}
}
}
/**
* Iterate through taxonomy fields
*
* Reduces [taxonomy_type] to dot-notation where necessary
*
* @param ... $object The Flex object to process
* @param string $taxonomy Taxonomy type to add
* @param string $key Taxonomy type to concatenate
* @param iterable|string $value Taxonomy value to add or iterate
* @return void
*/
protected function iterateTaxonomy($object, string $taxonomy, string $key, $value)
{
if (is_iterable($value)) {
foreach ($value as $identifier => $item) {
$identifier = "{$key}.{$identifier}";
$this->iterateTaxonomy($object, $taxonomy, $identifier, $item);
}
} elseif (is_string($value)) {
if (!empty($key)) {
$taxonomy .= $key;
}
$this->taxonomy_map[$taxonomy][(string) $value][$this->path($object)] = ['slug' => $object->getStorageKey()];
}
}
/**
* Gets and sets the path to the folder where the .md for this Flex object resides.
* This is equivalent to the filePath but without the filename.
*
* @param string|null $var the path
* @return string|null the path
*/
protected function path($obj = null): ?string
{
if (null === $obj) {
return false;
}
$folder = $obj->getStorageFolder();
if ($folder) {
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
$folder = $locator->isStream($folder) ? $locator->getResource($folder) : GRAV_ROOT . "/{$folder}";
}
return (string)$folder;
}
}
<?php
namespace Grav\Plugin;
use Grav\Common\Uri;
use Grav\Common\Grav;
use Grav\Common\Utils;
use Grav\Common\Plugin;
use Composer\Autoload\ClassLoader;
use RocketTheme\Toolbox\Event\Event;
use Grav\Common\Flex\Types\Pages\PageObject;
use Grav\Plugin\SoglFlex\Flextagslist;
/**
* Class SoglFlex
* @package Grav\Plugin
*/
class SoglFlex extends Plugin
{
/** @var string */
// protected $admin_route;
public $features = [
'blueprints' => 1000,
];
/**
* @return array
*
* The getSubscribedEvents() gives the core a list of events
* that the plugin wants to listen to. The key of each
* array section is the event that the plugin listens to
* and the value (in the form of an array) contains the
* callable (or function) as well as the priority. The
* higher the number the higher the priority.
*/
public static function getSubscribedEvents(): array
{
return [
'onPluginsInitialized' => [
// Uncomment following line when plugin requires Grav < 1.7
// ['autoload', 100000],
['onPluginsInitialized', 0]
]
];
}
/**
* Composer autoload
*
* @return ClassLoader
*/
public function autoload(): ClassLoader
{
return require __DIR__ . '/vendor/autoload.php';
}
/**
* Initialize the plugin
*/
public function onPluginsInitialized(): void
{
// Don't proceed if we are in the admin plugin
if ($this->isAdmin()) {
// $route = $this->config->get('plugins.admin.route');
// $base = '/' . trim($route, '/');
// $this->admin_route = $this->grav['base_url'] . $base;
$this->enable([
'onAdminTwigTemplatePaths' => ['onAdminTwigTemplatePaths', 11],
'onFlexAfterSave' => ['onFlexAfterSave', 0],
]);
}
// Enable the main events we are interested in
$this->enable([
// Put your main events here
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
]);
if (!$this->isAdmin()) {
$this->router();
}
}
/**
* Set needed variables to display the taxonomy list.
*
* @return void
*/
public function onTwigSiteVariables()
{
$twig = $this->grav['twig'];
$twig->twig_vars['flextagslist'] = new Flextagslist();
//dd($twig);
}
/**
* Add plugin templates path
*
* @param Event $event
* @return void
*/
public function onAdminTwigTemplatePaths(Event $event): void
{
$paths = $event['paths'];
$paths[] = __DIR__ . '/admin/templates';
$event['paths'] = $paths;
}
public function router()
{
/** @var Uri $uri */
$uri = $this->grav['uri'];
$route = Uri::getCurrentRoute()->getRoute();
if (Utils::startsWith($route, '/therapies') && !Utils::contains($route, '.')) {
// if (Utils::startsWith($route, '/therapies')) {
$this->enable([
'onPagesInitialized' => ['addTherapyPage', 0]
]);
}
}
public static function getFlexUsers(): array {
$flex = Grav::instance()['flex'] ?? null;
$collection = $flex ? $flex->getCollection('user-accounts')->filterBy(['specialist' => true])->sort(['fullname' => 'ASC']) : null; // change this line
if (!$collection) {
return [];
}
$objects = $collection->toArray();
$result = [];
foreach ($objects as $object) {
//$result[$object->getStorageKey()] = $object->getProperty('id') . ' - ' . $object->getProperty('name'); //change this line
$result[$object->getStorageKey()] = $object->getProperty('fullname');
}
return $result;
}
public function addTherapyPage()
{
$route = Uri::getCurrentRoute()->getRoute();
$normalized = trim($route, '/');
if (!$normalized) {
return;
}
$parts = explode('/', $normalized, 2);
$key = array_shift($parts);
$path = array_shift($parts);
/** @var Pages $pages */
$pages = $this->grav['pages'];
if ($pages->find($route)) {
/** @var Debugger $debugger */
$debugger = $this->grav['debugger'];
$debugger->addMessage("Page {$route} already exists, page cannot be added", 'error');
return;
}
$flex = Grav::instance()->get('flex');
$therapy = $flex->getObject($path, 'therapies');
$page = $pages->find('/therapies/therapy');
if ($page) {
$page->id($page->modified() . md5($route));
$page->slug(basename($route));
$page->folder(basename($route));
$page->route($route);
$page->rawRoute($route);
$page->modifyHeader('object', $path);
//$page->modifyHeader('title', $title);
if ($therapy) {
$title = $therapy->getProperty('title');
//$page->modifyHeader('title', $title);
$page->title($title);
$page->media($therapy->getMedia());
$page->content($therapy->getProperty('description'));
}
$pages->addPage($page, $route);
}
}
public function onFlexAfterSave($event)
{
//not for default pages
if (!$event['object'] instanceof PageObject) {
$uri = $this->grav['uri'];
$obj = $event['object'];
if ($obj->getKey() === $obj->getStorageKey()) {
return;
}
$paths = $uri->paths();
if (isset($paths[2])) {
$paths[2] = $obj->getStorageKey();
$this->grav->redirect(implode('/', $paths), 302);
}
}
}
}
{% set flex = grav['flex_objects'] %}
{% set directory = flex.directory('therapies') %}
{% set object = directory.getObject(header.object) %}
{% set userDir = flex.directory('user-accounts') %}
{% set author = userDir.getObject(object.author) %}
{% extends 'partials/base.html.twig' %}
{% block content %}
{% include 'partials/toc.html.twig' %}
<div id="body-inner" class="highlightable">
{# <h1>{{ object.title }}</h1> #}
<h1>{{ page.title }}</h1>
<div class="entry-details">
{# {{ object.description|markdown }} #}
{{ page.content|raw }}
{% if object.author %}
<p><a href="#" class="author">{{ author.fullname|e }}</a></p>
{% endif %}
</div>
<div class="entry-extra">
{% for tag in object.tags %}
<a href="{{ page.parent.route }}/tag:{{ tag|e }}"><span>{{ tag|e }}</span></a>
{% endfor %}
</div>
</div>
{% include 'partials/github-note.html.twig' %}
{% endblock %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment