test appel img twig
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
namespace Grav\Common\Assets;
|
||||
|
||||
use Grav\Common\Assets\Traits\AssetUtilsTrait;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
@@ -171,6 +172,31 @@ abstract class BaseAsset extends PropertyObject
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive asset location and return the SRI integrity hash
|
||||
*
|
||||
* @param $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function integrityHash( $input )
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
$assetsConfig = $grav['config']->get('system.assets');
|
||||
|
||||
if ( !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri'] )
|
||||
{
|
||||
$dataToHash = file_get_contents( GRAV_ROOT . $input);
|
||||
|
||||
$hash = hash('sha256', $dataToHash, true);
|
||||
$hash_base64 = base64_encode($hash);
|
||||
return ' integrity="sha256-' . $hash_base64 . '"';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,6 +47,6 @@ class Css extends BaseAsset
|
||||
return "<style>\n" . trim($buffer) . "\n</style>\n";
|
||||
}
|
||||
|
||||
return '<link href="' . trim($this->asset) . $this->renderQueryString() . '"' . $this->renderAttributes() . ">\n";
|
||||
return '<link href="' . trim($this->asset) . $this->renderQueryString() . '"' . $this->renderAttributes() . $this->integrityHash($this->asset) . ">\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,6 @@ class Js extends BaseAsset
|
||||
return '<script' . $this->renderAttributes() . ">\n" . trim($buffer) . "\n</script>\n";
|
||||
}
|
||||
|
||||
return '<script src="' . trim($this->asset) . $this->renderQueryString() . '"' . $this->renderAttributes() . "></script>\n";
|
||||
return '<script src="' . trim($this->asset) . $this->renderQueryString() . '"' . $this->renderAttributes() . $this->integrityHash($this->asset) . "></script>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Grav\Common\Assets;
|
||||
|
||||
use Grav\Common\Assets\BaseAsset;
|
||||
use Grav\Common\Assets\Traits\AssetUtilsTrait;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Grav;
|
||||
@@ -148,7 +149,7 @@ class Pipeline extends PropertyObject
|
||||
$output = "<style>\n" . $buffer . "\n</style>\n";
|
||||
} else {
|
||||
$this->asset = $relative_path;
|
||||
$output = '<link href="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . ">\n";
|
||||
$output = '<link href="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . BaseAsset::integrityHash($this->asset) . ">\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
@@ -211,7 +212,7 @@ class Pipeline extends PropertyObject
|
||||
$output = '<script' . $this->renderAttributes(). ">\n" . $buffer . "\n</script>\n";
|
||||
} else {
|
||||
$this->asset = $relative_path;
|
||||
$output = '<script src="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . "></script>\n";
|
||||
$output = '<script src="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . BaseAsset::integrityHash($this->asset) . "></script>\n";
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
||||
@@ -71,6 +71,7 @@ class Cache extends Getters
|
||||
'cache://twig/',
|
||||
'cache://doctrine/',
|
||||
'cache://compiled/',
|
||||
'cache://clockwork/',
|
||||
'cache://validated-',
|
||||
'cache://images',
|
||||
'asset://',
|
||||
@@ -80,6 +81,7 @@ class Cache extends Getters
|
||||
'cache://twig/',
|
||||
'cache://doctrine/',
|
||||
'cache://compiled/',
|
||||
'cache://clockwork/',
|
||||
'cache://validated-',
|
||||
'asset://',
|
||||
];
|
||||
@@ -311,7 +313,7 @@ class Cache extends Getters
|
||||
if ($password && !$redis->auth($password)) {
|
||||
throw new \RedisException('Redis authentication failed');
|
||||
}
|
||||
|
||||
|
||||
// Select alternate ( !=0 ) database ID if set
|
||||
if ($databaseId && !$redis->select($databaseId)) {
|
||||
throw new \RedisException('Could not select alternate Redis database ID');
|
||||
@@ -498,7 +500,7 @@ class Cache extends Getters
|
||||
$anything = true;
|
||||
}
|
||||
} elseif (is_dir($file)) {
|
||||
if (Folder::delete($file)) {
|
||||
if (Folder::delete($file, false)) {
|
||||
$anything = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,13 +21,16 @@ use Grav\Common\Grav;
|
||||
use Grav\Common\Page\Header;
|
||||
use Grav\Common\Page\Interfaces\PageCollectionInterface;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\User\Interfaces\UserInterface;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Flex\FlexDirectory;
|
||||
use Grav\Framework\Flex\Interfaces\FlexCollectionInterface;
|
||||
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
|
||||
use Grav\Framework\Flex\Pages\FlexPageIndex;
|
||||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use function array_slice;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
|
||||
@@ -299,7 +302,33 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
'type' => ['root', 'dir'],
|
||||
];
|
||||
|
||||
return $this->getLevelListingRecurse($options);
|
||||
$key = 'page.idx.lev.' . sha1(json_encode($options, JSON_THROW_ON_ERROR) . $this->getCacheKey());
|
||||
$checksum = $this->getCacheChecksum();
|
||||
|
||||
$cache = $this->getCache('object');
|
||||
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = Grav::instance()['debugger'];
|
||||
|
||||
$result = null;
|
||||
try {
|
||||
$cached = $cache->get($key);
|
||||
$test = $cached[0] ?? null;
|
||||
$result = $test === $checksum ? ($cached[1] ?? null) : null;
|
||||
} catch (\Psr\SimpleCache\InvalidArgumentException $e) {
|
||||
$debugger->addException($e);
|
||||
}
|
||||
|
||||
try {
|
||||
if (null === $result) {
|
||||
$result = $this->getLevelListingRecurse($options);
|
||||
$cache->set($key, [$checksum, $result]);
|
||||
}
|
||||
} catch (\Psr\SimpleCache\InvalidArgumentException $e) {
|
||||
$debugger->addException($e);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,6 +458,9 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
$selectedChildren = $selectedChildren->order($sortby, $order, $custom ?? null);
|
||||
}
|
||||
|
||||
/** @var UserInterface|null $user */
|
||||
$user = Grav::instance()['user'] ?? null;
|
||||
|
||||
/** @var PageObject $child */
|
||||
foreach ($selectedChildren as $child) {
|
||||
$selected = $child->path() === $extra;
|
||||
@@ -482,7 +514,7 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
'visible' => $child->visible(),
|
||||
'routable' => $child->routable(),
|
||||
'tags' => $tags,
|
||||
'actions' => $this->getListingActions($child),
|
||||
'actions' => $this->getListingActions($child, $user),
|
||||
];
|
||||
$extras = array_filter($extras, static function ($v) {
|
||||
return $v !== null;
|
||||
@@ -535,20 +567,21 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
|
||||
|
||||
/**
|
||||
* @param PageObject $object
|
||||
* @param UserInterface $user
|
||||
* @return array
|
||||
*/
|
||||
protected function getListingActions(PageObject $object): array
|
||||
protected function getListingActions(PageObject $object, UserInterface $user): array
|
||||
{
|
||||
$actions = [];
|
||||
if ($object->isAuthorized('read')) {
|
||||
if ($object->isAuthorized('read', null, $user)) {
|
||||
$actions[] = 'preview';
|
||||
$actions[] = 'edit';
|
||||
}
|
||||
if ($object->isAuthorized('update')) {
|
||||
if ($object->isAuthorized('update', null, $user)) {
|
||||
$actions[] = 'copy';
|
||||
$actions[] = 'move';
|
||||
}
|
||||
if ($object->isAuthorized('delete')) {
|
||||
if ($object->isAuthorized('delete', null, $user)) {
|
||||
$actions[] = 'delete';
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@ class PageObject extends FlexPageObject
|
||||
|
||||
/** @var string Language code, eg: 'en' */
|
||||
protected $language;
|
||||
|
||||
/** @var string File format, eg. 'md' */
|
||||
protected $format;
|
||||
|
||||
@@ -78,6 +77,7 @@ class PageObject extends FlexPageObject
|
||||
'path' => true,
|
||||
'full_order' => true,
|
||||
'filterBy' => true,
|
||||
'translated' => false,
|
||||
] + parent::getCachedMethods();
|
||||
}
|
||||
|
||||
@@ -92,6 +92,11 @@ class PageObject extends FlexPageObject
|
||||
}
|
||||
}
|
||||
|
||||
public function translated(): bool
|
||||
{
|
||||
return $this->translatedLanguages(true) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $query
|
||||
* @return Route|null
|
||||
@@ -223,7 +228,7 @@ class PageObject extends FlexPageObject
|
||||
}
|
||||
|
||||
// Reorder siblings.
|
||||
$siblings = is_array($reorder) ? $this->reorderSiblings($reorder) : [];
|
||||
$siblings = is_array($reorder) ? ($this->reorderSiblings($reorder) ?? []) : [];
|
||||
|
||||
$data = $this->prepareStorage();
|
||||
unset($data['header']);
|
||||
@@ -289,6 +294,9 @@ class PageObject extends FlexPageObject
|
||||
$grav->fireEvent('onAdminAfterSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => $this]));
|
||||
}
|
||||
|
||||
// Reset original after save events have all been called.
|
||||
$this->_original = null;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
@@ -308,13 +316,14 @@ class PageObject extends FlexPageObject
|
||||
|
||||
$this->_reorder = [];
|
||||
$this->setProperty('parent_key', $parent->getStorageKey());
|
||||
$this->storeOriginal();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $ordering
|
||||
* @return PageCollection
|
||||
* @return PageCollection|null
|
||||
*/
|
||||
protected function reorderSiblings(array $ordering)
|
||||
{
|
||||
@@ -324,17 +333,35 @@ class PageObject extends FlexPageObject
|
||||
$newParentKey = $this->getProperty('parent_key');
|
||||
$isMoved = $oldParentKey !== $newParentKey;
|
||||
$order = !$isMoved ? $this->order() : false;
|
||||
if ($order !== false) {
|
||||
$order = (int)$order;
|
||||
}
|
||||
|
||||
$parent = $this->parent();
|
||||
if (!$parent) {
|
||||
throw new RuntimeException('Cannot reorder a page which has no parent');
|
||||
}
|
||||
|
||||
/** @var PageCollection|null $siblings */
|
||||
/** @var PageCollection $siblings */
|
||||
$siblings = $parent->children();
|
||||
$siblings = $siblings->getCollection()->withOrdered();
|
||||
|
||||
/** @var PageCollection|null $siblings */
|
||||
$siblings = $siblings->getCollection()->withOrdered()->orderBy(['order' => 'ASC']);
|
||||
// Handle special case where ordering isn't given.
|
||||
if ($ordering === []) {
|
||||
if ($order >= 999999) {
|
||||
// Set ordering to point to be the last item.
|
||||
$order = 0;
|
||||
foreach ($siblings as $sibling) {
|
||||
$order = max($order, (int)$sibling->order());
|
||||
}
|
||||
$this->order($order + 1);
|
||||
}
|
||||
|
||||
// Do not change sibling ordering.
|
||||
return null;
|
||||
}
|
||||
|
||||
$siblings = $siblings->orderBy(['order' => 'ASC']);
|
||||
|
||||
if ($storageKey !== null) {
|
||||
if ($order !== false) {
|
||||
@@ -378,7 +405,9 @@ class PageObject extends FlexPageObject
|
||||
throw new RuntimeException("New parent page '{$parentKey}' not found.");
|
||||
}
|
||||
}
|
||||
$newSiblings = $newParent->children()->getCollection()->withOrdered();
|
||||
/** @var PageCollection $newSiblings */
|
||||
$newSiblings = $newParent->children();
|
||||
$newSiblings = $newSiblings->getCollection()->withOrdered();
|
||||
$order = 0;
|
||||
foreach ($newSiblings as $sibling) {
|
||||
$order = max($order, (int)$sibling->order());
|
||||
@@ -584,14 +613,17 @@ class PageObject extends FlexPageObject
|
||||
unset($elements['ordering'], $elements['order']);
|
||||
} elseif (array_key_exists('ordering', $elements) && array_key_exists('order', $elements)) {
|
||||
// Store ordering.
|
||||
$this->_reorder = !empty($elements['order']) ? explode(',', $elements['order']) : [];
|
||||
$ordering = $elements['order'] ?? null;
|
||||
$this->_reorder = !empty($ordering) ? explode(',', $ordering) : [];
|
||||
|
||||
$order = false;
|
||||
if ((bool)($elements['ordering'] ?? false)) {
|
||||
$order = 999999;
|
||||
$order = $this->order();
|
||||
if ($order === false) {
|
||||
$order = 999999;
|
||||
}
|
||||
}
|
||||
|
||||
$this->order();
|
||||
$elements['order'] = $order;
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,9 @@ class PageStorage extends FolderStorage
|
||||
}
|
||||
} catch (RuntimeException $e) {
|
||||
$frontmatter = 'ERROR: ' . $e->getMessage();
|
||||
} finally {
|
||||
$file->free();
|
||||
unset($file);
|
||||
}
|
||||
|
||||
return $frontmatter;
|
||||
@@ -127,6 +130,9 @@ class PageStorage extends FolderStorage
|
||||
$raw = $file->raw();
|
||||
} catch (RuntimeException $e) {
|
||||
$raw = 'ERROR: ' . $e->getMessage();
|
||||
} finally {
|
||||
$file->free();
|
||||
unset($file);
|
||||
}
|
||||
|
||||
return $raw;
|
||||
@@ -407,7 +413,7 @@ class PageStorage extends FolderStorage
|
||||
if (!$isClone && $file->exists()) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
$toPath = $locator->isStream($newFilepath) ? $locator->findResource($newFilepath, true, true) : $newFilepath;
|
||||
$toPath = $locator->isStream($newFilepath) ? $locator->findResource($newFilepath, true, true) : GRAV_ROOT . "/{$newFilepath}";
|
||||
$success = $file->rename($toPath);
|
||||
if (!$success) {
|
||||
throw new RuntimeException("Changing page template failed: {$oldFilepath} => {$newFilepath}");
|
||||
@@ -439,16 +445,19 @@ class PageStorage extends FolderStorage
|
||||
} else {
|
||||
$debugger->addMessage('Page content has not been changed, do not update the file', 'debug');
|
||||
}
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($newFolder)) {
|
||||
$locator->clearCache();
|
||||
}
|
||||
} catch (RuntimeException $e) {
|
||||
$name = isset($file) ? $file->filename() : $newKey;
|
||||
|
||||
throw new RuntimeException(sprintf('Flex saveRow(%s): %s', $name, $e->getMessage()));
|
||||
} finally {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
$locator->clearCache();
|
||||
|
||||
if (isset($file)) {
|
||||
$file->free();
|
||||
unset($file);
|
||||
}
|
||||
}
|
||||
|
||||
$row['__META'] = $this->getObjectMeta($newKey, true);
|
||||
@@ -512,7 +521,11 @@ class PageStorage extends FolderStorage
|
||||
$locator = Grav::instance()['locator'];
|
||||
if (mb_strpos($key, '@@') === false) {
|
||||
$path = $this->getStoragePath($key);
|
||||
$path = $path ? $locator->findResource($path) : null;
|
||||
if (is_string($path)) {
|
||||
$path = $locator->isStream($path) ? $locator->findResource($path) : GRAV_ROOT . "/{$path}";
|
||||
} else {
|
||||
$path = null;
|
||||
}
|
||||
} else {
|
||||
$path = null;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ trait PageTranslateTrait
|
||||
if (!$folder) {
|
||||
return [];
|
||||
}
|
||||
$folder = $locator($folder);
|
||||
$folder = $locator->isStream($folder) ? $locator->getResource($folder) : GRAV_ROOT . "/{$folder}";
|
||||
|
||||
$list = array_fill_keys($languages, null);
|
||||
foreach ($translated as $languageCode => $languageFile) {
|
||||
|
||||
@@ -426,12 +426,18 @@ class Grav extends Container
|
||||
// Clean route for redirect
|
||||
$route = preg_replace("#^\/[\\\/]+\/#", '/', $route);
|
||||
|
||||
// Check for code in route
|
||||
$regex = '/.*(\[(30[1-7])\])$/';
|
||||
preg_match($regex, $route, $matches);
|
||||
if ($matches) {
|
||||
$route = str_replace($matches[1], '', $matches[0]);
|
||||
$code = $matches[2];
|
||||
if (null !== $code || $code < 300 || $code > 399) {
|
||||
$code = null;
|
||||
}
|
||||
|
||||
if (null === $code) {
|
||||
// Check for redirect code in the route: e.g. /new/[301], /new[301]/route or /new[301].html
|
||||
$regex = '/.*(\[(30[1-7])\])(.\w+|\/.*?)?$/';
|
||||
preg_match($regex, $route, $matches);
|
||||
if ($matches) {
|
||||
$route = str_replace($matches[1], '', $matches[0]);
|
||||
$code = $matches[2];
|
||||
}
|
||||
}
|
||||
|
||||
if ($code === null) {
|
||||
|
||||
@@ -34,7 +34,7 @@ class LogViewer
|
||||
public function objectTail($filepath, $lines = 1, $desc = true)
|
||||
{
|
||||
$data = $this->tail($filepath, $lines);
|
||||
$tailed_log = explode(PHP_EOL, $data);
|
||||
$tailed_log = $data ? explode(PHP_EOL, $data) : [];
|
||||
$line_objects = [];
|
||||
|
||||
foreach ($tailed_log as $line) {
|
||||
@@ -54,13 +54,13 @@ class LogViewer
|
||||
public function tail($filepath, $lines = 1)
|
||||
{
|
||||
|
||||
$f = @fopen($filepath, "rb");
|
||||
$f = $filepath ? @fopen($filepath, 'rb') : false;
|
||||
if ($f === false) {
|
||||
return false;
|
||||
} else {
|
||||
$buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
|
||||
}
|
||||
|
||||
$buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096));
|
||||
|
||||
fseek($f, -1, SEEK_END);
|
||||
if (fread($f, 1) != "\n") {
|
||||
$lines -= 1;
|
||||
|
||||
@@ -63,7 +63,7 @@ interface PageRoutableInterface
|
||||
* the parents route and the current Page's slug.
|
||||
*
|
||||
* @param string|null $var Set new default route.
|
||||
* @return string The route for the Page.
|
||||
* @return string|null The route for the Page.
|
||||
*/
|
||||
public function route($var = null);
|
||||
|
||||
|
||||
@@ -278,10 +278,10 @@ class Excerpts
|
||||
);
|
||||
}
|
||||
|
||||
$defaults = $config['images']['defaults'] ?? [];
|
||||
$defaults = $this->config['images']['defaults'] ?? [];
|
||||
if (count($defaults)) {
|
||||
foreach ($defaults as $method => $params) {
|
||||
if (!array_search($method, array_column($actions, 'method'))) {
|
||||
if (array_search($method, array_column($actions, 'method')) === false) {
|
||||
$actions[] = [
|
||||
'method' => $method,
|
||||
'params' => $params,
|
||||
|
||||
@@ -1875,7 +1875,7 @@ class Page implements PageInterface
|
||||
* the parents route and the current Page's slug.
|
||||
*
|
||||
* @param string|null $var Set new default route.
|
||||
* @return string The route for the Page.
|
||||
* @return string|null The route for the Page.
|
||||
*/
|
||||
public function route($var = null)
|
||||
{
|
||||
|
||||
@@ -769,6 +769,9 @@ class Pages
|
||||
public function get($path)
|
||||
{
|
||||
$path = (string)$path;
|
||||
if ($path === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check for local instances first.
|
||||
if (array_key_exists($path, $this->instances)) {
|
||||
@@ -777,14 +780,26 @@ class Pages
|
||||
|
||||
$instance = $this->index[$path] ?? null;
|
||||
if (is_string($instance)) {
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
$lang = $language->getActive();
|
||||
if ($lang) {
|
||||
$instance .= ':' . $lang;
|
||||
if ($this->directory) {
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
$lang = $language->getActive();
|
||||
if ($lang) {
|
||||
$languages = $language->getFallbackLanguages($lang, true);
|
||||
$key = $instance;
|
||||
$instance = null;
|
||||
foreach ($languages as $code) {
|
||||
$test = $code ? $key . ':' . $code : $key;
|
||||
if (($instance = $this->directory->getObject($test, 'flex_key')) !== null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$instance = $this->directory->getObject($instance, 'flex_key');
|
||||
}
|
||||
}
|
||||
$instance = $this->directory ? $this->directory->getObject($instance, 'flex_key') : null;
|
||||
if ($instance) {
|
||||
|
||||
if ($instance instanceof PageInterface) {
|
||||
if ($this->fire_events && method_exists($instance, 'initialize')) {
|
||||
$instance->initialize();
|
||||
}
|
||||
@@ -1159,7 +1174,14 @@ class Pages
|
||||
$event->types = $types;
|
||||
$grav->fireEvent('onGetPageBlueprints', $event);
|
||||
|
||||
$types->scanBlueprints('theme://blueprints/');
|
||||
$types->init();
|
||||
|
||||
// Try new location first.
|
||||
$lookup = 'theme://blueprints/pages/';
|
||||
if (!is_dir($lookup)) {
|
||||
$lookup = 'theme://blueprints/';
|
||||
}
|
||||
$types->scanBlueprints($lookup);
|
||||
|
||||
// Scan templates
|
||||
$event = new Event();
|
||||
|
||||
@@ -32,22 +32,23 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
/** @var array */
|
||||
protected $items;
|
||||
/** @var array */
|
||||
protected $systemBlueprints;
|
||||
protected $systemBlueprints = [];
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param Blueprint|null $blueprint
|
||||
* @return void
|
||||
*/
|
||||
public function register($type, $blueprint = null)
|
||||
{
|
||||
if (!isset($this->items[$type])) {
|
||||
$this->items[$type] = [];
|
||||
} elseif (!$blueprint) {
|
||||
} elseif (null === $blueprint) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$blueprint && $this->systemBlueprints) {
|
||||
$blueprint = $this->systemBlueprints[$type] ?? $this->systemBlueprints['default'];
|
||||
if (null === $blueprint) {
|
||||
$blueprint = $this->systemBlueprints[$type] ?? $this->systemBlueprints['default'] ?? null;
|
||||
}
|
||||
|
||||
if ($blueprint) {
|
||||
@@ -55,8 +56,23 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (null === $this->systemBlueprints) {
|
||||
// Register all blueprints from the blueprints stream.
|
||||
$this->systemBlueprints = $this->findBlueprints('blueprints://pages');
|
||||
foreach ($this->systemBlueprints as $type => $blueprint) {
|
||||
$this->register($type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function scanBlueprints($uri)
|
||||
{
|
||||
@@ -64,15 +80,6 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
throw new InvalidArgumentException('First parameter must be URI');
|
||||
}
|
||||
|
||||
if (null === $this->systemBlueprints) {
|
||||
$this->systemBlueprints = $this->findBlueprints('blueprints://pages');
|
||||
|
||||
// Register default by default.
|
||||
$this->register('default');
|
||||
|
||||
$this->register('external');
|
||||
}
|
||||
|
||||
foreach ($this->findBlueprints($uri) as $type => $blueprint) {
|
||||
$this->register($type, $blueprint);
|
||||
}
|
||||
@@ -80,6 +87,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable
|
||||
|
||||
/**
|
||||
* @param string $uri
|
||||
* @return void
|
||||
*/
|
||||
public function scanTemplates($uri)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Config\Config;
|
||||
use LogicException;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use function defined;
|
||||
@@ -35,11 +36,11 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
|
||||
/** @var Grav */
|
||||
protected $grav;
|
||||
/** @var Config */
|
||||
/** @var Config|null */
|
||||
protected $config;
|
||||
/** @var bool */
|
||||
protected $active = true;
|
||||
/** @var Blueprint */
|
||||
/** @var Blueprint|null */
|
||||
protected $blueprint;
|
||||
|
||||
/**
|
||||
@@ -127,21 +128,25 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
protected function isPluginActiveAdmin($plugin_route)
|
||||
{
|
||||
$should_run = false;
|
||||
$active = false;
|
||||
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->grav['uri'];
|
||||
/** @var Config $config */
|
||||
$config = $this->config ?? $this->grav['config'];
|
||||
|
||||
if (strpos($uri->path(), $this->config->get('plugins.admin.route') . '/' . $plugin_route) === false) {
|
||||
$should_run = false;
|
||||
if (strpos($uri->path(), $config->get('plugins.admin.route') . '/' . $plugin_route) === false) {
|
||||
$active = false;
|
||||
} elseif (isset($uri->paths()[1]) && $uri->paths()[1] === $plugin_route) {
|
||||
$should_run = true;
|
||||
$active = true;
|
||||
}
|
||||
|
||||
return $should_run;
|
||||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
* @return void
|
||||
*/
|
||||
protected function enable(array $events)
|
||||
{
|
||||
@@ -164,22 +169,18 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
/**
|
||||
* @param array $params
|
||||
* @param string $eventName
|
||||
* @return int
|
||||
*/
|
||||
private function getPriority($params, $eventName)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$override = implode('.', ['priorities', $this->name, $eventName, $params[0]]);
|
||||
if ($grav['config']->get($override) !== null) {
|
||||
return $grav['config']->get($override);
|
||||
}
|
||||
if (isset($params[1])) {
|
||||
return $params[1];
|
||||
}
|
||||
return 0;
|
||||
|
||||
return $this->grav['config']->get($override) ?? $params[1] ?? 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $events
|
||||
* @return void
|
||||
*/
|
||||
protected function disable(array $events)
|
||||
{
|
||||
@@ -207,12 +208,13 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$this->loadBlueprint();
|
||||
|
||||
if ($offset === 'title') {
|
||||
$offset = 'name';
|
||||
}
|
||||
return isset($this->blueprint[$offset]);
|
||||
|
||||
$blueprint = $this->getBlueprint();
|
||||
|
||||
return isset($blueprint[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,12 +225,13 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$this->loadBlueprint();
|
||||
|
||||
if ($offset === 'title') {
|
||||
$offset = 'name';
|
||||
}
|
||||
return $this->blueprint[$offset] ?? null;
|
||||
|
||||
$blueprint = $this->getBlueprint();
|
||||
|
||||
return $blueprint[$offset] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,9 +284,12 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
protected function parseLinks($content, $function, $internal_regex = '(.*)')
|
||||
{
|
||||
$regex = '/\[plugin:(?:' . $this->name . ')\]\(' . $internal_regex . '\)/i';
|
||||
$regex = '/\[plugin:(?:' . preg_quote($this->name, '/') . ')\]\(' . $internal_regex . '\)/i';
|
||||
|
||||
return preg_replace_callback($regex, $function, $content);
|
||||
$result = preg_replace_callback($regex, $function, $content);
|
||||
\assert($result !== null);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -301,9 +307,12 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
protected function mergeConfig(PageInterface $page, $deep = false, $params = [], $type = 'plugins')
|
||||
{
|
||||
/** @var Config $config */
|
||||
$config = $this->config ?? $this->grav['config'];
|
||||
|
||||
$class_name = $this->name;
|
||||
$class_name_merged = $class_name . '.merged';
|
||||
$defaults = $this->config->get($type . '.' . $class_name, []);
|
||||
$defaults = $config->get($type . '.' . $class_name, []);
|
||||
$page_header = $page->header();
|
||||
$header = [];
|
||||
|
||||
@@ -356,23 +365,26 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
/**
|
||||
* Persists to disk the plugin parameters currently stored in the Grav Config object
|
||||
*
|
||||
* @param string $plugin_name The name of the plugin whose config it should store.
|
||||
*
|
||||
* @param string $name The name of the plugin whose config it should store.
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveConfig($plugin_name)
|
||||
public static function saveConfig($name)
|
||||
{
|
||||
if (!$plugin_name) {
|
||||
if (!$name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
$filename = 'config://plugins/' . $plugin_name . '.yaml';
|
||||
$file = YamlFile::instance($locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('plugins.' . $plugin_name);
|
||||
|
||||
$filename = 'config://plugins/' . $name . '.yaml';
|
||||
$file = YamlFile::instance((string)$locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('plugins.' . $name);
|
||||
$file->save($content);
|
||||
$file->free();
|
||||
unset($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -384,21 +396,28 @@ class Plugin implements EventSubscriberInterface, ArrayAccess
|
||||
*/
|
||||
public function getBlueprint()
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
if (null === $this->blueprint) {
|
||||
$this->loadBlueprint();
|
||||
\assert($this->blueprint instanceof Blueprint);
|
||||
}
|
||||
|
||||
return $this->blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load blueprints.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function loadBlueprint()
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
if (null === $this->blueprint) {
|
||||
$grav = Grav::instance();
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = $grav['plugins'];
|
||||
$this->blueprint = $plugins->get($this->name)->blueprints();
|
||||
$data = $plugins->get($this->name);
|
||||
\assert($data !== null);
|
||||
$this->blueprint = $data->blueprints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Events\PluginsLoadedEvent;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use RuntimeException;
|
||||
use SplFileInfo;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
use function get_class;
|
||||
use function is_object;
|
||||
@@ -27,7 +28,7 @@ use function is_object;
|
||||
*/
|
||||
class Plugins extends Iterator
|
||||
{
|
||||
/** @var array */
|
||||
/** @var array|null */
|
||||
public $formFieldTypes;
|
||||
|
||||
/** @var bool */
|
||||
@@ -46,6 +47,7 @@ class Plugins extends Iterator
|
||||
$iterator = $locator->getIterator('plugins://');
|
||||
|
||||
$plugins = [];
|
||||
/** @var SplFileInfo $directory */
|
||||
foreach ($iterator as $directory) {
|
||||
if (!$directory->isDir()) {
|
||||
continue;
|
||||
@@ -56,7 +58,10 @@ class Plugins extends Iterator
|
||||
sort($plugins, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
|
||||
foreach ($plugins as $plugin) {
|
||||
$this->add($this->loadPlugin($plugin));
|
||||
$object = $this->loadPlugin($plugin);
|
||||
if ($object) {
|
||||
$this->add($object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,13 +73,21 @@ class Plugins extends Iterator
|
||||
$blueprints = [];
|
||||
$formFields = [];
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $grav['config'];
|
||||
|
||||
/** @var Plugin $plugin */
|
||||
foreach ($this->items as $plugin) {
|
||||
if (isset($plugin->features['blueprints'])) {
|
||||
$blueprints["plugin://{$plugin->name}/blueprints"] = $plugin->features['blueprints'];
|
||||
}
|
||||
if (method_exists($plugin, 'getFormFieldTypes')) {
|
||||
$formFields[get_class($plugin)] = isset($plugin->features['formfields']) ? $plugin->features['formfields'] : 0;
|
||||
// Setup only enabled plugins.
|
||||
if ($config["plugins.{$plugin->name}.enabled"] && $plugin instanceof Plugin) {
|
||||
if (isset($plugin->features['blueprints'])) {
|
||||
$blueprints["plugin://{$plugin->name}/blueprints"] = $plugin->features['blueprints'];
|
||||
}
|
||||
if (method_exists($plugin, 'getFormFieldTypes')) {
|
||||
$formFields[get_class($plugin)] = $plugin->features['formfields'] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +96,7 @@ class Plugins extends Iterator
|
||||
arsort($blueprints, SORT_NUMERIC);
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
$locator = $grav['locator'];
|
||||
$locator->addPath('blueprints', '', array_keys($blueprints), ['system', 'blueprints']);
|
||||
}
|
||||
|
||||
@@ -150,6 +163,7 @@ class Plugins extends Iterator
|
||||
* Add a plugin
|
||||
*
|
||||
* @param Plugin $plugin
|
||||
* @return void
|
||||
*/
|
||||
public function add($plugin)
|
||||
{
|
||||
@@ -175,8 +189,8 @@ class Plugins extends Iterator
|
||||
*/
|
||||
public static function getPlugins(): array
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$plugins = $grav['plugins'];
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = Grav::instance()['plugins'];
|
||||
|
||||
$list = [];
|
||||
foreach ($plugins as $instance) {
|
||||
@@ -200,11 +214,13 @@ class Plugins extends Iterator
|
||||
/**
|
||||
* Return list of all plugin data with their blueprints.
|
||||
*
|
||||
* @return array<string,Data>
|
||||
* @return Data[]
|
||||
*/
|
||||
public static function all()
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = $grav['plugins'];
|
||||
$list = [];
|
||||
|
||||
|
||||
@@ -105,8 +105,9 @@ class InitializeProcessor extends ProcessorBase
|
||||
$this->initializeUri($config);
|
||||
|
||||
// Grav may return redirect response right away.
|
||||
if ($config->get('system.pages.redirect_trailing_slash', false)) {
|
||||
$response = $this->handleRedirectRequest($request);
|
||||
$redirectCode = (int)$config->get('system.pages.redirect_trailing_slash', 1);
|
||||
if ($redirectCode) {
|
||||
$response = $this->handleRedirectRequest($request, $redirectCode > 300 ? $redirectCode : null);
|
||||
if ($response) {
|
||||
$this->stopTimer('_init');
|
||||
|
||||
@@ -413,7 +414,7 @@ class InitializeProcessor extends ProcessorBase
|
||||
$this->stopTimer('_init_uri');
|
||||
}
|
||||
|
||||
protected function handleRedirectRequest(RequestInterface $request): ?ResponseInterface
|
||||
protected function handleRedirectRequest(RequestInterface $request, int $code = null): ?ResponseInterface
|
||||
{
|
||||
if (!in_array($request->getMethod(), ['GET', 'HEAD'])) {
|
||||
return null;
|
||||
@@ -426,7 +427,7 @@ class InitializeProcessor extends ProcessorBase
|
||||
|
||||
if ($path !== $root && $path !== $root . '/' && Utils::endsWith($path, '/')) {
|
||||
// Use permanent redirect for SEO reasons.
|
||||
return $this->container->getRedirectResponse((string)$uri->withPath(rtrim($path, '/')), 301);
|
||||
return $this->container->getRedirectResponse((string)$uri->withPath(rtrim($path, '/')), $code);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -77,32 +77,46 @@ class PagesServiceProvider implements ServiceProviderInterface
|
||||
}
|
||||
}
|
||||
|
||||
$url = $pages->route($page->route());
|
||||
$route = $page->route();
|
||||
if ($route && \in_array($uri->method(), ['GET', 'HEAD'], true)) {
|
||||
$pageExtension = $page->urlExtension();
|
||||
$url = $pages->route($route) . $pageExtension;
|
||||
|
||||
if ($uri->params()) {
|
||||
if ($url === '/') { //Avoid double slash
|
||||
$url = $uri->params();
|
||||
} else {
|
||||
$url .= $uri->params();
|
||||
if ($uri->params()) {
|
||||
if ($url === '/') { //Avoid double slash
|
||||
$url = $uri->params();
|
||||
} else {
|
||||
$url .= $uri->params();
|
||||
}
|
||||
}
|
||||
if ($uri->query()) {
|
||||
$url .= '?' . $uri->query();
|
||||
}
|
||||
if ($uri->fragment()) {
|
||||
$url .= '#' . $uri->fragment();
|
||||
}
|
||||
}
|
||||
if ($uri->query()) {
|
||||
$url .= '?' . $uri->query();
|
||||
}
|
||||
if ($uri->fragment()) {
|
||||
$url .= '#' . $uri->fragment();
|
||||
}
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $grav['language'];
|
||||
/** @var Language $language */
|
||||
$language = $grav['language'];
|
||||
|
||||
// Language-specific redirection scenarios
|
||||
if ($language->enabled() && ($language->isLanguageInUrl() xor $language->isIncludeDefaultLanguage())) {
|
||||
$grav->redirect($url);
|
||||
}
|
||||
// Default route test and redirect
|
||||
if ($config->get('system.pages.redirect_default_route') && $page->route() !== $path) {
|
||||
$grav->redirect($url);
|
||||
$redirectCode = (int)$config->get('system.pages.redirect_default_route', 0);
|
||||
|
||||
// Language-specific redirection scenarios
|
||||
if ($language->enabled() && ($language->isLanguageInUrl() xor $language->isIncludeDefaultLanguage())) {
|
||||
$grav->redirect($url, $redirectCode);
|
||||
}
|
||||
|
||||
// Default route test and redirect
|
||||
if ($redirectCode) {
|
||||
$uriExtension = $uri->extension();
|
||||
$uriExtension = null !== $uriExtension ? '.' . $uriExtension : '';
|
||||
|
||||
if ($route !== $path || ($pageExtension !== $uriExtension
|
||||
&& \in_array($pageExtension, ['', '.htm', '.html'], true)
|
||||
&& \in_array($uriExtension, ['', '.htm', '.html'], true))) {
|
||||
$grav->redirect($url, $redirectCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Config\Config;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
/**
|
||||
* Class Theme
|
||||
@@ -44,53 +44,30 @@ class Theme extends Plugin
|
||||
/**
|
||||
* Persists to disk the theme parameters currently stored in the Grav Config object
|
||||
*
|
||||
* @param string $theme_name The name of the theme whose config it should store.
|
||||
* @param string $name The name of the theme whose config it should store.
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveConfig($theme_name)
|
||||
public static function saveConfig($name)
|
||||
{
|
||||
if (!$theme_name) {
|
||||
if (!$name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
$filename = 'config://themes/' . $theme_name . '.yaml';
|
||||
$file = YamlFile::instance($locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('themes.' . $theme_name);
|
||||
|
||||
$filename = 'config://themes/' . $name . '.yaml';
|
||||
$file = YamlFile::instance((string)$locator->findResource($filename, true, true));
|
||||
$content = $grav['config']->get('themes.' . $name);
|
||||
$file->save($content);
|
||||
$file->free();
|
||||
unset($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the mergeConfig method to work for themes
|
||||
*
|
||||
* @param PageInterface $page
|
||||
* @param string $deep
|
||||
* @param array $params
|
||||
* @param string $type
|
||||
* @return Data\Data
|
||||
*/
|
||||
protected function mergeConfig(PageInterface $page, $deep = 'merge', $params = [], $type = 'themes')
|
||||
{
|
||||
return parent::mergeConfig($page, $deep, $params, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simpler getter for the theme blueprint
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBlueprint()
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
$this->loadBlueprint();
|
||||
}
|
||||
return $this->blueprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load blueprints.
|
||||
*
|
||||
@@ -100,8 +77,11 @@ class Theme extends Plugin
|
||||
{
|
||||
if (!$this->blueprint) {
|
||||
$grav = Grav::instance();
|
||||
/** @var Themes $themes */
|
||||
$themes = $grav['themes'];
|
||||
$this->blueprint = $themes->get($this->name)->blueprints();
|
||||
$data = $themes->get($this->name);
|
||||
\assert($data !== null);
|
||||
$this->blueprint = $data->blueprints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,8 @@ class Themes extends Iterator
|
||||
{
|
||||
/** @var Grav */
|
||||
protected $grav;
|
||||
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
|
||||
/** @var bool */
|
||||
protected $inited = false;
|
||||
|
||||
@@ -95,6 +93,20 @@ class Themes extends Iterator
|
||||
$events->addSubscriber($instance);
|
||||
}
|
||||
|
||||
// Register blueprints.
|
||||
if (is_dir('theme://blueprints/pages')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
$locator->addPath('blueprints', '', ['theme://blueprints'], ['user', 'blueprints']);
|
||||
}
|
||||
|
||||
// Register form fields.
|
||||
if (method_exists($instance, 'getFormFieldTypes')) {
|
||||
/** @var Plugins $plugins */
|
||||
$plugins = $this->grav['plugins'];
|
||||
$plugins->formFieldTypes = $instance->getFormFieldTypes() + $plugins->formFieldTypes;
|
||||
}
|
||||
|
||||
$this->grav['theme'] = $instance;
|
||||
|
||||
$this->grav->fireEvent('onThemeInitialized');
|
||||
@@ -382,7 +394,10 @@ class Themes extends Iterator
|
||||
}
|
||||
|
||||
// Try Old style theme classes
|
||||
$path = strtolower(preg_replace('#\\\|_(?!.+\\\)#', '/', $class));
|
||||
$path = preg_replace('#\\\|_(?!.+\\\)#', '/', $class);
|
||||
\assert(null !== $path);
|
||||
|
||||
$path = strtolower($path);
|
||||
$file = $locator("themes://{$path}/theme.php") ?: $locator("themes://{$path}/{$path}.php");
|
||||
|
||||
// Load class
|
||||
|
||||
@@ -21,6 +21,7 @@ use RocketTheme\Toolbox\Event\Event;
|
||||
use RuntimeException;
|
||||
use function array_key_exists;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function is_string;
|
||||
use function strlen;
|
||||
@@ -394,7 +395,7 @@ class Uri
|
||||
* Return the Extension of the URI
|
||||
*
|
||||
* @param string|null $default
|
||||
* @return string The extension of the URI
|
||||
* @return string|null The extension of the URI
|
||||
*/
|
||||
public function extension($default = null)
|
||||
{
|
||||
@@ -1408,18 +1409,14 @@ class Uri
|
||||
/**
|
||||
* Check if this is a valid Grav extension
|
||||
*
|
||||
* @param string $extension
|
||||
* @param string|null $extension
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidExtension($extension)
|
||||
public function isValidExtension($extension): bool
|
||||
{
|
||||
$valid_page_types = implode('|', Utils::getSupportPageTypes());
|
||||
$extension = (string)$extension;
|
||||
|
||||
// Strip the file extension for valid page types
|
||||
if (preg_match('/(' . $valid_page_types . ')/', $extension)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $extension !== '' && in_array($extension, Utils::getSupportPageTypes(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user