mirror of
https://github.com/getgrav/grav.git
synced 2026-03-22 20:41:39 +01:00
Merge branches 'develop' and 'feature/blueprints-update' of https://github.com/getgrav/grav into feature/blueprints-update
# Conflicts: # system/src/Grav/Common/Plugins.php # system/src/Grav/Common/Themes.php
This commit is contained in:
@@ -100,7 +100,7 @@ What you mainly want to know is that:
|
||||
* [What is Grav?](http://learn.getgrav.org/basics/what-is-grav)
|
||||
* [Install](http://learn.getgrav.org/basics/installation) Grav in few seconds
|
||||
* Understand the [Configuration](http://learn.getgrav.org/basics/grav-configuration)
|
||||
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons#extras)
|
||||
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons)
|
||||
* If you have questions, jump on our [Gitter Room](https://gitter.im/getgrav/grav)!
|
||||
* Have fun!
|
||||
|
||||
|
||||
@@ -848,6 +848,13 @@ form:
|
||||
underline: true
|
||||
|
||||
fields:
|
||||
proxy_url:
|
||||
type: text
|
||||
size: medium
|
||||
placeholder: "e.g. 127.0.0.1:3128"
|
||||
label: PLUGIN_ADMIN.PROXY_URL
|
||||
help: PLUGIN_ADMIN.PROXY_URL_HELP
|
||||
|
||||
reverse_proxy_setup:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.REVERSE_PROXY
|
||||
|
||||
@@ -16,12 +16,12 @@ summary:
|
||||
delimiter: === # The summary delimiter
|
||||
|
||||
redirects:
|
||||
/redirect-test: / # Redirect test goes to home page
|
||||
/old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
|
||||
# /redirect-test: / # Redirect test goes to home page
|
||||
# /old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
|
||||
|
||||
routes:
|
||||
/something/else: '/blog/sample-3' # Alias for /blog/sample-3
|
||||
/new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
|
||||
# /something/else: '/blog/sample-3' # Alias for /blog/sample-3
|
||||
# /new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
|
||||
|
||||
blog:
|
||||
route: '/blog' # Custom value added (accessible via system.blog.route)
|
||||
|
||||
@@ -4,6 +4,7 @@ default_locale: # Default locale (defaults to system
|
||||
param_sep: ':' # Parameter separator, use ';' for Apache on windows
|
||||
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
|
||||
reverse_proxy_setup: false # Running in a reverse proxy scenario with different webserver ports than proxy
|
||||
proxy_url: # Configure a manual proxy URL for GPM (eg 127.0.0.1:3128)
|
||||
|
||||
languages:
|
||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
||||
|
||||
@@ -66,11 +66,11 @@ class Assets
|
||||
|
||||
// The asset holding arrays
|
||||
protected $collections = [];
|
||||
protected $css = [];
|
||||
protected $js = [];
|
||||
protected $inline_css = [];
|
||||
protected $inline_js = [];
|
||||
protected $imports = [];
|
||||
protected $css = [];
|
||||
protected $js = [];
|
||||
protected $inline_css = [];
|
||||
protected $inline_js = [];
|
||||
protected $imports = [];
|
||||
|
||||
// Some configuration variables
|
||||
protected $config;
|
||||
@@ -243,9 +243,9 @@ class Assets
|
||||
* You may add more than one asset passing an array as argument.
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param null $group
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param null $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -255,9 +255,11 @@ class Assets
|
||||
foreach ($asset as $a) {
|
||||
$this->addCss($a, $priority, $pipeline, $group);
|
||||
}
|
||||
|
||||
return $this;
|
||||
} elseif (isset($this->collections[$asset])) {
|
||||
$this->addCss($this->collections[$asset], $priority, $pipeline, $group);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -274,8 +276,8 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->css),
|
||||
'pipeline' => (bool) $pipeline,
|
||||
'group' => $group ?: 'head'
|
||||
'pipeline' => (bool)$pipeline,
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
@@ -300,11 +302,12 @@ class Assets
|
||||
* It checks for duplicates.
|
||||
* You may add more than one asset passing an array as argument.
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param string $loading how the asset is loaded (async/defer)
|
||||
* @param string $group name of the group
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param string $loading how the asset is loaded (async/defer)
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addJs($asset, $priority = null, $pipeline = true, $loading = null, $group = null)
|
||||
@@ -313,9 +316,11 @@ class Assets
|
||||
foreach ($asset as $a) {
|
||||
$this->addJs($a, $priority, $pipeline, $loading, $group);
|
||||
}
|
||||
|
||||
return $this;
|
||||
} elseif (isset($this->collections[$asset])) {
|
||||
$this->addJs($this->collections[$asset], $priority, $pipeline, $loading, $group);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -332,9 +337,9 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->js),
|
||||
'pipeline' => (bool) $pipeline,
|
||||
'pipeline' => (bool)$pipeline,
|
||||
'loading' => $loading ?: '',
|
||||
'group' => $group ?: 'head'
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
@@ -356,9 +361,9 @@ class Assets
|
||||
/**
|
||||
* Convenience wrapper for async loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'async']
|
||||
@@ -373,9 +378,9 @@ class Assets
|
||||
/**
|
||||
* Convenience wrapper for deferred loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'defer']
|
||||
@@ -394,8 +399,8 @@ class Assets
|
||||
* For adding chunks of string-based inline CSS
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param null $group
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param null $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -404,17 +409,17 @@ class Assets
|
||||
$asset = trim($asset);
|
||||
|
||||
if (is_a($asset, 'Twig_Markup')) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
|
||||
if (isset($matches[3])) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches);
|
||||
if (isset($matches[3])) {
|
||||
$asset = $matches[3];
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->inline_css),
|
||||
'asset' => $asset,
|
||||
'group' => $group ?: 'head'
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->inline_css),
|
||||
'asset' => $asset,
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
@@ -441,7 +446,7 @@ class Assets
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param string $group name of the group
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -450,8 +455,8 @@ class Assets
|
||||
$asset = trim($asset);
|
||||
|
||||
if (is_a($asset, 'Twig_Markup')) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
|
||||
if (isset($matches[3])) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches);
|
||||
if (isset($matches[3])) {
|
||||
$asset = $matches[3];
|
||||
}
|
||||
}
|
||||
@@ -460,7 +465,7 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->js),
|
||||
'group' => $group ?: 'head'
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
@@ -483,7 +488,7 @@ class Assets
|
||||
* Build the CSS link tags.
|
||||
*
|
||||
* @param string $group name of the group
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -499,6 +504,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
|
||||
@@ -506,6 +512,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
}
|
||||
@@ -556,7 +563,7 @@ class Assets
|
||||
* Build the JavaScript script tags.
|
||||
*
|
||||
* @param string $group name of the group
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -571,6 +578,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
|
||||
@@ -578,6 +586,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
|
||||
@@ -596,7 +605,7 @@ class Assets
|
||||
}
|
||||
foreach ($this->js_no_pipeline as $file) {
|
||||
if ($group && $file['group'] == $group) {
|
||||
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading']. '></script>' . "\n";
|
||||
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading'] . '></script>' . "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -625,6 +634,7 @@ class Assets
|
||||
* Minify and concatenate CSS
|
||||
*
|
||||
* @param string $group
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function pipelineCss($group = 'head')
|
||||
@@ -695,6 +705,7 @@ class Assets
|
||||
* Minify and concatenate JS files.
|
||||
*
|
||||
* @param string $group
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pipelineJs($group = 'head')
|
||||
@@ -744,6 +755,7 @@ class Assets
|
||||
// Write file
|
||||
if (strlen(trim($buffer)) > 0) {
|
||||
file_put_contents($absolute_path, $buffer);
|
||||
|
||||
return $relative_path . $key;
|
||||
} else {
|
||||
return false;
|
||||
@@ -789,9 +801,7 @@ class Assets
|
||||
*/
|
||||
public function exists($asset)
|
||||
{
|
||||
if (isset($this->collections[$asset]) ||
|
||||
isset($this->css[$asset]) ||
|
||||
isset($this->js[$asset])) {
|
||||
if (isset($this->collections[$asset]) || isset($this->css[$asset]) || isset($this->js[$asset])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -834,6 +844,7 @@ class Assets
|
||||
public function resetJs()
|
||||
{
|
||||
$this->js = [];
|
||||
$this->inline_js = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -846,14 +857,27 @@ class Assets
|
||||
public function resetCss()
|
||||
{
|
||||
$this->css = [];
|
||||
$this->inline_css = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all CSS assets within $directory (relative to public dir).
|
||||
* Add all JavaScript assets within $directory
|
||||
*
|
||||
* @param string $directory Relative to $this->public_dir
|
||||
* @param string $directory Relative to the Grav root path, or a stream identifier
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDirJs($directory)
|
||||
{
|
||||
return $this->addDir($directory, self::JS_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all CSS assets within $directory
|
||||
*
|
||||
* @param string $directory Relative to the Grav root path, or a stream identifier
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -865,7 +889,7 @@ class Assets
|
||||
/**
|
||||
* Add all assets matching $pattern within $directory.
|
||||
*
|
||||
* @param string $directory Relative to $this->public_dir
|
||||
* @param string $directory Relative to the Grav root path, or a stream identifier
|
||||
* @param string $pattern (regex)
|
||||
*
|
||||
* @return $this
|
||||
@@ -873,13 +897,15 @@ class Assets
|
||||
*/
|
||||
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
|
||||
{
|
||||
// Check if public_dir exists
|
||||
if (!is_dir($this->assets_dir)) {
|
||||
throw new Exception('Assets: Public dir not found');
|
||||
$root_dir = rtrim(ROOT_DIR, '/');
|
||||
|
||||
// Check if $directory is a stream.
|
||||
if (strpos($directory, '://')) {
|
||||
$directory = self::$grav['locator']->findResource($directory, null);
|
||||
}
|
||||
|
||||
// Get files
|
||||
$files = $this->rglob($this->assets_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->assets_dir);
|
||||
$files = $this->rglob($root_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $root_dir . '/');
|
||||
|
||||
// No luck? Nothing to do
|
||||
if (!$files) {
|
||||
@@ -888,27 +914,25 @@ class Assets
|
||||
|
||||
// Add CSS files
|
||||
if ($pattern === self::CSS_REGEX) {
|
||||
$this->css = array_unique(array_merge($this->css, $files));
|
||||
foreach ($files as $file) {
|
||||
$this->addCss($file);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Add JavaScript files
|
||||
if ($pattern === self::JS_REGEX) {
|
||||
$this->js = array_unique(array_merge($this->js, $files));
|
||||
foreach ($files as $file) {
|
||||
$this->addJs($file);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Unknown pattern. We must poll to know the extension :(
|
||||
// Unknown pattern.
|
||||
foreach ($files as $asset) {
|
||||
$info = pathinfo($asset);
|
||||
if (isset($info['extension'])) {
|
||||
$ext = strtolower($info['extension']);
|
||||
if ($ext === 'css' && !in_array($asset, $this->css)) {
|
||||
$this->css[] = $asset;
|
||||
} elseif ($ext === 'js' && !in_array($asset, $this->js)) {
|
||||
$this->js[] = $asset;
|
||||
}
|
||||
}
|
||||
$this->add($asset);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -925,8 +949,8 @@ class Assets
|
||||
*/
|
||||
protected function isRemoteLink($link)
|
||||
{
|
||||
return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8)
|
||||
|| '//' === substr($link, 0, 2));
|
||||
return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8) || '//' === substr($link, 0,
|
||||
2));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -979,7 +1003,7 @@ class Assets
|
||||
* Download and concatenate the content of several links.
|
||||
*
|
||||
* @param array $links
|
||||
* @param bool $css
|
||||
* @param bool $css
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -1041,8 +1065,8 @@ class Assets
|
||||
/**
|
||||
* Finds relative CSS urls() and rewrites the URL with an absolute one
|
||||
*
|
||||
* @param string $file the css source file
|
||||
* @param string $relative_path relative path to the css file
|
||||
* @param string $file the css source file
|
||||
* @param string $relative_path relative path to the css file
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -1053,23 +1077,19 @@ class Assets
|
||||
|
||||
// Find any css url() elements, grab the URLs and calculate an absolute path
|
||||
// Then replace the old url with the new one
|
||||
$file = preg_replace_callback(
|
||||
self::CSS_URL_REGEX,
|
||||
function ($matches) use ($relative_path) {
|
||||
$file = preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use ($relative_path) {
|
||||
|
||||
$old_url = $matches[1];
|
||||
$old_url = $matches[1];
|
||||
|
||||
// ensure this is not a data url
|
||||
if (strpos($old_url, 'data:') === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
// ensure this is not a data url
|
||||
if (strpos($old_url, 'data:') === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
|
||||
$new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
|
||||
|
||||
return str_replace($old_url, $new_url, $matches[0]);
|
||||
},
|
||||
$file
|
||||
);
|
||||
return str_replace($old_url, $new_url, $matches[0]);
|
||||
}, $file);
|
||||
|
||||
return $file;
|
||||
}
|
||||
@@ -1085,14 +1105,11 @@ class Assets
|
||||
{
|
||||
$this->imports = [];
|
||||
|
||||
$file = preg_replace_callback(
|
||||
self::CSS_IMPORT_REGEX,
|
||||
function ($matches) {
|
||||
$this->imports[] = $matches[0];
|
||||
return '';
|
||||
},
|
||||
$file
|
||||
);
|
||||
$file = preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) {
|
||||
$this->imports[] = $matches[0];
|
||||
|
||||
return '';
|
||||
}, $file);
|
||||
|
||||
return implode("\n", $this->imports) . "\n\n" . $file;
|
||||
}
|
||||
@@ -1108,15 +1125,8 @@ class Assets
|
||||
*/
|
||||
protected function rglob($directory, $pattern, $ltrim = null)
|
||||
{
|
||||
$iterator = new RegexIterator(
|
||||
new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator(
|
||||
$directory,
|
||||
FilesystemIterator::SKIP_DOTS
|
||||
)
|
||||
),
|
||||
$pattern
|
||||
);
|
||||
$iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory,
|
||||
FilesystemIterator::SKIP_DOTS)), $pattern);
|
||||
$offset = strlen($ltrim);
|
||||
$files = [];
|
||||
|
||||
@@ -1127,18 +1137,6 @@ class Assets
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all JavaScript assets within $directory.
|
||||
*
|
||||
* @param string $directory Relative to $this->public_dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDirJs($directory)
|
||||
{
|
||||
return $this->addDir($directory, self::JS_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of CSS Pipeline
|
||||
*
|
||||
@@ -1146,7 +1144,7 @@ class Assets
|
||||
*/
|
||||
public function setCssPipeline($value)
|
||||
{
|
||||
$this->css_pipeline = (bool) $value;
|
||||
$this->css_pipeline = (bool)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1156,7 +1154,7 @@ class Assets
|
||||
*/
|
||||
public function setJsPipeline($value)
|
||||
{
|
||||
$this->js_pipeline = (bool) $value;
|
||||
$this->js_pipeline = (bool)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1166,7 +1164,7 @@ class Assets
|
||||
*/
|
||||
public function setTimestamp($value)
|
||||
{
|
||||
$this->timestamp = '?'.$value;
|
||||
$this->timestamp = '?' . $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,14 @@ class ZipBackup
|
||||
'.idea'
|
||||
];
|
||||
|
||||
/**
|
||||
* Backup
|
||||
*
|
||||
* @param null $destination
|
||||
* @param callable|null $messager
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function backup($destination = null, callable $messager = null)
|
||||
{
|
||||
if (!$destination) {
|
||||
|
||||
@@ -13,6 +13,9 @@ class Browser
|
||||
{
|
||||
protected $useragent = [];
|
||||
|
||||
/**
|
||||
* Browser constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
@@ -107,6 +110,7 @@ class Browser
|
||||
public function getVersion()
|
||||
{
|
||||
$version = explode('.', $this->getLongVersion());
|
||||
|
||||
return intval($version[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use \Doctrine\Common\Cache\Cache as DoctrineCache;
|
||||
use \Doctrine\Common\Cache as DoctrineCache;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
|
||||
@@ -16,7 +16,7 @@ use Grav\Common\Filesystem\Folder;
|
||||
* MemCacheD
|
||||
* FileSystem
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Cache extends Getters
|
||||
@@ -31,10 +31,11 @@ class Cache extends Getters
|
||||
protected $lifetime;
|
||||
protected $now;
|
||||
|
||||
/** @var Config $config */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var DoctrineCache
|
||||
* @var DoctrineCache\CacheProvider
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
@@ -79,7 +80,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @params Grav $grav
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
@@ -90,6 +91,7 @@ class Cache extends Getters
|
||||
* Initialization that sets a base key and the driver based on configuration settings
|
||||
*
|
||||
* @param Grav $grav
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init(Grav $grav)
|
||||
@@ -105,10 +107,11 @@ class Cache extends Getters
|
||||
|
||||
$prefix = $this->config->get('system.cache.prefix');
|
||||
|
||||
$this->enabled = (bool) $this->config->get('system.cache.enabled');
|
||||
$this->enabled = (bool)$this->config->get('system.cache.enabled');
|
||||
|
||||
// Cache key allows us to invalidate all cache on configuration changes.
|
||||
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
|
||||
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION),
|
||||
2, 8);
|
||||
|
||||
$this->driver_setting = $this->config->get('system.cache.driver');
|
||||
|
||||
@@ -127,7 +130,7 @@ class Cache extends Getters
|
||||
* If there is no config option for $driver in the config, or it's set to 'auto', it will
|
||||
* pick the best option based on which cache extensions are installed.
|
||||
*
|
||||
* @return DoctrineCacheDriver The cache driver to use
|
||||
* @return DoctrineCache\CacheProvider The cache driver to use
|
||||
*/
|
||||
public function getCacheDriver()
|
||||
{
|
||||
@@ -152,40 +155,40 @@ class Cache extends Getters
|
||||
|
||||
switch ($driver_name) {
|
||||
case 'apc':
|
||||
$driver = new \Doctrine\Common\Cache\ApcCache();
|
||||
$driver = new DoctrineCache\ApcCache();
|
||||
break;
|
||||
|
||||
case 'apcu':
|
||||
$driver = new \Doctrine\Common\Cache\ApcuCache();
|
||||
$driver = new DoctrineCache\ApcuCache();
|
||||
break;
|
||||
|
||||
case 'wincache':
|
||||
$driver = new \Doctrine\Common\Cache\WinCacheCache();
|
||||
$driver = new DoctrineCache\WinCacheCache();
|
||||
break;
|
||||
|
||||
case 'xcache':
|
||||
$driver = new \Doctrine\Common\Cache\XcacheCache();
|
||||
$driver = new DoctrineCache\XcacheCache();
|
||||
break;
|
||||
|
||||
case 'memcache':
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect($this->config->get('system.cache.memcache.server','localhost'),
|
||||
$this->config->get('system.cache.memcache.port', 11211));
|
||||
$driver = new \Doctrine\Common\Cache\MemcacheCache();
|
||||
$memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcache.port', 11211));
|
||||
$driver = new DoctrineCache\MemcacheCache();
|
||||
$driver->setMemcache($memcache);
|
||||
break;
|
||||
|
||||
case 'redis':
|
||||
$redis = new \Redis();
|
||||
$redis->connect($this->config->get('system.cache.redis.server','localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
|
||||
$driver = new \Doctrine\Common\Cache\RedisCache();
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
break;
|
||||
|
||||
default:
|
||||
$driver = new \Doctrine\Common\Cache\FilesystemCache($this->cache_dir);
|
||||
$driver = new DoctrineCache\FilesystemCache($this->cache_dir);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -196,6 +199,7 @@ class Cache extends Getters
|
||||
* Gets a cached entry if it exists based on an id. If it does not exist, it returns false
|
||||
*
|
||||
* @param string $id the id of the cached entry
|
||||
*
|
||||
* @return object returns the cached entry, can be any type, or false if doesn't exist
|
||||
*/
|
||||
public function fetch($id)
|
||||
@@ -210,9 +214,9 @@ class Cache extends Getters
|
||||
/**
|
||||
* Stores a new cached entry.
|
||||
*
|
||||
* @param string $id the id of the cached entry
|
||||
* @param string $id the id of the cached entry
|
||||
* @param array|object $data the data for the cached entry to store
|
||||
* @param int $lifetime the lifetime to store the entry in seconds
|
||||
* @param int $lifetime the lifetime to store the entry in seconds
|
||||
*/
|
||||
public function save($id, $data, $lifetime = null)
|
||||
{
|
||||
@@ -235,7 +239,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* Helper method to clear all Grav caches
|
||||
*
|
||||
* @param string $remove standard|all|assets-only|images-only|cache-only
|
||||
* @param string $remove standard|all|assets-only|images-only|cache-only
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -245,7 +249,7 @@ class Cache extends Getters
|
||||
$output = [];
|
||||
$user_config = USER_DIR . 'config/system.yaml';
|
||||
|
||||
switch($remove) {
|
||||
switch ($remove) {
|
||||
case 'all':
|
||||
$remove_paths = self::$all_remove;
|
||||
break;
|
||||
@@ -268,8 +272,9 @@ class Cache extends Getters
|
||||
// Convert stream to a real path
|
||||
$path = $locator->findResource($stream, true, true);
|
||||
// Make sure path exists before proceeding, otherwise we would wipe ROOT_DIR
|
||||
if (!$path)
|
||||
if (!$path) {
|
||||
throw new \RuntimeException("Stream '{$stream}' not found", 500);
|
||||
}
|
||||
|
||||
$anything = false;
|
||||
$files = glob($path . '/*');
|
||||
|
||||
@@ -35,6 +35,11 @@ class Composer
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the composer executable file path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getComposerExecutor()
|
||||
{
|
||||
$executor = PHP_BINARY . ' ';
|
||||
|
||||
@@ -559,6 +559,10 @@ class Validation
|
||||
$options = isset($field['options']) ? array_keys($field['options']) : array();
|
||||
$multi = isset($field['multiple']) ? $field['multiple'] : false;
|
||||
|
||||
if (count($values) == 1 && isset($values[0]) && $values[0] == '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($options) {
|
||||
$useKey = isset($field['use']) && $field['use'] == 'keys';
|
||||
foreach ($values as $key => $value) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use DebugBar\DataCollector\ConfigCollector;
|
||||
use DebugBar\JavascriptRenderer;
|
||||
use DebugBar\StandardDebugBar;
|
||||
use Grav\Common\Config\Config;
|
||||
|
||||
/**
|
||||
* Class Debugger
|
||||
@@ -10,45 +12,79 @@ use DebugBar\StandardDebugBar;
|
||||
*/
|
||||
class Debugger
|
||||
{
|
||||
/** @var Grav $grav */
|
||||
protected $grav;
|
||||
protected $debugbar;
|
||||
|
||||
/** @var Config $config */
|
||||
protected $config;
|
||||
|
||||
/** @var JavascriptRenderer $renderer */
|
||||
protected $renderer;
|
||||
|
||||
/** @var StandardDebugBar $debugbar */
|
||||
protected $debugbar;
|
||||
|
||||
protected $enabled;
|
||||
|
||||
protected $timers = [];
|
||||
|
||||
/**
|
||||
* Debugger constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->debugbar = new StandardDebugBar();
|
||||
$this->debugbar['time']->addMeasure('Loading', $this->debugbar['time']->getRequestStartTime(), microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the debugger
|
||||
*
|
||||
* @return $this
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->grav = Grav::instance();
|
||||
$this->config = $this->grav['config'];
|
||||
|
||||
if ($this->enabled()) {
|
||||
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('system'), 'Config'));
|
||||
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('plugins'), 'Plugins'));
|
||||
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('system'), 'Config'));
|
||||
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('plugins'), 'Plugins'));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/get the enabled state of the debugger
|
||||
*
|
||||
* @param bool $state If null, the method returns the enabled value. If set, the method sets the enabled state
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function enabled($state = null)
|
||||
{
|
||||
if (isset($state)) {
|
||||
$this->enabled = $state;
|
||||
} else {
|
||||
if (!isset($this->enabled)) {
|
||||
$this->enabled = $this->grav['config']->get('system.debugger.enabled');
|
||||
$this->enabled = $this->config->get('system.debugger.enabled');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the debugger assets to the Grav Assets
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addAssets()
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
/** @var Assets $assets */
|
||||
$assets = $this->grav['assets'];
|
||||
|
||||
// Add jquery library
|
||||
@@ -69,58 +105,113 @@ class Debugger
|
||||
$assets->addJs($js);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a data collector
|
||||
*
|
||||
* @param $collector
|
||||
*
|
||||
* @return $this
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function addCollector($collector)
|
||||
{
|
||||
$this->debugbar->addCollector($collector);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data collector
|
||||
*
|
||||
* @param $collector
|
||||
*
|
||||
* @return \DebugBar\DataCollector\DataCollectorInterface
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function getCollector($collector)
|
||||
{
|
||||
return $this->debugbar->getCollector($collector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the debug bar
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
echo $this->renderer->render();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data through the HTTP headers
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sendDataInHeaders()
|
||||
{
|
||||
$this->debugbar->sendDataInHeaders();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a timer with an associated name and description
|
||||
*
|
||||
* @param $name
|
||||
* @param string|null $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function startTimer($name, $description = null)
|
||||
{
|
||||
if ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled')) {
|
||||
if ($name[0] == '_' || $this->config->get('system.debugger.enabled')) {
|
||||
$this->debugbar['time']->startMeasure($name, $description);
|
||||
$this->timers[] = $name;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the named timer
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stopTimer($name)
|
||||
{
|
||||
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled'))) {
|
||||
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->config->get('system.debugger.enabled'))) {
|
||||
$this->debugbar['time']->stopMeasure($name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump variables into the Messages tab of the Debug Bar
|
||||
*
|
||||
* @param $message
|
||||
* @param string $label
|
||||
* @param bool $isString
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addMessage($message, $label = 'info', $isString = true)
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
$this->debugbar['messages']->addMessage($message, $label, $isString);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,8 +64,9 @@ abstract class Folder
|
||||
/**
|
||||
* Get relative path between target and base path. If path isn't relative, return full path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $base
|
||||
* @param string $path
|
||||
* @param mixed|string $base
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getRelativePath($path, $base = GRAV_ROOT)
|
||||
@@ -141,7 +142,7 @@ abstract class Folder
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public static function all($path, array $params = array())
|
||||
public static function all($path, array $params = [])
|
||||
{
|
||||
if ($path === false) {
|
||||
throw new \RuntimeException("Path to {$path} doesn't exist.");
|
||||
@@ -166,7 +167,7 @@ abstract class Folder
|
||||
$iterator = new \FilesystemIterator($path);
|
||||
}
|
||||
|
||||
$results = array();
|
||||
$results = [];
|
||||
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
|
||||
@@ -3,12 +3,21 @@ namespace Grav\Common\Filesystem;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
|
||||
/**
|
||||
* Class RecursiveFolderFilterIterator
|
||||
* @package Grav\Common\Filesystem
|
||||
*/
|
||||
class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
protected static $folder_ignores;
|
||||
|
||||
/**
|
||||
* Create a RecursiveFilterIterator from a RecursiveIterator
|
||||
*
|
||||
* @param RecursiveIterator $iterator
|
||||
*/
|
||||
public function __construct(\RecursiveIterator $iterator)
|
||||
{
|
||||
parent::__construct($iterator);
|
||||
@@ -17,9 +26,13 @@ class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current element of the iterator is acceptable
|
||||
*
|
||||
* @return bool true if the current element is acceptable, otherwise false.
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
|
||||
/** @var $current \SplFileInfo */
|
||||
$current = $this->current();
|
||||
|
||||
|
||||
@@ -2,9 +2,12 @@
|
||||
namespace Grav\Common\GPM;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\GravTrait;
|
||||
|
||||
class Response
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/**
|
||||
* The callback for the progress
|
||||
*
|
||||
@@ -192,6 +195,12 @@ class Response
|
||||
$options = $args[1];
|
||||
$callback = $args[2];
|
||||
|
||||
// if proxy set add that
|
||||
$proxy_url = self::getGrav()['config']->get('system.proxy_url');
|
||||
if ($proxy_url) {
|
||||
$options['fopen']['proxy'] = $proxy_url;
|
||||
}
|
||||
|
||||
if ($callback) {
|
||||
$options['fopen']['notification'] = ['self', 'progress'];
|
||||
}
|
||||
@@ -246,6 +255,12 @@ class Response
|
||||
);
|
||||
}
|
||||
|
||||
// if proxy set add that
|
||||
$proxy_url = self::getGrav()['config']->get('system.proxy_url');
|
||||
if ($proxy_url) {
|
||||
$options['curl'][CURLOPT_PROXY] = $proxy_url;
|
||||
}
|
||||
|
||||
// no open_basedir set, we can proceed normally
|
||||
if (!ini_get('open_basedir')) {
|
||||
curl_setopt_array($ch, $options['curl']);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Grav\Common;
|
||||
* Abstract class to implement magic __get(), __set(), __isset() and __unset().
|
||||
* Also implements ArrayAccess.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
abstract class Getters implements \ArrayAccess, \Countable
|
||||
@@ -32,6 +32,7 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
* Magic getter method
|
||||
*
|
||||
* @param mixed $offset Medium name value
|
||||
*
|
||||
* @return mixed Medium value
|
||||
*/
|
||||
public function __get($offset)
|
||||
@@ -42,7 +43,8 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
/**
|
||||
* Magic method to determine if the attribute is set
|
||||
*
|
||||
* @param mixed $offset Medium name value
|
||||
* @param mixed $offset Medium name value
|
||||
*
|
||||
* @return boolean True if the value is set
|
||||
*/
|
||||
public function __isset($offset)
|
||||
@@ -62,12 +64,14 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
if ($this->gettersVariable) {
|
||||
$var = $this->gettersVariable;
|
||||
|
||||
return isset($this->{$var}[$offset]);
|
||||
} else {
|
||||
return isset($this->{$offset});
|
||||
@@ -76,12 +80,14 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->gettersVariable) {
|
||||
$var = $this->gettersVariable;
|
||||
|
||||
return isset($this->{$var}[$offset]) ? $this->{$var}[$offset] : null;
|
||||
} else {
|
||||
return isset($this->{$offset}) ? $this->{$offset} : null;
|
||||
@@ -137,13 +143,17 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
{
|
||||
if ($this->gettersVariable) {
|
||||
$var = $this->gettersVariable;
|
||||
|
||||
return $this->{$var};
|
||||
} else {
|
||||
$properties = (array) $this;
|
||||
$list = array();
|
||||
$properties = (array)$this;
|
||||
$list = [];
|
||||
foreach ($properties as $property => $value) {
|
||||
if ($property[0] != "\0") $list[$property] = $value;
|
||||
if ($property[0] != "\0") {
|
||||
$list[$property] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Medium\ImageMedium;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Service\ConfigServiceProvider;
|
||||
use Grav\Common\Service\ErrorServiceProvider;
|
||||
@@ -16,8 +19,8 @@ use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
/**
|
||||
* Grav
|
||||
*
|
||||
* @author Andy Miller
|
||||
* @link http://www.rockettheme.com
|
||||
* @author Andy Miller
|
||||
* @link http://www.rockettheme.com
|
||||
* @license http://opensource.org/licenses/MIT
|
||||
*
|
||||
* Influenced by Pico, Stacey, Kirby, PieCrust and other great platforms...
|
||||
@@ -34,7 +37,14 @@ class Grav extends Container
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
public static function instance(array $values = array())
|
||||
/**
|
||||
* Return the Grav instance. Create it if it's not already instanced
|
||||
*
|
||||
* @param array $values
|
||||
*
|
||||
* @return Grav
|
||||
*/
|
||||
public static function instance(array $values = [])
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = static::load($values);
|
||||
@@ -51,6 +61,13 @@ class Grav extends Container
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and return a Grav instance
|
||||
*
|
||||
* @param array $values
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
protected static function load(array $values)
|
||||
{
|
||||
$container = new static($values);
|
||||
@@ -65,45 +82,56 @@ class Grav extends Container
|
||||
$container->register(new ErrorServiceProvider);
|
||||
|
||||
$container['uri'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Uri($c);
|
||||
};
|
||||
|
||||
$container['task'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return !empty($_POST['task']) ? $_POST['task'] : $c['uri']->param('task');
|
||||
};
|
||||
|
||||
$container['events'] = function ($c) {
|
||||
$container['events'] = function () {
|
||||
return new EventDispatcher;
|
||||
};
|
||||
$container['cache'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Cache($c);
|
||||
};
|
||||
$container['session'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Session($c);
|
||||
};
|
||||
$container['plugins'] = function ($c) {
|
||||
$container['plugins'] = function () {
|
||||
return new Plugins();
|
||||
};
|
||||
$container['themes'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Themes($c);
|
||||
};
|
||||
$container['twig'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Twig($c);
|
||||
};
|
||||
$container['taxonomy'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Taxonomy($c);
|
||||
};
|
||||
$container['language'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Language($c);
|
||||
};
|
||||
|
||||
$container['pages'] = function ($c) {
|
||||
return new Page\Pages($c);
|
||||
/** @var Grav $c */
|
||||
return new Pages($c);
|
||||
};
|
||||
|
||||
$container['assets'] = new Assets();
|
||||
|
||||
$container['page'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $c['pages'];
|
||||
/** @var Language $language */
|
||||
@@ -138,7 +166,7 @@ class Grav extends Container
|
||||
if (!$page || !$page->routable()) {
|
||||
|
||||
// Try fallback URL stuff...
|
||||
$c->fallbackUrl($page, $path);
|
||||
$c->fallbackUrl($path);
|
||||
|
||||
// If no page found, fire event
|
||||
$event = $c->fireEvent('onPageNotFound');
|
||||
@@ -149,22 +177,31 @@ class Grav extends Container
|
||||
throw new \RuntimeException('Page Not Found', 404);
|
||||
}
|
||||
}
|
||||
|
||||
return $page;
|
||||
};
|
||||
|
||||
$container['output'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return $c['twig']->processSite($c['uri']->extension());
|
||||
};
|
||||
$container['browser'] = function ($c) {
|
||||
|
||||
$container['browser'] = function () {
|
||||
return new Browser();
|
||||
};
|
||||
|
||||
$container['base_url_absolute'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return $c['config']->get('system.base_url_absolute') ?: $c['uri']->rootUrl(true);
|
||||
};
|
||||
|
||||
$container['base_url_relative'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return $c['config']->get('system.base_url_relative') ?: $c['uri']->rootUrl(false);
|
||||
};
|
||||
|
||||
$container['base_url'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return $c['config']->get('system.absolute_urls') ? $c['base_url_absolute'] : $c['base_url_relative'];
|
||||
};
|
||||
|
||||
@@ -178,6 +215,9 @@ class Grav extends Container
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a request
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
/** @var Debugger $debugger */
|
||||
@@ -207,7 +247,7 @@ class Grav extends Container
|
||||
ob_start();
|
||||
if ($this['config']->get('system.cache.gzip')) {
|
||||
// Enable zip/deflate with a fallback in case of if browser does not support compressing.
|
||||
if(!ob_start("ob_gzhandler")) {
|
||||
if (!ob_start("ob_gzhandler")) {
|
||||
ob_start();
|
||||
}
|
||||
}
|
||||
@@ -279,7 +319,7 @@ class Grav extends Container
|
||||
* Redirect browser to another location.
|
||||
*
|
||||
* @param string $route Internal route.
|
||||
* @param int $code Redirection code (30x)
|
||||
* @param int $code Redirection code (30x)
|
||||
*/
|
||||
public function redirect($route, $code = null)
|
||||
{
|
||||
@@ -305,10 +345,13 @@ class Grav extends Container
|
||||
if ($uri->isExternal($route)) {
|
||||
$url = $route;
|
||||
} else {
|
||||
if ($this['config']->get('system.pages.redirect_trailing_slash', true))
|
||||
$url = rtrim($uri->rootUrl(), '/') .'/'. trim($route, '/'); // Remove trailing slash
|
||||
else
|
||||
$url = rtrim($uri->rootUrl(), '/') .'/'. ltrim($route, '/'); // Support trailing slash default routes
|
||||
$url = rtrim($uri->rootUrl(), '/') . '/';
|
||||
|
||||
if ($this['config']->get('system.pages.redirect_trailing_slash', true)) {
|
||||
$url .= trim($route, '/'); // Remove trailing slash
|
||||
} else {
|
||||
$url .= ltrim($route, '/'); // Support trailing slash default routes
|
||||
}
|
||||
}
|
||||
|
||||
header("Location: {$url}", true, $code);
|
||||
@@ -319,7 +362,7 @@ class Grav extends Container
|
||||
* Redirect browser to another location taking language into account (preferred)
|
||||
*
|
||||
* @param string $route Internal route.
|
||||
* @param int $code Redirection code (30x)
|
||||
* @param int $code Redirection code (30x)
|
||||
*/
|
||||
public function redirectLangSafe($route, $code = null)
|
||||
{
|
||||
@@ -327,9 +370,9 @@ class Grav extends Container
|
||||
$language = $this['language'];
|
||||
|
||||
if (!$this['uri']->isExternal($route) && $language->enabled() && $language->isIncludeDefaultLanguage()) {
|
||||
return $this->redirect($language->getLanguage() . $route, $code);
|
||||
$this->redirect($language->getLanguage() . $route, $code);
|
||||
} else {
|
||||
return $this->redirect($route, $code);
|
||||
$this->redirect($route, $code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,6 +380,7 @@ class Grav extends Container
|
||||
* Returns mime type for the file format.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mime($format)
|
||||
@@ -353,6 +397,7 @@ class Grav extends Container
|
||||
case 'xml':
|
||||
return 'application/xml';
|
||||
}
|
||||
|
||||
return 'text/html';
|
||||
}
|
||||
|
||||
@@ -374,7 +419,7 @@ class Grav extends Container
|
||||
if ($expires > 0) {
|
||||
$expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT';
|
||||
header('Cache-Control: max-age=' . $expires);
|
||||
header('Expires: '. $expires_date);
|
||||
header('Expires: ' . $expires_date);
|
||||
}
|
||||
|
||||
// Set the last modified time
|
||||
@@ -409,12 +454,14 @@ class Grav extends Container
|
||||
*
|
||||
* @param string $eventName
|
||||
* @param Event $event
|
||||
*
|
||||
* @return Event
|
||||
*/
|
||||
public function fireEvent($eventName, Event $event = null)
|
||||
{
|
||||
/** @var EventDispatcher $events */
|
||||
$events = $this['events'];
|
||||
|
||||
return $events->dispatch($eventName, $event);
|
||||
}
|
||||
|
||||
@@ -472,10 +519,10 @@ class Grav extends Container
|
||||
|
||||
/**
|
||||
* This attempts to find media, other files, and download them
|
||||
* @param $page
|
||||
*
|
||||
* @param $path
|
||||
*/
|
||||
protected function fallbackUrl($page, $path)
|
||||
protected function fallbackUrl($path)
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
@@ -495,20 +542,22 @@ class Grav extends Container
|
||||
}
|
||||
|
||||
$path_parts = pathinfo($path);
|
||||
|
||||
/** @var Page $page */
|
||||
$page = $this['pages']->dispatch($path_parts['dirname'], true);
|
||||
|
||||
if ($page) {
|
||||
$media = $page->media()->all();
|
||||
|
||||
$parsed_url = parse_url(rawurldecode($uri->basename()));
|
||||
|
||||
$media_file = $parsed_url['path'];
|
||||
|
||||
// if this is a media object, try actions first
|
||||
if (isset($media[$media_file])) {
|
||||
/** @var Medium $medium */
|
||||
$medium = $media[$media_file];
|
||||
foreach ($uri->query(null, true) as $action => $params) {
|
||||
if (in_array($action, ImageMedium::$magic_actions)) {
|
||||
call_user_func_array(array(&$medium, $action), explode(',', $params));
|
||||
call_user_func_array([&$medium, $action], explode(',', $params));
|
||||
}
|
||||
}
|
||||
Utils::download($medium->path(), false);
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
/**
|
||||
* Class GravTrait
|
||||
*
|
||||
* @package Grav\Common
|
||||
*/
|
||||
trait GravTrait
|
||||
{
|
||||
/**
|
||||
@@ -16,6 +21,7 @@ trait GravTrait
|
||||
if (!self::$grav) {
|
||||
self::$grav = Grav::instance();
|
||||
}
|
||||
|
||||
return self::$grav;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,20 +4,19 @@ namespace Grav\Common;
|
||||
/**
|
||||
* This file was originally part of the Akelos Framework
|
||||
*/
|
||||
use Grav\Common\Language\Language;
|
||||
|
||||
/**
|
||||
* Inflector for pluralize and singularize English nouns.
|
||||
*
|
||||
* This Inflector is a port of Ruby on Rails Inflector.
|
||||
*
|
||||
* It can be really helpful for developers that want to
|
||||
* create frameworks based on naming conventions rather than
|
||||
* configurations.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
* Inflector for pluralize and singularize English nouns.
|
||||
*
|
||||
* This Inflector is a port of Ruby on Rails Inflector.
|
||||
*
|
||||
* It can be really helpful for developers that want to
|
||||
* create frameworks based on naming conventions rather than
|
||||
* configurations.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
class Inflector
|
||||
{
|
||||
@@ -42,11 +41,13 @@ class Inflector
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to pluralize
|
||||
* @return string Plural noun
|
||||
*/
|
||||
* Pluralizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to pluralize
|
||||
* @param int $count The count
|
||||
*
|
||||
* @return string Plural noun
|
||||
*/
|
||||
public function pluralize($word, $count = 2)
|
||||
{
|
||||
$this->init();
|
||||
@@ -58,14 +59,14 @@ class Inflector
|
||||
$lowercased_word = strtolower($word);
|
||||
|
||||
foreach ($this->uncountable as $_uncountable) {
|
||||
if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) {
|
||||
if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->irregular as $_plural => $_singular) {
|
||||
if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
|
||||
return preg_replace('/('.$_plural.')$/i', substr($arr[0], 0, 1).substr($_singular, 1), $word);
|
||||
if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) {
|
||||
return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,17 +75,19 @@ class Inflector
|
||||
return preg_replace($rule, $replacement, $word);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Singularizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to singularize
|
||||
* @param int $count
|
||||
* @return string Singular noun.
|
||||
*/
|
||||
* Singularizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to singularize
|
||||
* @param int $count
|
||||
*
|
||||
* @return string Singular noun.
|
||||
*/
|
||||
public function singularize($word, $count = 1)
|
||||
{
|
||||
$this->init();
|
||||
@@ -95,14 +98,14 @@ class Inflector
|
||||
|
||||
$lowercased_word = strtolower($word);
|
||||
foreach ($this->uncountable as $_uncountable) {
|
||||
if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) {
|
||||
if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->irregular as $_plural => $_singular) {
|
||||
if (preg_match('/('.$_singular.')$/i', $word, $arr)) {
|
||||
return preg_replace('/('.$_singular.')$/i', substr($arr[0], 0, 1).substr($_plural, 1), $word);
|
||||
if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) {
|
||||
return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,181 +119,206 @@ class Inflector
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an underscored or CamelCase word into a English
|
||||
* sentence.
|
||||
*
|
||||
* The titleize public function converts text like "WelcomePage",
|
||||
* "welcome_page" or "welcome page" to this "Welcome
|
||||
* Page".
|
||||
* If second parameter is set to 'first' it will only
|
||||
* capitalize the first character of the title.
|
||||
*
|
||||
* @param string $word Word to format as tile
|
||||
* @param string $uppercase If set to 'first' it will only uppercase the
|
||||
* first character. Otherwise it will uppercase all
|
||||
* the words in the title.
|
||||
* @return string Text formatted as title
|
||||
*/
|
||||
* Converts an underscored or CamelCase word into a English
|
||||
* sentence.
|
||||
*
|
||||
* The titleize public function converts text like "WelcomePage",
|
||||
* "welcome_page" or "welcome page" to this "Welcome
|
||||
* Page".
|
||||
* If second parameter is set to 'first' it will only
|
||||
* capitalize the first character of the title.
|
||||
*
|
||||
* @param string $word Word to format as tile
|
||||
* @param string $uppercase If set to 'first' it will only uppercase the
|
||||
* first character. Otherwise it will uppercase all
|
||||
* the words in the title.
|
||||
*
|
||||
* @return string Text formatted as title
|
||||
*/
|
||||
public function titleize($word, $uppercase = '')
|
||||
{
|
||||
$uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords';
|
||||
|
||||
return $uppercase($this->humanize($this->underscorize($word)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given word as CamelCased
|
||||
*
|
||||
* Converts a word like "send_email" to "SendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "WhoSOnline"
|
||||
*
|
||||
* @see variablize
|
||||
* @param string $word Word to convert to camel case
|
||||
* @return string UpperCamelCasedWord
|
||||
*/
|
||||
* Returns given word as CamelCased
|
||||
*
|
||||
* Converts a word like "send_email" to "SendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "WhoSOnline"
|
||||
*
|
||||
* @see variablize
|
||||
*
|
||||
* @param string $word Word to convert to camel case
|
||||
*
|
||||
* @return string UpperCamelCasedWord
|
||||
*/
|
||||
public function camelize($word)
|
||||
{
|
||||
return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a word "into_it_s_underscored_version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "underscored_word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to underscore
|
||||
* @return string Underscored word
|
||||
*/
|
||||
* Converts a word "into_it_s_underscored_version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "underscored_word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to underscore
|
||||
*
|
||||
* @return string Underscored word
|
||||
*/
|
||||
public function underscorize($word)
|
||||
{
|
||||
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word);
|
||||
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1);
|
||||
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '_', $regex2);
|
||||
return strtolower($regex3);
|
||||
|
||||
return strtolower($regex3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a word "into-it-s-hyphenated-version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "hyphenated-word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to hyphenate
|
||||
* @return string hyphenized word
|
||||
*/
|
||||
* Converts a word "into-it-s-hyphenated-version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "hyphenated-word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to hyphenate
|
||||
*
|
||||
* @return string hyphenized word
|
||||
*/
|
||||
public function hyphenize($word)
|
||||
{
|
||||
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word);
|
||||
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1-\2', $regex1);
|
||||
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex2);
|
||||
return strtolower($regex3);
|
||||
|
||||
return strtolower($regex3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable string from $word
|
||||
*
|
||||
* Returns a human-readable string from $word, by replacing
|
||||
* underscores with a space, and by upper-casing the initial
|
||||
* character by default.
|
||||
*
|
||||
* If you need to uppercase all the words you just have to
|
||||
* pass 'all' as a second parameter.
|
||||
*
|
||||
* @param string $word String to "humanize"
|
||||
* @param string $uppercase If set to 'all' it will uppercase all the words
|
||||
* instead of just the first one.
|
||||
* @return string Human-readable word
|
||||
*/
|
||||
* Returns a human-readable string from $word
|
||||
*
|
||||
* Returns a human-readable string from $word, by replacing
|
||||
* underscores with a space, and by upper-casing the initial
|
||||
* character by default.
|
||||
*
|
||||
* If you need to uppercase all the words you just have to
|
||||
* pass 'all' as a second parameter.
|
||||
*
|
||||
* @param string $word String to "humanize"
|
||||
* @param string $uppercase If set to 'all' it will uppercase all the words
|
||||
* instead of just the first one.
|
||||
*
|
||||
* @return string Human-readable word
|
||||
*/
|
||||
public function humanize($word, $uppercase = '')
|
||||
{
|
||||
$uppercase = $uppercase == 'all' ? 'ucwords' : 'ucfirst';
|
||||
|
||||
return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as camelize but first char is underscored
|
||||
*
|
||||
* Converts a word like "send_email" to "sendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "whoSOnline"
|
||||
*
|
||||
* @see camelize
|
||||
* @param string $word Word to lowerCamelCase
|
||||
* @return string Returns a lowerCamelCasedWord
|
||||
*/
|
||||
* Same as camelize but first char is underscored
|
||||
*
|
||||
* Converts a word like "send_email" to "sendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "whoSOnline"
|
||||
*
|
||||
* @see camelize
|
||||
*
|
||||
* @param string $word Word to lowerCamelCase
|
||||
*
|
||||
* @return string Returns a lowerCamelCasedWord
|
||||
*/
|
||||
public function variablize($word)
|
||||
{
|
||||
$word = $this->camelize($word);
|
||||
return strtolower($word[0]).substr($word, 1);
|
||||
|
||||
return strtolower($word[0]) . substr($word, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a class name to its table name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "Person" to "people"
|
||||
*
|
||||
* @see classify
|
||||
* @param string $class_name Class name for getting related table_name.
|
||||
* @return string plural_table_name
|
||||
*/
|
||||
* Converts a class name to its table name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "Person" to "people"
|
||||
*
|
||||
* @see classify
|
||||
*
|
||||
* @param string $class_name Class name for getting related table_name.
|
||||
*
|
||||
* @return string plural_table_name
|
||||
*/
|
||||
public function tableize($class_name)
|
||||
{
|
||||
return $this->pluralize($this->underscore($class_name));
|
||||
return $this->pluralize($this->underscorize($class_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a table name to its class name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "people" to "Person"
|
||||
*
|
||||
* @see tableize
|
||||
* @param string $table_name Table name for getting related ClassName.
|
||||
* @return string SingularClassName
|
||||
*/
|
||||
* Converts a table name to its class name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "people" to "Person"
|
||||
*
|
||||
* @see tableize
|
||||
*
|
||||
* @param string $table_name Table name for getting related ClassName.
|
||||
*
|
||||
* @return string SingularClassName
|
||||
*/
|
||||
public function classify($table_name)
|
||||
{
|
||||
return $this->camelize($this->singularize($table_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts number to its ordinal English form.
|
||||
*
|
||||
* This method converts 13 to 13th, 2 to 2nd ...
|
||||
*
|
||||
* @param integer $number Number to get its ordinal value
|
||||
* @return string Ordinal representation of given string.
|
||||
*/
|
||||
* Converts number to its ordinal English form.
|
||||
*
|
||||
* This method converts 13 to 13th, 2 to 2nd ...
|
||||
*
|
||||
* @param integer $number Number to get its ordinal value
|
||||
*
|
||||
* @return string Ordinal representation of given string.
|
||||
*/
|
||||
public function ordinalize($number)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
|
||||
if (in_array(($number % 100), range(11, 13))) {
|
||||
return $number.$this->ordinals['default'];
|
||||
return $number . $this->ordinals['default'];
|
||||
} else {
|
||||
switch (($number % 10)) {
|
||||
case 1:
|
||||
return $number.$this->ordinals['first'];
|
||||
return $number . $this->ordinals['first'];
|
||||
break;
|
||||
case 2:
|
||||
return $number.$this->ordinals['second'];
|
||||
return $number . $this->ordinals['second'];
|
||||
break;
|
||||
case 3:
|
||||
return $number.$this->ordinals['third'];
|
||||
return $number . $this->ordinals['third'];
|
||||
break;
|
||||
default:
|
||||
return $number.$this->ordinals['default'];
|
||||
return $number . $this->ordinals['default'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number of days to a number of months
|
||||
*
|
||||
* @param int $days
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function monthize($days)
|
||||
{
|
||||
$now = new \DateTime();
|
||||
@@ -300,9 +328,9 @@ class Inflector
|
||||
|
||||
$diff = $end->add($duration)->diff($now);
|
||||
|
||||
// handle years
|
||||
// handle years
|
||||
if ($diff->y > 0) {
|
||||
$diff->m = $diff->m + 12*$diff->y;
|
||||
$diff->m = $diff->m + 12 * $diff->y;
|
||||
}
|
||||
|
||||
return $diff->m;
|
||||
|
||||
@@ -26,6 +26,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($key, $args)
|
||||
@@ -79,11 +80,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
* Return nth item.
|
||||
*
|
||||
* @param int $key
|
||||
*
|
||||
* @return mixed|bool
|
||||
*/
|
||||
public function nth($key)
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
|
||||
return (isset($items[$key])) ? $this->offsetGet($items[$key]) : false;
|
||||
}
|
||||
|
||||
@@ -95,6 +98,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
public function first()
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
|
||||
return $this->offsetGet(array_shift($items));
|
||||
}
|
||||
|
||||
@@ -106,6 +110,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
public function last()
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
|
||||
return $this->offsetGet(array_pop($items));
|
||||
}
|
||||
|
||||
@@ -117,11 +122,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
public function reverse()
|
||||
{
|
||||
$this->items = array_reverse($this->items);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $needle Searched value.
|
||||
*
|
||||
* @return string|bool Key if found, otherwise false.
|
||||
*/
|
||||
public function indexOf($needle)
|
||||
@@ -131,6 +138,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -144,7 +152,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
$keys = array_keys($this->items);
|
||||
shuffle($keys);
|
||||
|
||||
$new = array();
|
||||
$new = [];
|
||||
foreach ($keys as $key) {
|
||||
$new[$key] = $this->items[$key];
|
||||
}
|
||||
@@ -159,6 +167,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function slice($offset, $length = null)
|
||||
@@ -171,12 +180,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
/**
|
||||
* Pick one or more random entries.
|
||||
*
|
||||
* @param int $num Specifies how many entries should be picked.
|
||||
* @param int $num Specifies how many entries should be picked.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function random($num = 1)
|
||||
{
|
||||
$this->items = array_intersect_key($this->items, array_flip((array) array_rand($this->items, $num)));
|
||||
$this->items = array_intersect_key($this->items, array_flip((array)array_rand($this->items, $num)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -184,7 +194,8 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
/**
|
||||
* Append new elements to the list.
|
||||
*
|
||||
* @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values.
|
||||
* @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function append($items)
|
||||
@@ -192,14 +203,17 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
if ($items instanceof static) {
|
||||
$items = $items->toArray();
|
||||
}
|
||||
$this->items = array_merge($this->items, (array) $items);
|
||||
$this->items = array_merge($this->items, (array)$items);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter elements from the list
|
||||
* @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate filter status
|
||||
*
|
||||
* @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate
|
||||
* filter status
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(callable $callback = null)
|
||||
@@ -207,7 +221,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
foreach ($this->items as $key => $value) {
|
||||
if (
|
||||
($callback && !call_user_func($callback, $value, $key)) ||
|
||||
(!$callback && !(bool) $value)
|
||||
(!$callback && !(bool)$value)
|
||||
) {
|
||||
unset($this->items[$key]);
|
||||
}
|
||||
@@ -230,7 +244,9 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*/
|
||||
public function sort(callable $callback = null, $desc = false)
|
||||
{
|
||||
if (!$callback || !is_callable($callback)) { return $this; }
|
||||
if (!$callback || !is_callable($callback)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$items = $this->items;
|
||||
uasort($items, $callback);
|
||||
|
||||
@@ -252,6 +252,8 @@ class Language
|
||||
/**
|
||||
* Gets an array of valid extensions with active first, then fallback extensions
|
||||
*
|
||||
* @param string|null $file_ext
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFallbackPageExtensions($file_ext = null)
|
||||
@@ -328,15 +330,15 @@ class Language
|
||||
/**
|
||||
* Translate a key and possibly arguments into a string using current lang and fallbacks
|
||||
*
|
||||
* @param $args first argument is the lookup key value
|
||||
* other arguments can be passed and replaced in the translation with sprintf syntax
|
||||
* @param Array $languages
|
||||
* @param mixed $args The first argument is the lookup key value
|
||||
* Other arguments can be passed and replaced in the translation with sprintf syntax
|
||||
* @param array $languages
|
||||
* @param bool $array_support
|
||||
* @param bool $html_out
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function translate($args, Array $languages = null, $array_support = false, $html_out = false)
|
||||
public function translate($args, array $languages = null, $array_support = false, $html_out = false)
|
||||
{
|
||||
if (is_array($args)) {
|
||||
$lookup = array_shift($args);
|
||||
@@ -345,7 +347,6 @@ class Language
|
||||
$args = [];
|
||||
}
|
||||
|
||||
|
||||
if ($this->config->get('system.languages.translations', true)) {
|
||||
if ($this->enabled() && $lookup) {
|
||||
if (empty($languages)) {
|
||||
@@ -422,8 +423,8 @@ class Language
|
||||
/**
|
||||
* Lookup the translation text for a given lang and key
|
||||
*
|
||||
* @param $lang lang code
|
||||
* @param $key key to lookup with
|
||||
* @param string $lang lang code
|
||||
* @param string $key key to lookup with
|
||||
* @param bool $array_support
|
||||
*
|
||||
* @return string
|
||||
@@ -438,6 +439,13 @@ class Language
|
||||
return $translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the browser accepted languages
|
||||
*
|
||||
* @param array $accept_langs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBrowserLanguages($accept_langs = [])
|
||||
{
|
||||
if (empty($this->http_accept_language)) {
|
||||
@@ -451,9 +459,9 @@ class Language
|
||||
// split $pref again by ';q='
|
||||
// and decorate the language entries by inverted position
|
||||
if (false !== ($i = strpos($pref, ';q='))) {
|
||||
$langs[substr($pref, 0, $i)] = array((float)substr($pref, $i + 3), -$k);
|
||||
$langs[substr($pref, 0, $i)] = [(float)substr($pref, $i + 3), -$k];
|
||||
} else {
|
||||
$langs[$pref] = array(1, -$k);
|
||||
$langs[$pref] = [1, -$k];
|
||||
}
|
||||
}
|
||||
arsort($langs);
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<?php
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
/**
|
||||
* Class Parsedown
|
||||
* @package Grav\Common\Markdown
|
||||
*/
|
||||
class Parsedown extends \Parsedown
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
/**
|
||||
* Parsedown constructor.
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
*/
|
||||
public function __construct($page, $defaults)
|
||||
{
|
||||
$this->init($page, $defaults);
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<?php
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
/**
|
||||
* Class ParsedownExtra
|
||||
* @package Grav\Common\Markdown
|
||||
*/
|
||||
class ParsedownExtra extends \ParsedownExtra
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
/**
|
||||
* ParsedownExtra constructor.
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
*/
|
||||
public function __construct($page, $defaults)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Uri;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
@@ -11,12 +13,18 @@ use RocketTheme\Toolbox\Event\Event;
|
||||
trait ParsedownGravTrait
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/** @var Page $page */
|
||||
protected $page;
|
||||
|
||||
/** @var Pages $pages */
|
||||
protected $pages;
|
||||
|
||||
protected $base_url;
|
||||
protected $pages_dir;
|
||||
protected $special_chars;
|
||||
protected $twig_link_regex = '/\!*\[(?:.*)\]\((\{([\{%#])\s*(.*?)\s*(?:\2|\})\})\)/';
|
||||
protected $special_protocols = ['xmpp', 'mailto', 'tel', 'sms'];
|
||||
|
||||
public $completable_blocks = [];
|
||||
public $continuable_blocks = [];
|
||||
@@ -34,10 +42,9 @@ trait ParsedownGravTrait
|
||||
$this->page = $page;
|
||||
$this->pages = $grav['pages'];
|
||||
$this->BlockTypes['{'] [] = "TwigTag";
|
||||
$this->BlockTypes['['] [] = "ShortcodeTag";
|
||||
$this->base_url = rtrim(self::getGrav()['base_url'] . self::getGrav()['pages']->base(), '/');
|
||||
$this->pages_dir = self::getGrav()['locator']->findResource('page://');
|
||||
$this->special_chars = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
|
||||
$this->special_chars = ['>' => 'gt', '<' => 'lt', '"' => 'quot'];
|
||||
|
||||
if ($defaults === null) {
|
||||
$defaults = self::getGrav()['config']->get('system.pages.markdown');
|
||||
@@ -60,7 +67,7 @@ trait ParsedownGravTrait
|
||||
*/
|
||||
public function addBlockType($type, $tag, $continuable = false, $completable = false)
|
||||
{
|
||||
$this->BlockTypes[$type] []= $tag;
|
||||
$this->BlockTypes[$type] [] = $tag;
|
||||
|
||||
if ($continuable) {
|
||||
$this->continuable_blocks[] = $tag;
|
||||
@@ -79,7 +86,7 @@ trait ParsedownGravTrait
|
||||
*/
|
||||
public function addInlineType($type, $tag)
|
||||
{
|
||||
$this->InlineTypes[$type] []= $tag;
|
||||
$this->InlineTypes[$type] [] = $tag;
|
||||
$this->inlineMarkerList .= $type;
|
||||
}
|
||||
|
||||
@@ -87,11 +94,13 @@ trait ParsedownGravTrait
|
||||
* Overrides the default behavior to allow for plugin-provided blocks to be continuable
|
||||
*
|
||||
* @param $Type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlockContinuable($Type)
|
||||
{
|
||||
$continuable = in_array($Type, $this->continuable_blocks) || method_exists($this, 'block'.$Type.'Continue');
|
||||
$continuable = in_array($Type, $this->continuable_blocks) || method_exists($this, 'block' . $Type . 'Continue');
|
||||
|
||||
return $continuable;
|
||||
}
|
||||
|
||||
@@ -99,11 +108,13 @@ trait ParsedownGravTrait
|
||||
* Overrides the default behavior to allow for plugin-provided blocks to be completable
|
||||
*
|
||||
* @param $Type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlockCompletable($Type)
|
||||
{
|
||||
$completable = in_array($Type, $this->completable_blocks) || method_exists($this, 'block'.$Type.'Complete');
|
||||
$completable = in_array($Type, $this->completable_blocks) || method_exists($this, 'block' . $Type . 'Complete');
|
||||
|
||||
return $completable;
|
||||
}
|
||||
|
||||
@@ -111,7 +122,8 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Make the element function publicly accessible, Medium uses this to render from Twig
|
||||
*
|
||||
* @param array $Element
|
||||
* @param array $Element
|
||||
*
|
||||
* @return string markup
|
||||
*/
|
||||
public function elementToHtml(array $Element)
|
||||
@@ -139,37 +151,28 @@ trait ParsedownGravTrait
|
||||
protected function blockTwigTag($Line)
|
||||
{
|
||||
if (preg_match('/(?:{{|{%|{#)(.*)(?:}}|%}|#})/', $Line['body'], $matches)) {
|
||||
$Block = array(
|
||||
$Block = [
|
||||
'markup' => $Line['body'],
|
||||
);
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
protected function blockShortcodeTag($Line)
|
||||
{
|
||||
if (preg_match('/^(?:\[)(.*)(?:\])$/', $Line['body'], $matches)) {
|
||||
$Block = array(
|
||||
'markup' => $Line['body'],
|
||||
);
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function inlineSpecialCharacter($Excerpt)
|
||||
{
|
||||
if ($Excerpt['text'][0] === '&' && ! preg_match('/^&#?\w+;/', $Excerpt['text'])) {
|
||||
return array(
|
||||
if ($Excerpt['text'][0] === '&' && !preg_match('/^&#?\w+;/', $Excerpt['text'])) {
|
||||
return [
|
||||
'markup' => '&',
|
||||
'extent' => 1,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
if (isset($this->special_chars[$Excerpt['text'][0]])) {
|
||||
return array(
|
||||
'markup' => '&'.$this->special_chars[$Excerpt['text'][0]].';',
|
||||
return [
|
||||
'markup' => '&' . $this->special_chars[$Excerpt['text'][0]] . ';',
|
||||
'extent' => 1,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +183,7 @@ trait ParsedownGravTrait
|
||||
$excerpt = parent::inlineImage($excerpt);
|
||||
$excerpt['element']['attributes']['src'] = $matches[1];
|
||||
$excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1;
|
||||
|
||||
return $excerpt;
|
||||
} else {
|
||||
$excerpt['type'] = 'image';
|
||||
@@ -187,7 +191,7 @@ trait ParsedownGravTrait
|
||||
}
|
||||
|
||||
// Some stuff we will need
|
||||
$actions = array();
|
||||
$actions = [];
|
||||
$media = null;
|
||||
|
||||
// if this is an image
|
||||
@@ -229,7 +233,7 @@ trait ParsedownGravTrait
|
||||
$actions = array_reduce(explode('&', $url['query']), function ($carry, $item) {
|
||||
$parts = explode('=', $item, 2);
|
||||
$value = isset($parts[1]) ? $parts[1] : null;
|
||||
$carry[] = [ 'method' => $parts[0], 'params' => $value ];
|
||||
$carry[] = ['method' => $parts[0], 'params' => $value];
|
||||
|
||||
return $carry;
|
||||
}, []);
|
||||
@@ -237,7 +241,8 @@ trait ParsedownGravTrait
|
||||
|
||||
// loop through actions for the image and call them
|
||||
foreach ($actions as $action) {
|
||||
$medium = call_user_func_array(array($medium, $action['method']), explode(',', urldecode($action['params'])));
|
||||
$medium = call_user_func_array([$medium, $action['method']],
|
||||
explode(',', urldecode($action['params'])));
|
||||
}
|
||||
|
||||
if (isset($url['fragment'])) {
|
||||
@@ -270,6 +275,7 @@ trait ParsedownGravTrait
|
||||
$excerpt = parent::inlineLink($excerpt);
|
||||
$excerpt['element']['attributes']['href'] = $matches[1];
|
||||
$excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1;
|
||||
|
||||
return $excerpt;
|
||||
} else {
|
||||
$excerpt = parent::inlineLink($excerpt);
|
||||
@@ -312,7 +318,7 @@ trait ParsedownGravTrait
|
||||
}
|
||||
|
||||
|
||||
$url['query']= http_build_query($actions, null, '&', PHP_QUERY_RFC3986);
|
||||
$url['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
// if no query elements left, unset query
|
||||
@@ -322,7 +328,10 @@ trait ParsedownGravTrait
|
||||
|
||||
// if there is no scheme, the file is local and we'll need to convert that URL
|
||||
if (!isset($url['scheme']) && (count($url) > 0)) {
|
||||
$excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type, true);
|
||||
$excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type,
|
||||
true);
|
||||
} elseif (in_array($url['scheme'], $this->special_protocols)) {
|
||||
return $excerpt;
|
||||
} else {
|
||||
$excerpt['element']['attributes']['href'] = Uri::buildUrl($url);
|
||||
}
|
||||
@@ -336,6 +345,7 @@ trait ParsedownGravTrait
|
||||
{
|
||||
if (isset($this->$method) === true) {
|
||||
$func = $this->$method;
|
||||
|
||||
return call_user_func_array($func, $args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use Grav\Common\Utils;
|
||||
/**
|
||||
* Collection of Pages.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Collection extends Iterator
|
||||
@@ -23,7 +23,14 @@ class Collection extends Iterator
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
public function __construct($items = array(), array $params = array(), Pages $pages = null)
|
||||
/**
|
||||
* Collection constructor.
|
||||
*
|
||||
* @param array $items
|
||||
* @param array $params
|
||||
* @param Pages|null $pages
|
||||
*/
|
||||
public function __construct($items = [], array $params = [], Pages $pages = null)
|
||||
{
|
||||
parent::__construct($items);
|
||||
|
||||
@@ -31,6 +38,11 @@ class Collection extends Iterator
|
||||
$this->pages = $pages ? $pages : Grav::instance()->offsetGet('pages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function params()
|
||||
{
|
||||
return $this->params;
|
||||
@@ -40,11 +52,13 @@ class Collection extends Iterator
|
||||
* Add a single page to a collection
|
||||
*
|
||||
* @param Page $page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPage(Page $page)
|
||||
{
|
||||
$this->items[$page->path()] = ['slug' => $page->slug()];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -63,11 +77,13 @@ class Collection extends Iterator
|
||||
* Set parameters to the Collection
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParams(array $params)
|
||||
{
|
||||
$this->params = array_merge($this->params, $params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -79,6 +95,7 @@ class Collection extends Iterator
|
||||
public function current()
|
||||
{
|
||||
$current = parent::key();
|
||||
|
||||
return $this->pages->get($current);
|
||||
}
|
||||
|
||||
@@ -90,13 +107,15 @@ class Collection extends Iterator
|
||||
public function key()
|
||||
{
|
||||
$current = parent::current();
|
||||
|
||||
return $current['slug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
*
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
@@ -108,6 +127,7 @@ class Collection extends Iterator
|
||||
* Remove item from the list.
|
||||
*
|
||||
* @param Page|string|null $key
|
||||
*
|
||||
* @return $this|void
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
@@ -123,6 +143,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
parent::remove($key);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -132,6 +153,7 @@ class Collection extends Iterator
|
||||
* @param string $by
|
||||
* @param string $dir
|
||||
* @param array $manual
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function order($by, $dir = 'asc', $manual = null)
|
||||
@@ -145,6 +167,7 @@ class Collection extends Iterator
|
||||
* Check to see if this item is the first in the collection.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return boolean True if item is first.
|
||||
*/
|
||||
public function isFirst($path)
|
||||
@@ -160,11 +183,12 @@ class Collection extends Iterator
|
||||
* Check to see if this item is the last in the collection.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return boolean True if item is last.
|
||||
*/
|
||||
public function isLast($path)
|
||||
{
|
||||
if ($this->items && $path == array_keys($this->items)[count($this->items)-1]) {
|
||||
if ($this->items && $path == array_keys($this->items)[count($this->items) - 1]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -174,7 +198,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Gets the previous sibling based on current position.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
*
|
||||
* @return Page The previous item.
|
||||
*/
|
||||
public function prevSibling($path)
|
||||
@@ -185,7 +210,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Gets the next sibling based on current position.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
*
|
||||
* @return Page The next item.
|
||||
*/
|
||||
public function nextSibling($path)
|
||||
@@ -198,6 +224,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path
|
||||
* @param integer $direction either -1 or +1
|
||||
*
|
||||
* @return Page The sibling item.
|
||||
*/
|
||||
public function adjacentSibling($path, $direction = 1)
|
||||
@@ -210,6 +237,7 @@ class Collection extends Iterator
|
||||
|
||||
return isset($values[$index]) ? $this->offsetGet($values[$index]) : $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
@@ -217,7 +245,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Returns the item in the current position.
|
||||
*
|
||||
* @param string $path the path the item
|
||||
* @param string $path the path the item
|
||||
*
|
||||
* @return Page Item in the array the the current position.
|
||||
*/
|
||||
public function currentPosition($path)
|
||||
@@ -256,6 +285,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $date_range;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -275,6 +305,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -294,6 +325,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -313,6 +345,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $modular;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -332,6 +365,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $modular;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -351,6 +385,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $published;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -370,6 +405,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $published;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -391,6 +427,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $routable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -410,12 +447,15 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $routable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new collection with only pages of the specified type
|
||||
*
|
||||
* @param $type
|
||||
*
|
||||
* @return Collection The collection
|
||||
*/
|
||||
public function ofType($type)
|
||||
@@ -430,12 +470,15 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new collection with only pages of one of the specified types
|
||||
*
|
||||
* @param $types
|
||||
*
|
||||
* @return Collection The collection
|
||||
*/
|
||||
public function ofOneOfTheseTypes($types)
|
||||
@@ -450,12 +493,15 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new collection with only pages of one of the specified access levels
|
||||
*
|
||||
* @param $accessLevels
|
||||
*
|
||||
* @return Collection The collection
|
||||
*/
|
||||
public function ofOneOfTheseAccessLevels($accessLevels)
|
||||
@@ -472,7 +518,7 @@ class Collection extends Iterator
|
||||
|
||||
foreach ($page->header()->access as $index => $accessLevel) {
|
||||
if (is_array($accessLevel)) {
|
||||
foreach($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
foreach ($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
if (in_array($innerAccessLevel, $accessLevels)) {
|
||||
$valid = true;
|
||||
}
|
||||
@@ -497,11 +543,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ namespace Grav\Common\Page;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Constructor;
|
||||
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccess;
|
||||
|
||||
/**
|
||||
* Class Header
|
||||
* @package Grav\Common\Page
|
||||
*/
|
||||
class Header implements \ArrayAccess
|
||||
{
|
||||
use NestedArrayAccess, Constructor;
|
||||
|
||||
@@ -20,11 +20,11 @@ class Media extends Getters
|
||||
protected $gettersVariable = 'instances';
|
||||
protected $path;
|
||||
|
||||
protected $instances = array();
|
||||
protected $images = array();
|
||||
protected $videos = array();
|
||||
protected $audios = array();
|
||||
protected $files = array();
|
||||
protected $instances = [];
|
||||
protected $images = [];
|
||||
protected $videos = [];
|
||||
protected $audios = [];
|
||||
protected $files = [];
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
|
||||
@@ -118,7 +118,7 @@ class Medium extends Data implements RenderableInterface
|
||||
* Return PATH to file.
|
||||
*
|
||||
* @param bool $reset
|
||||
* @return string path to file
|
||||
* @return string path to file
|
||||
*/
|
||||
public function path($reset = true)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,15 +1,15 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Cache;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Language;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\Blueprints;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Plugin\Admin;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
@@ -18,7 +18,7 @@ use Whoops\Exception\ErrorException;
|
||||
/**
|
||||
* GravPages is the class that is the entry point into the hierarchy of pages
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Pages
|
||||
@@ -46,7 +46,7 @@ class Pages
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected $routes = array();
|
||||
protected $routes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@@ -89,6 +89,7 @@ class Pages
|
||||
* Get or set base path for the pages.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function base($path = null)
|
||||
@@ -118,6 +119,7 @@ class Pages
|
||||
* Get or set last modification time.
|
||||
*
|
||||
* @param int $modified
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function lastModified($modified = null)
|
||||
@@ -125,6 +127,7 @@ class Pages
|
||||
if ($modified && $modified > $this->last_modified) {
|
||||
$this->last_modified = $modified;
|
||||
}
|
||||
|
||||
return $this->last_modified;
|
||||
}
|
||||
|
||||
@@ -151,8 +154,8 @@ class Pages
|
||||
/**
|
||||
* Adds a page and assigns a route to it.
|
||||
*
|
||||
* @param Page $page Page to be added.
|
||||
* @param string $route Optional route (uses route from the object if not set).
|
||||
* @param Page $page Page to be added.
|
||||
* @param string $route Optional route (uses route from the object if not set).
|
||||
*/
|
||||
public function addPage(Page $page, $route = null)
|
||||
{
|
||||
@@ -161,7 +164,7 @@ class Pages
|
||||
}
|
||||
$route = $page->route($route);
|
||||
if ($page->parent()) {
|
||||
$this->children[$page->parent()->path()][$page->path()] = array('slug' => $page->slug());
|
||||
$this->children[$page->parent()->path()][$page->path()] = ['slug' => $page->slug()];
|
||||
}
|
||||
$this->routes[$route] = $page->path();
|
||||
}
|
||||
@@ -169,7 +172,7 @@ class Pages
|
||||
/**
|
||||
* Sort sub-pages in a page.
|
||||
*
|
||||
* @param Page $page
|
||||
* @param Page $page
|
||||
* @param string $order_by
|
||||
* @param string $order_dir
|
||||
*
|
||||
@@ -185,7 +188,7 @@ class Pages
|
||||
}
|
||||
|
||||
$path = $page->path();
|
||||
$children = isset($this->children[$path]) ? $this->children[$path] : array();
|
||||
$children = isset($this->children[$path]) ? $this->children[$path] : [];
|
||||
|
||||
if (!$children) {
|
||||
return $children;
|
||||
@@ -206,9 +209,10 @@ class Pages
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @param $orderBy
|
||||
* @param string $orderDir
|
||||
* @param null $orderManual
|
||||
* @param $orderBy
|
||||
* @param string $orderDir
|
||||
* @param null $orderManual
|
||||
*
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
@@ -219,7 +223,7 @@ class Pages
|
||||
return [];
|
||||
}
|
||||
|
||||
$lookup = md5(json_encode($items));
|
||||
$lookup = md5(json_encode($items) . json_encode($orderManual) . $orderBy . $orderDir);
|
||||
if (!isset($this->sort[$lookup][$orderBy])) {
|
||||
$this->buildSort($lookup, $items, $orderBy, $orderManual);
|
||||
}
|
||||
@@ -237,7 +241,8 @@ class Pages
|
||||
/**
|
||||
* Get a page instance.
|
||||
*
|
||||
* @param string $path The filesystem full path of the page
|
||||
* @param string $path The filesystem full path of the page
|
||||
*
|
||||
* @return Page
|
||||
* @throws \Exception
|
||||
*/
|
||||
@@ -246,26 +251,30 @@ class Pages
|
||||
if (!is_null($path) && !is_string($path)) {
|
||||
throw new \Exception();
|
||||
}
|
||||
return isset($this->instances[(string) $path]) ? $this->instances[(string) $path] : null;
|
||||
|
||||
return isset($this->instances[(string)$path]) ? $this->instances[(string)$path] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children of the path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function children($path)
|
||||
{
|
||||
$children = isset($this->children[(string) $path]) ? $this->children[(string) $path] : array();
|
||||
return new Collection($children, array(), $this);
|
||||
$children = isset($this->children[(string)$path]) ? $this->children[(string)$path] : [];
|
||||
|
||||
return new Collection($children, [], $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch URI to a page.
|
||||
*
|
||||
* @param string $url The relative URL of the page
|
||||
* @param bool $all
|
||||
* @param bool $all
|
||||
*
|
||||
* @return Page|null
|
||||
*/
|
||||
public function dispatch($url, $all = false)
|
||||
@@ -297,28 +306,34 @@ class Pages
|
||||
$page = $this->dispatch($route, $all);
|
||||
} else {
|
||||
// Try Regex style redirects
|
||||
foreach ((array)$config->get("site.redirects") as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$this->grav->redirectLangSafe($found);
|
||||
$site_redirects = $config->get("site.redirects");
|
||||
if (is_array($site_redirects)) {
|
||||
foreach ((array)$site_redirects as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$this->grav->redirectLangSafe($found);
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Try Regex style routes
|
||||
foreach ((array)$config->get("site.routes") as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$page = $this->dispatch($found, $all);
|
||||
$site_routes = $config->get("site.routes");
|
||||
if (is_array($site_routes)) {
|
||||
foreach ((array)$site_routes as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$page = $this->dispatch($found, $all);
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.routes: ' . $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.routes: '. $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,7 +358,8 @@ class Pages
|
||||
/**
|
||||
* Get a blueprint for a page type.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $type
|
||||
*
|
||||
* @return Blueprint
|
||||
*/
|
||||
public function blueprints($type)
|
||||
@@ -370,6 +386,7 @@ class Pages
|
||||
* Get all pages
|
||||
*
|
||||
* @param \Grav\Common\Page\Page $current
|
||||
*
|
||||
* @return \Grav\Common\Page\Collection
|
||||
*/
|
||||
public function all(Page $current = null)
|
||||
@@ -380,7 +397,7 @@ class Pages
|
||||
$current = $current ?: $this->root();
|
||||
|
||||
if (!$current->root()) {
|
||||
$all[$current->path()] = [ 'slug' => $current->slug() ];
|
||||
$all[$current->path()] = ['slug' => $current->slug()];
|
||||
}
|
||||
|
||||
foreach ($current->children() as $next) {
|
||||
@@ -394,8 +411,11 @@ class Pages
|
||||
* Get list of route/title of all pages.
|
||||
*
|
||||
* @param Page $current
|
||||
* @param int $level
|
||||
* @param int $level
|
||||
* @param bool $rawRoutes
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getList(Page $current = null, $level = 0, $rawRoutes = false)
|
||||
@@ -408,7 +428,7 @@ class Pages
|
||||
$current = $this->root();
|
||||
}
|
||||
|
||||
$list = array();
|
||||
$list = [];
|
||||
|
||||
if (!$current->root()) {
|
||||
if ($rawRoutes) {
|
||||
@@ -416,7 +436,7 @@ class Pages
|
||||
} else {
|
||||
$route = $current->route();
|
||||
}
|
||||
$list[$route] = str_repeat(' ', ($level-1)*2) . $current->title();
|
||||
$list[$route] = str_repeat(' ', ($level - 1) * 2) . $current->title();
|
||||
}
|
||||
|
||||
foreach ($current->children() as $next) {
|
||||
@@ -499,12 +519,12 @@ class Pages
|
||||
public function accessLevels()
|
||||
{
|
||||
$accessLevels = [];
|
||||
foreach($this->all() as $page) {
|
||||
foreach ($this->all() as $page) {
|
||||
if (isset($page->header()->access)) {
|
||||
if (is_array($page->header()->access)) {
|
||||
foreach($page->header()->access as $index => $accessLevel) {
|
||||
foreach ($page->header()->access as $index => $accessLevel) {
|
||||
if (is_array($accessLevel)) {
|
||||
foreach($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
foreach ($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
array_push($accessLevels, $innerIndex);
|
||||
}
|
||||
} else {
|
||||
@@ -529,6 +549,7 @@ class Pages
|
||||
public static function parents()
|
||||
{
|
||||
$rawRoutes = false;
|
||||
|
||||
return self::getParents($rawRoutes);
|
||||
}
|
||||
|
||||
@@ -540,6 +561,7 @@ class Pages
|
||||
public static function parentsRawRoutes()
|
||||
{
|
||||
$rawRoutes = true;
|
||||
|
||||
return self::getParents($rawRoutes);
|
||||
}
|
||||
|
||||
@@ -573,17 +595,16 @@ class Pages
|
||||
}
|
||||
|
||||
return $parents;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's the home route
|
||||
* Gets the home route
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getHomeRoute()
|
||||
{
|
||||
if (empty(self::$home)) {
|
||||
if (empty(self::$home_route)) {
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Config $config */
|
||||
@@ -615,6 +636,7 @@ class Pages
|
||||
|
||||
self::$home_route = trim($home, '/');
|
||||
}
|
||||
|
||||
return self::$home_route;
|
||||
}
|
||||
|
||||
@@ -625,7 +647,7 @@ class Pages
|
||||
*/
|
||||
protected function buildPages()
|
||||
{
|
||||
$this->sort = array();
|
||||
$this->sort = [];
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
@@ -656,7 +678,7 @@ class Pages
|
||||
$last_modified = Folder::lastModifiedFile($pages_dir);
|
||||
}
|
||||
|
||||
$page_cache_id = md5(USER_DIR.$last_modified.$language->getActive().$config->checksum());
|
||||
$page_cache_id = md5(USER_DIR . $last_modified . $language->getActive() . $config->checksum());
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
|
||||
if (!$this->instances) {
|
||||
@@ -689,35 +711,33 @@ class Pages
|
||||
|
||||
// cache if needed
|
||||
if ($this->grav['config']->get('system.cache.enabled')) {
|
||||
/** @var Cache $cache */
|
||||
/** @var Cache $cache */
|
||||
$cache = $this->grav['cache'];
|
||||
/** @var Taxonomy $taxonomy */
|
||||
$taxonomy = $this->grav['taxonomy'];
|
||||
|
||||
// save pages, routes, taxonomy, and sort to cache
|
||||
$cache->save(
|
||||
$page_cache_id,
|
||||
array($this->instances, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort)
|
||||
);
|
||||
$cache->save($page_cache_id, [$this->instances, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive function to load & build page relationships.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string $directory
|
||||
* @param Page|null $parent
|
||||
*
|
||||
* @return Page
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
*/
|
||||
protected function recurse($directory, Page &$parent = null)
|
||||
{
|
||||
$directory = rtrim($directory, DS);
|
||||
$page = new Page;
|
||||
$directory = rtrim($directory, DS);
|
||||
$page = new Page;
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
$config = $this->grav['config'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
@@ -743,20 +763,21 @@ class Pages
|
||||
if (!isset($this->instances[$page->path()])) {
|
||||
$this->instances[$page->path()] = $page;
|
||||
if ($parent && $page->path()) {
|
||||
$this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
|
||||
$this->children[$parent->path()][$page->path()] = ['slug' => $page->slug()];
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException('Fatal error when creating page instances.');
|
||||
}
|
||||
|
||||
$content_exists = false;
|
||||
$pages_found = glob($directory.'/*'.CONTENT_EXT);
|
||||
$page_extensions = $language->getFallbackPageExtensions();
|
||||
$pages_found = glob($directory . '/*' . CONTENT_EXT);
|
||||
$page_extension = '';
|
||||
|
||||
if ($pages_found) {
|
||||
$page_extensions = $language->getFallbackPageExtensions();
|
||||
foreach ($page_extensions as $extension) {
|
||||
foreach ($pages_found as $found) {
|
||||
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+('.$extension.')$/', $found)) {
|
||||
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+(' . $extension . ')$/', $found)) {
|
||||
$page_found = $found;
|
||||
$page_extension = $extension;
|
||||
break 2;
|
||||
@@ -800,14 +821,14 @@ class Pages
|
||||
$page->path($file->getPath());
|
||||
}
|
||||
|
||||
$path = $directory.DS.$name;
|
||||
$path = $directory . DS . $name;
|
||||
$child = $this->recurse($path, $page);
|
||||
|
||||
if (Utils::startsWith($name, '_')) {
|
||||
$child->routable(false);
|
||||
}
|
||||
|
||||
$this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
|
||||
$this->children[$page->path()][$child->path()] = ['slug' => $child->slug()];
|
||||
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
|
||||
@@ -833,7 +854,7 @@ class Pages
|
||||
|
||||
// Override the modified and ID so that it takes the latest change into account
|
||||
$page->modified($last_modified);
|
||||
$page->id($last_modified.md5($page->filePath()));
|
||||
$page->id($last_modified . md5($page->filePath()));
|
||||
|
||||
// Sort based on Defaults or Page Overridden sort order
|
||||
$this->children[$page->path()] = $this->sort($page);
|
||||
@@ -859,7 +880,7 @@ class Pages
|
||||
// process taxonomy
|
||||
$taxonomy->addTaxonomy($page);
|
||||
|
||||
$route = $page->route();
|
||||
$route = $page->route();
|
||||
$raw_route = $page->rawRoute();
|
||||
$page_path = $page->path();
|
||||
|
||||
@@ -896,19 +917,20 @@ class Pages
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $pages
|
||||
* @param array $pages
|
||||
* @param string $order_by
|
||||
* @param array $manual
|
||||
* @param array $manual
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
*/
|
||||
protected function buildSort($path, array $pages, $order_by = 'default', $manual = null)
|
||||
{
|
||||
$list = array();
|
||||
$list = [];
|
||||
$header_default = null;
|
||||
$header_query = null;
|
||||
|
||||
// do this headery query work only once
|
||||
// do this header query work only once
|
||||
if (strpos($order_by, 'header.') === 0) {
|
||||
$header_query = explode('|', str_replace('header.', '', $order_by));
|
||||
if (isset($header_query[1])) {
|
||||
@@ -965,7 +987,7 @@ class Pages
|
||||
|
||||
// Move manually ordered items into the beginning of the list. Order of the unlisted items does not change.
|
||||
if (is_array($manual) && !empty($manual)) {
|
||||
$new_list = array();
|
||||
$new_list = [];
|
||||
$i = count($manual);
|
||||
|
||||
foreach ($list as $key => $dummy) {
|
||||
@@ -974,7 +996,7 @@ class Pages
|
||||
if ($order === false) {
|
||||
$order = $i++;
|
||||
}
|
||||
$new_list[$key] = (int) $order;
|
||||
$new_list[$key] = (int)$order;
|
||||
}
|
||||
|
||||
$list = $new_list;
|
||||
@@ -989,13 +1011,19 @@ class Pages
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffles and associative array
|
||||
/**
|
||||
* Shuffles an associative array
|
||||
*
|
||||
* @param array $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function arrayShuffle($list)
|
||||
{
|
||||
$keys = array_keys($list);
|
||||
shuffle($keys);
|
||||
|
||||
$new = array();
|
||||
$new = [];
|
||||
foreach ($keys as $key) {
|
||||
$new[$key] = $list[$key];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use RocketTheme\Toolbox\File\YamlFile;
|
||||
/**
|
||||
* The Plugin object just holds the id and path to a plugin.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Plugin implements EventSubscriberInterface
|
||||
@@ -42,7 +42,7 @@ class Plugin implements EventSubscriberInterface
|
||||
{
|
||||
$methods = get_class_methods(get_called_class());
|
||||
|
||||
$list = array();
|
||||
$list = [];
|
||||
foreach ($methods as $method) {
|
||||
if (strpos($method, 'on') === 0) {
|
||||
$list[$method] = [$method, 0];
|
||||
@@ -55,9 +55,9 @@ class Plugin implements EventSubscriberInterface
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* @param Grav $grav
|
||||
* @param Config $config
|
||||
* @param string $name
|
||||
* @param Grav $grav
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct($name, Grav $grav)
|
||||
{
|
||||
@@ -84,6 +84,7 @@ class Plugin implements EventSubscriberInterface
|
||||
if (isset($this->grav['admin'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -97,12 +98,12 @@ class Plugin implements EventSubscriberInterface
|
||||
|
||||
foreach ($events as $eventName => $params) {
|
||||
if (is_string($params)) {
|
||||
$dispatcher->addListener($eventName, array($this, $params));
|
||||
$dispatcher->addListener($eventName, [$this, $params]);
|
||||
} elseif (is_string($params[0])) {
|
||||
$dispatcher->addListener($eventName, array($this, $params[0]), isset($params[1]) ? $params[1] : 0);
|
||||
$dispatcher->addListener($eventName, [$this, $params[0]], isset($params[1]) ? $params[1] : 0);
|
||||
} else {
|
||||
foreach ($params as $listener) {
|
||||
$dispatcher->addListener($eventName, array($this, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
|
||||
$dispatcher->addListener($eventName, [$this, $listener[0]], isset($listener[1]) ? $listener[1] : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,12 +119,12 @@ class Plugin implements EventSubscriberInterface
|
||||
|
||||
foreach ($events as $eventName => $params) {
|
||||
if (is_string($params)) {
|
||||
$dispatcher->removeListener($eventName, array($this, $params));
|
||||
$dispatcher->removeListener($eventName, [$this, $params]);
|
||||
} elseif (is_string($params[0])) {
|
||||
$dispatcher->removeListener($eventName, array($this, $params[0]));
|
||||
$dispatcher->removeListener($eventName, [$this, $params[0]]);
|
||||
} else {
|
||||
foreach ($params as $listener) {
|
||||
$dispatcher->removeListener($eventName, array($this, $listener[0]));
|
||||
$dispatcher->removeListener($eventName, [$this, $listener[0]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,15 +137,16 @@ class Plugin implements EventSubscriberInterface
|
||||
*
|
||||
* format: [plugin:myplugin_name](function_data)
|
||||
*
|
||||
* @param $content The string to perform operations upon
|
||||
* @param $function The anonymous callback function
|
||||
* @param string $internal_regex Optional internal regex to extra data from
|
||||
* @param string $content The string to perform operations upon
|
||||
* @param callable $function The anonymous callback function
|
||||
* @param string $internal_regex Optional internal regex to extra data from
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parseLinks($content, $function, $internal_regex = '(.*)')
|
||||
{
|
||||
$regex = '/\[plugin:(?:'.$this->name.')\]\('.$internal_regex.'\)/i';
|
||||
$regex = '/\[plugin:(?:' . $this->name . ')\]\(' . $internal_regex . '\)/i';
|
||||
|
||||
return preg_replace_callback($regex, $function, $content);
|
||||
}
|
||||
|
||||
@@ -163,7 +165,7 @@ class Plugin implements EventSubscriberInterface
|
||||
{
|
||||
$class_name = $this->name;
|
||||
$class_name_merged = $class_name . '.merged';
|
||||
$defaults = $this->config->get('plugins.'. $class_name, []);
|
||||
$defaults = $this->config->get('plugins.' . $class_name, []);
|
||||
$page_header = $page->header();
|
||||
$header = [];
|
||||
if (!isset($page_header->$class_name_merged) && isset($page_header->$class_name)) {
|
||||
@@ -194,6 +196,7 @@ class Plugin implements EventSubscriberInterface
|
||||
} else {
|
||||
$header = array_merge($header, $params);
|
||||
}
|
||||
|
||||
// Return configurations as a new data config class
|
||||
return new Data($header);
|
||||
}
|
||||
@@ -201,11 +204,12 @@ class Plugin implements EventSubscriberInterface
|
||||
/**
|
||||
* 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 $plugin_name The name of the plugin whose config it should store.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public static function saveConfig($plugin_name) {
|
||||
public static function saveConfig($plugin_name)
|
||||
{
|
||||
if (!$plugin_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
* The Plugins object holds an array of all the plugin objects that
|
||||
* Grav knows about
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Plugins extends Iterator
|
||||
@@ -88,6 +88,8 @@ class Plugins extends Iterator
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plugin
|
||||
*
|
||||
* @param $plugin
|
||||
*/
|
||||
public function add($plugin)
|
||||
@@ -119,6 +121,13 @@ class Plugins extends Iterator
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a plugin by name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Data|null
|
||||
*/
|
||||
public static function get($name)
|
||||
{
|
||||
$blueprints = new Blueprints('plugins://');
|
||||
|
||||
@@ -9,11 +9,19 @@ class Session extends \RocketTheme\Toolbox\Session\Session
|
||||
protected $grav;
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* Session constructor.
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->grav = $grav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session init
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
@@ -37,10 +45,7 @@ class Session extends \RocketTheme\Toolbox\Session\Session
|
||||
|
||||
if ($config->get('system.session.enabled') || $is_admin) {
|
||||
// Define session service.
|
||||
parent::__construct(
|
||||
$session_timeout,
|
||||
$session_path
|
||||
);
|
||||
parent::__construct($session_timeout, $session_path);
|
||||
|
||||
$domain = $uri->host();
|
||||
if ($domain == 'localhost') {
|
||||
|
||||
@@ -22,7 +22,7 @@ use Grav\Common\Page\Page;
|
||||
* [tag][grav][path/to/item2]
|
||||
* [tag][dog][path/to/item3]
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Taxonomy
|
||||
@@ -32,10 +32,12 @@ class Taxonomy
|
||||
|
||||
/**
|
||||
* Constructor that resets the map
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->taxonomy_map = array();
|
||||
$this->taxonomy_map = [];
|
||||
$this->grav = $grav;
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ class Taxonomy
|
||||
* Takes an individual page and processes the taxonomies configured in its header. It
|
||||
* then adds those taxonomies to the map
|
||||
*
|
||||
* @param Page $page the page to process
|
||||
* @param Page $page the page to process
|
||||
* @param array $page_taxonomy
|
||||
*/
|
||||
public function addTaxonomy(Page $page, $page_taxonomy = null)
|
||||
@@ -59,10 +61,10 @@ class Taxonomy
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
if ($config->get('site.taxonomies')) {
|
||||
foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
|
||||
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()] = array('slug' => $page->slug());
|
||||
foreach ((array)$page_taxonomy[$taxonomy] as $item) {
|
||||
$this->taxonomy_map[$taxonomy][(string)$item][$page->path()] = ['slug' => $page->slug()];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,8 +75,9 @@ class Taxonomy
|
||||
* 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 'or')
|
||||
* @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
|
||||
* @param string $operator can be 'or' or 'and' (defaults to 'or')
|
||||
*
|
||||
* @return Collection Collection object set to contain matches found in the taxonomy map
|
||||
*/
|
||||
public function findTaxonomy($taxonomies, $operator = 'and')
|
||||
@@ -83,7 +86,7 @@ class Taxonomy
|
||||
$results = [];
|
||||
|
||||
foreach ((array)$taxonomies as $taxonomy => $items) {
|
||||
foreach ((array) $items as $item) {
|
||||
foreach ((array)$items as $item) {
|
||||
if (isset($this->taxonomy_map[$taxonomy][$item])) {
|
||||
$matches[] = $this->taxonomy_map[$taxonomy][$item];
|
||||
}
|
||||
@@ -108,6 +111,7 @@ class Taxonomy
|
||||
* Gets and Sets the taxonomy map
|
||||
*
|
||||
* @param array $var the taxonomy map
|
||||
*
|
||||
* @return array the taxonomy map
|
||||
*/
|
||||
public function taxonomy($var = null)
|
||||
@@ -115,6 +119,7 @@ class Taxonomy
|
||||
if ($var) {
|
||||
$this->taxonomy_map = $var;
|
||||
}
|
||||
|
||||
return $this->taxonomy_map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
|
||||
/**
|
||||
* Class Theme
|
||||
* @package Grav\Common
|
||||
*/
|
||||
class Theme extends Plugin
|
||||
{
|
||||
public $name;
|
||||
@@ -10,7 +15,7 @@ class Theme extends Plugin
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Grav $grav
|
||||
* @param Grav $grav
|
||||
* @param Config $config
|
||||
* @param string $name
|
||||
*/
|
||||
@@ -24,11 +29,12 @@ 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 $theme_name The name of the theme whose config it should store.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public static function saveConfig($theme_name) {
|
||||
public static function saveConfig($theme_name)
|
||||
{
|
||||
if (!$theme_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
/**
|
||||
* The Themes object holds an array of all the theme objects that Grav knows about.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Themes extends Iterator
|
||||
@@ -23,6 +23,11 @@ class Themes extends Iterator
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Themes constructor.
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -51,7 +56,7 @@ class Themes extends Iterator
|
||||
try {
|
||||
$instance = $themes->load();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new \RuntimeException($this->current(). ' theme could not be found');
|
||||
throw new \RuntimeException($this->current() . ' theme could not be found');
|
||||
}
|
||||
|
||||
if ($instance instanceof EventSubscriberInterface) {
|
||||
@@ -73,10 +78,10 @@ class Themes extends Iterator
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$list = array();
|
||||
$list = [];
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$themes = (array) $locator->findResources('themes://', false);
|
||||
$themes = (array)$locator->findResources('themes://', false);
|
||||
foreach ($themes as $path) {
|
||||
$iterator = new \DirectoryIterator($path);
|
||||
|
||||
@@ -102,7 +107,8 @@ class Themes extends Iterator
|
||||
/**
|
||||
* Get theme configuration or throw exception if it cannot be found.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
*
|
||||
* @return Data
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
@@ -126,8 +132,10 @@ class Themes extends Iterator
|
||||
|
||||
// Find thumbnail.
|
||||
$thumb = "themes://{$name}/thumbnail.jpg";
|
||||
if ($path = $this->grav['locator']->findResource($thumb, false)) {
|
||||
$blueprint->setMeta('', 'thumbnail', $this->grav['base_url'] . '/' . $path);
|
||||
$path = $this->grav['locator']->findResource($thumb, false);
|
||||
|
||||
if ($path) {
|
||||
$blueprint->setMeta('thumbnail', $this->grav['base_url'] . '/' . $path);
|
||||
}
|
||||
|
||||
$obj = new Data($file->content(), $blueprint);
|
||||
@@ -149,7 +157,7 @@ class Themes extends Iterator
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return (string) $this->config->get('system.pages.theme');
|
||||
return (string)$this->config->get('system.pages.theme');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,10 +184,9 @@ class Themes extends Iterator
|
||||
|
||||
if (!is_object($class)) {
|
||||
$themeClassFormat = [
|
||||
'Grav\\Theme\\'.ucfirst($name),
|
||||
'Grav\\Theme\\'.$inflector->camelize($name)
|
||||
'Grav\\Theme\\' . ucfirst($name),
|
||||
'Grav\\Theme\\' . $inflector->camelize($name)
|
||||
];
|
||||
$themeClassName = false;
|
||||
|
||||
foreach ($themeClassFormat as $themeClass) {
|
||||
if (class_exists($themeClass)) {
|
||||
@@ -253,8 +260,8 @@ class Themes extends Iterator
|
||||
/**
|
||||
* Load theme configuration.
|
||||
*
|
||||
* @param string $name Theme name
|
||||
* @param Config $config Configuration class
|
||||
* @param string $name Theme name
|
||||
* @param Config $config Configuration class
|
||||
*/
|
||||
protected function loadConfiguration($name, Config $config)
|
||||
{
|
||||
@@ -265,7 +272,7 @@ class Themes extends Iterator
|
||||
/**
|
||||
* Load theme languages.
|
||||
*
|
||||
* @param Config $config Configuration class
|
||||
* @param Config $config Configuration class
|
||||
*/
|
||||
protected function loadLanguages(Config $config)
|
||||
{
|
||||
@@ -282,7 +289,7 @@ class Themes extends Iterator
|
||||
|
||||
if ($languages) {
|
||||
$languages = call_user_func_array('array_replace_recursive', $languages);
|
||||
$config->getLanguages()->mergeRecursive($languages);
|
||||
$this->grav['languages']->mergeRecursive($languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,7 +318,7 @@ class Themes extends Iterator
|
||||
|
||||
// Load class
|
||||
if (file_exists($file)) {
|
||||
return include_once($file);
|
||||
return include_once($file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use Grav\Common\Page\Page;
|
||||
/**
|
||||
* The URI object provides information about the current URL
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Uri
|
||||
@@ -87,6 +87,7 @@ class Uri
|
||||
private function buildPort()
|
||||
{
|
||||
$port = isset($_SERVER['SERVER_PORT']) ? (string)$_SERVER['SERVER_PORT'] : '80';
|
||||
|
||||
return $port;
|
||||
}
|
||||
|
||||
@@ -98,6 +99,7 @@ class Uri
|
||||
private function buildUri()
|
||||
{
|
||||
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
@@ -132,7 +134,7 @@ class Uri
|
||||
|
||||
// check if userdir in the path and workaround PHP bug with PHP_SELF
|
||||
if (strpos($this->uri, '/~') !== false && strpos($_SERVER['PHP_SELF'], '/~') === false) {
|
||||
$root_path = substr($uri, 0, strpos($this->uri, '/', 1)) . $root_path;
|
||||
$root_path = substr($this->uri, 0, strpos($this->uri, '/', 1)) . $root_path;
|
||||
}
|
||||
|
||||
return $root_path;
|
||||
@@ -168,7 +170,9 @@ class Uri
|
||||
*/
|
||||
public function initializeWithUrl($url = '')
|
||||
{
|
||||
if (!$url) return;
|
||||
if (!$url) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->paths = [];
|
||||
$this->params = [];
|
||||
@@ -201,6 +205,14 @@ class Uri
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the URI class by providing url and root_path arguments
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $root_path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function initializeWithUrlAndRootPath($url, $root_path)
|
||||
{
|
||||
$this->initializeWithUrl($url);
|
||||
@@ -222,7 +234,7 @@ class Uri
|
||||
|
||||
// add the port to the base for non-standard ports
|
||||
if ($config->get('system.reverse_proxy_setup') == false && $this->port != '80' && $this->port != '443') {
|
||||
$this->base .= ":".$this->port;
|
||||
$this->base .= ":" . $this->port;
|
||||
}
|
||||
|
||||
// Set some defaults
|
||||
@@ -277,8 +289,8 @@ class Uri
|
||||
$valid_page_types = implode('|', $config->get('system.pages.types'));
|
||||
|
||||
// Strip the file extension for valid page types
|
||||
if (preg_match("/\.(".$valid_page_types.")$/", $parts['basename'])) {
|
||||
$uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS). '/' .$parts['filename'];
|
||||
if (preg_match("/\.(" . $valid_page_types . ")$/", $parts['basename'])) {
|
||||
$uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS) . '/' . $parts['filename'];
|
||||
}
|
||||
|
||||
// set the new url
|
||||
@@ -302,7 +314,7 @@ class Uri
|
||||
{
|
||||
if (strpos($uri, $delimiter) !== false) {
|
||||
$bits = explode('/', $uri);
|
||||
$path = array();
|
||||
$path = [];
|
||||
foreach ($bits as $bit) {
|
||||
if (strpos($bit, $delimiter) !== false) {
|
||||
$param = explode($delimiter, $bit);
|
||||
@@ -316,13 +328,15 @@ class Uri
|
||||
}
|
||||
$uri = '/' . ltrim(implode('/', $path), '/');
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URI path.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function paths($id = null)
|
||||
@@ -337,8 +351,9 @@ class Uri
|
||||
/**
|
||||
* Return route to the current URI. By default route doesn't include base path.
|
||||
*
|
||||
* @param bool $absolute True to include full path.
|
||||
* @param bool $domain True to include domain. Works only if first parameter is also true.
|
||||
* @param bool $absolute True to include full path.
|
||||
* @param bool $domain True to include domain. Works only if first parameter is also true.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function route($absolute = false, $domain = false)
|
||||
@@ -349,8 +364,10 @@ class Uri
|
||||
/**
|
||||
* Return full query string or a single query attribute.
|
||||
*
|
||||
* @param string $id Optional attribute.
|
||||
* @return string
|
||||
* @param string $id Optional attribute. Get a single query attribute if set
|
||||
* @param bool $raw If true and $id is not set, return the full query array. Otherwise return the query string
|
||||
*
|
||||
* @return string|array Returns an array if $id = null and $raw = true
|
||||
*/
|
||||
public function query($id = null, $raw = false)
|
||||
{
|
||||
@@ -363,6 +380,7 @@ class Uri
|
||||
if (!$this->query) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return http_build_query($this->query);
|
||||
}
|
||||
}
|
||||
@@ -371,8 +389,9 @@ class Uri
|
||||
/**
|
||||
* Return all or a single query parameter as a URI compatible string.
|
||||
*
|
||||
* @param string $id Optional parameter name.
|
||||
* @param string $id Optional parameter name.
|
||||
* @param boolean $array return the array format or not
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function params($id = null, $array = false)
|
||||
@@ -384,16 +403,16 @@ class Uri
|
||||
if ($array) {
|
||||
return $this->params;
|
||||
}
|
||||
$output = array();
|
||||
$output = [];
|
||||
foreach ($this->params as $key => $value) {
|
||||
$output[] = $key . $config->get('system.param_sep') . $value;
|
||||
$params = '/'.implode('/', $output);
|
||||
$params = '/' . implode('/', $output);
|
||||
}
|
||||
} elseif (isset($this->params[$id])) {
|
||||
if ($array) {
|
||||
return $this->params[$id];
|
||||
}
|
||||
$params = "/{$id}". $config->get('system.param_sep') . $this->params[$id];
|
||||
$params = "/{$id}" . $config->get('system.param_sep') . $this->params[$id];
|
||||
}
|
||||
|
||||
return $params;
|
||||
@@ -402,7 +421,8 @@ class Uri
|
||||
/**
|
||||
* Get URI parameter.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function param($id)
|
||||
@@ -417,7 +437,8 @@ class Uri
|
||||
/**
|
||||
* Return URL.
|
||||
*
|
||||
* @param bool $include_host Include hostname.
|
||||
* @param bool $include_host Include hostname.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url($include_host = false)
|
||||
@@ -426,6 +447,7 @@ class Uri
|
||||
return $this->url;
|
||||
} else {
|
||||
$url = (str_replace($this->base, '', rtrim($this->url, '/')));
|
||||
|
||||
return $url ? $url : '/';
|
||||
}
|
||||
}
|
||||
@@ -441,6 +463,7 @@ class Uri
|
||||
if ($path === '') {
|
||||
$path = '/';
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
@@ -456,6 +479,7 @@ class Uri
|
||||
if (!$this->extension) {
|
||||
$this->extension = $default;
|
||||
}
|
||||
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
@@ -513,7 +537,8 @@ class Uri
|
||||
/**
|
||||
* Return root URL to the site.
|
||||
*
|
||||
* @param bool $include_host Include hostname.
|
||||
* @param bool $include_host Include hostname.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rootUrl($include_host = false)
|
||||
@@ -522,6 +547,7 @@ class Uri
|
||||
return $this->root;
|
||||
} else {
|
||||
$root = str_replace($this->base, '', $this->root);
|
||||
|
||||
return $root;
|
||||
}
|
||||
}
|
||||
@@ -545,6 +571,7 @@ class Uri
|
||||
*
|
||||
* @param string $default
|
||||
* @param string $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function referrer($default = null, $attributes = null)
|
||||
@@ -600,7 +627,8 @@ class Uri
|
||||
/**
|
||||
* Is this an external URL? if it starts with `http` then yes, else false
|
||||
*
|
||||
* @param string $url the URL in question
|
||||
* @param string $url the URL in question
|
||||
*
|
||||
* @return boolean is eternal state
|
||||
*/
|
||||
public function isExternal($url)
|
||||
@@ -616,6 +644,7 @@ class Uri
|
||||
* The opposite of built-in PHP method parse_url()
|
||||
*
|
||||
* @param $parsed_url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildUrl($parsed_url)
|
||||
@@ -629,16 +658,17 @@ class Uri
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
|
||||
return "$scheme$user$pass$host$port$path$query$fragment";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts links from absolute '/' or relative (../..) to a Grav friendly format
|
||||
*
|
||||
* @param Page $page the current page to use as reference
|
||||
* @param string $markdown_url the URL as it was written in the markdown
|
||||
* @param string $type the type of URL, image | link
|
||||
* @param null $relative if null, will use system default, if true will use relative links internally
|
||||
* @param Page $page the current page to use as reference
|
||||
* @param string $markdown_url the URL as it was written in the markdown
|
||||
* @param string $type the type of URL, image | link
|
||||
* @param null $relative if null, will use system default, if true will use relative links internally
|
||||
*
|
||||
* @return string the more friendly formatted url
|
||||
*/
|
||||
@@ -646,7 +676,6 @@ class Uri
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Grav\Common\Language\Language $language */
|
||||
$language = $grav['language'];
|
||||
|
||||
// Link processing should prepend language
|
||||
@@ -659,7 +688,7 @@ class Uri
|
||||
if (is_null($relative)) {
|
||||
$base = $grav['base_url'];
|
||||
} else {
|
||||
$base = $relative ? $grav['base_url_relative'] : $grav['base_url_absolute'];
|
||||
$base = $relative ? $grav['base_url_relative'] : $grav['base_url_absolute'];
|
||||
}
|
||||
|
||||
$base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append;
|
||||
@@ -721,8 +750,10 @@ class Uri
|
||||
// get page instances and try to find one that fits
|
||||
$instances = $grav['pages']->instances();
|
||||
if (isset($instances[$page_path])) {
|
||||
/** @var Page $target */
|
||||
$target = $instances[$page_path];
|
||||
$url_bits['path'] = $base_url . rtrim($target->route(), '/') . $filename;
|
||||
|
||||
return Uri::buildUrl($url_bits);
|
||||
}
|
||||
|
||||
@@ -733,8 +764,8 @@ class Uri
|
||||
/**
|
||||
* Adds the nonce to a URL for a specific action
|
||||
*
|
||||
* @param string $url the url
|
||||
* @param string $action the action
|
||||
* @param string $url the url
|
||||
* @param string $action the action
|
||||
* @param string $nonceParamName the param name to use
|
||||
*
|
||||
* @return string the url with the nonce
|
||||
@@ -742,6 +773,7 @@ class Uri
|
||||
public static function addNonce($url, $action, $nonceParamName = 'nonce')
|
||||
{
|
||||
$urlWithNonce = $url . '/' . $nonceParamName . Grav::instance()['config']->get('system.param_sep', ':') . Utils::getNonce($action);
|
||||
|
||||
return $urlWithNonce;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Grav\Common\User;
|
||||
/**
|
||||
* User authentication
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
abstract class Authentication
|
||||
@@ -12,7 +12,8 @@ abstract class Authentication
|
||||
/**
|
||||
* Create password hash from plaintext password.
|
||||
*
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $password Plaintext password.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return string|bool
|
||||
*/
|
||||
@@ -34,8 +35,9 @@ abstract class Authentication
|
||||
/**
|
||||
* Verifies that a password matches a hash.
|
||||
*
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $hash Hash to verify against.
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $hash Hash to verify against.
|
||||
*
|
||||
* @return int Returns 0 if the check fails, 1 if password matches, 2 if hash needs to be updated.
|
||||
*/
|
||||
public static function verify($password, $hash)
|
||||
|
||||
@@ -10,10 +10,7 @@ use Grav\Common\Utils;
|
||||
/**
|
||||
* Group object
|
||||
*
|
||||
* @property mixed authenticated
|
||||
* @property mixed password
|
||||
* @property bool|string hashed_password
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Group extends Data
|
||||
@@ -28,12 +25,15 @@ class Group extends Data
|
||||
private static function groups()
|
||||
{
|
||||
$groups = self::getGrav()['config']->get('groups');
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a group exists
|
||||
*
|
||||
* @param string $groupname
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function group_exists($groupname)
|
||||
@@ -44,6 +44,8 @@ class Group extends Data
|
||||
/**
|
||||
* Get a group by name
|
||||
*
|
||||
* @param string $groupname
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function load($groupname)
|
||||
@@ -76,7 +78,7 @@ class Group extends Data
|
||||
|
||||
self::getGrav()['config']->set("groups.$this->groupname", []);
|
||||
|
||||
foreach($fields as $field) {
|
||||
foreach ($fields as $field) {
|
||||
if ($field['type'] == 'text') {
|
||||
$value = $field['name'];
|
||||
if (isset($this->items[$value])) {
|
||||
@@ -87,8 +89,10 @@ class Group extends Data
|
||||
$value = $field['name'];
|
||||
$arrayValues = Utils::resolve($this->items, $field['name']);
|
||||
|
||||
if ($arrayValues) foreach($arrayValues as $arrayIndex => $arrayValue) {
|
||||
self::getGrav()['config']->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue);
|
||||
if ($arrayValues) {
|
||||
foreach ($arrayValues as $arrayIndex => $arrayValue) {
|
||||
self::getGrav()['config']->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +108,8 @@ class Group extends Data
|
||||
/**
|
||||
* Remove a group
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $groupname
|
||||
*
|
||||
* @return bool True if the action was performed
|
||||
*/
|
||||
public static function remove($groupname)
|
||||
|
||||
@@ -10,10 +10,10 @@ use Grav\Common\Utils;
|
||||
/**
|
||||
* User object
|
||||
*
|
||||
* @property mixed authenticated
|
||||
* @property mixed password
|
||||
* @property mixed authenticated
|
||||
* @property mixed password
|
||||
* @property bool|string hashed_password
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class User extends Data
|
||||
@@ -26,6 +26,7 @@ class User extends Data
|
||||
* Always creates user object. To check if user exists, use $this->exists().
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public static function load($username)
|
||||
@@ -56,6 +57,7 @@ class User extends Data
|
||||
* Remove user account.
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return bool True if the action was performed
|
||||
*/
|
||||
public static function remove($username)
|
||||
@@ -73,7 +75,8 @@ class User extends Data
|
||||
*
|
||||
* If user password needs to be updated, new information will be saved.
|
||||
*
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $password Plaintext password.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate($password)
|
||||
@@ -90,6 +93,7 @@ class User extends Data
|
||||
$password,
|
||||
self::getGrav()['config']->get('system.security.default_hash')
|
||||
);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Plain-text does match, we can update the hash and proceed
|
||||
@@ -113,7 +117,7 @@ class User extends Data
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
return (bool)$result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +143,8 @@ class User extends Data
|
||||
/**
|
||||
* Checks user authorization to the action.
|
||||
*
|
||||
* @param string $action
|
||||
* @param string $action
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize($action)
|
||||
@@ -156,11 +161,13 @@ class User extends Data
|
||||
|
||||
//Check group access level
|
||||
$groups = $this->get('groups');
|
||||
if ($groups) foreach((array)$groups as $group) {
|
||||
$permission = self::getGrav()['config']->get("groups.{$group}.access.{$action}");
|
||||
$return = Utils::isPositive($permission);
|
||||
if ($return === true) {
|
||||
break;
|
||||
if ($groups) {
|
||||
foreach ((array)$groups as $group) {
|
||||
$permission = self::getGrav()['config']->get("groups.{$group}.access.{$action}");
|
||||
$return = Utils::isPositive($permission);
|
||||
if ($return === true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +187,7 @@ class User extends Data
|
||||
* Ensures backwards compatibility
|
||||
*
|
||||
* @param string $action
|
||||
*
|
||||
* @deprecated use authorize()
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -85,13 +85,15 @@ abstract class Utils
|
||||
*
|
||||
* @param $haystack
|
||||
* @param $needle
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function substrToString($haystack, $needle)
|
||||
{
|
||||
if (static::contains($haystack, $needle)) {
|
||||
return substr($haystack, 0, strpos($haystack,$needle));
|
||||
return substr($haystack, 0, strpos($haystack, $needle));
|
||||
}
|
||||
|
||||
return $haystack;
|
||||
}
|
||||
|
||||
@@ -128,6 +130,7 @@ abstract class Utils
|
||||
if ($default_format) {
|
||||
$date_formats = array_merge([$default_format => $default_format.' (e.g. '.$now->format($default_format).')'], $date_formats);
|
||||
}
|
||||
|
||||
return $date_formats;
|
||||
}
|
||||
|
||||
@@ -135,10 +138,11 @@ abstract class Utils
|
||||
* Truncate text by number of characters but can cut off words.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $limit Max number of characters.
|
||||
* @param bool $up_to_break truncate up to breakpoint after char count
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
* @param int $limit Max number of characters.
|
||||
* @param bool $up_to_break truncate up to breakpoint after char count
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function truncate($string, $limit = 150, $up_to_break = false, $break = " ", $pad = "…")
|
||||
@@ -163,8 +167,9 @@ abstract class Utils
|
||||
/**
|
||||
* Truncate text by number of characters in a "word-safe" manor.
|
||||
*
|
||||
* @param $string
|
||||
* @param int $limit
|
||||
* @param string $string
|
||||
* @param int $limit
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function safeTruncate($string, $limit = 150)
|
||||
@@ -183,7 +188,7 @@ abstract class Utils
|
||||
*/
|
||||
public static function truncateHtml($text, $length = 100)
|
||||
{
|
||||
return Truncator::truncate($text, $length, array('length_in_chars' => true));
|
||||
return Truncator::truncate($text, $length, ['length_in_chars' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,7 +201,7 @@ abstract class Utils
|
||||
*/
|
||||
public static function safeTruncateHtml($text, $length = 100)
|
||||
{
|
||||
return Truncator::truncate($text, $length, array('length_in_chars' => true, 'word_safe' => true));
|
||||
return Truncator::truncate($text, $length, ['length_in_chars' => true, 'word_safe' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,8 +219,8 @@ abstract class Utils
|
||||
/**
|
||||
* Provides the ability to download a file to the browser
|
||||
*
|
||||
* @param $file the full path to the file to be downloaded
|
||||
* @param bool $force_download as opposed to letting browser choose if to download or render
|
||||
* @param string $file the full path to the file to be downloaded
|
||||
* @param bool $force_download as opposed to letting browser choose if to download or render
|
||||
*/
|
||||
public static function download($file, $force_download = true)
|
||||
{
|
||||
@@ -231,7 +236,8 @@ abstract class Utils
|
||||
if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
|
||||
set_time_limit(0);
|
||||
}
|
||||
} catch (\Exception $e) {}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
ignore_user_abort(false);
|
||||
|
||||
@@ -272,7 +278,7 @@ abstract class Utils
|
||||
/**
|
||||
* Return the mimetype based on filename
|
||||
*
|
||||
* @param $extension Extension of file (eg "txt")
|
||||
* @param string $extension Extension of file (eg "txt")
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -300,7 +306,7 @@ abstract class Utils
|
||||
$root = ($path[0] === '/') ? '/' : '';
|
||||
|
||||
$segments = explode('/', trim($path, '/'));
|
||||
$ret = array();
|
||||
$ret = [];
|
||||
foreach ($segments as $segment) {
|
||||
if (($segment == '.') || empty($segment)) {
|
||||
continue;
|
||||
@@ -328,7 +334,7 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted timezones list
|
||||
* Get the formatted timezones list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -345,7 +351,7 @@ abstract class Utils
|
||||
|
||||
asort($offsets);
|
||||
|
||||
$timezone_list = array();
|
||||
$timezone_list = [];
|
||||
foreach ($offsets as $timezone => $offset) {
|
||||
$offset_prefix = $offset < 0 ? '-' : '+';
|
||||
$offset_formatted = gmdate('H:i', abs($offset));
|
||||
@@ -361,34 +367,32 @@ abstract class Utils
|
||||
/**
|
||||
* Recursively filter an array, filtering values by processing them through the $fn function argument
|
||||
*
|
||||
* @param array $source the Array to filter
|
||||
* @param $fn the function to pass through each array item
|
||||
* @param array $source the Array to filter
|
||||
* @param callable $fn the function to pass through each array item
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFilterRecursive(Array $source, $fn)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($source as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$result = [];
|
||||
foreach ($source as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$result[$key] = static::arrayFilterRecursive($value, $fn);
|
||||
continue;
|
||||
}
|
||||
if ($fn($key, $value))
|
||||
{
|
||||
if ($fn($key, $value)) {
|
||||
$result[$key] = $value; // KEEP
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the passed path contains the language code prefix
|
||||
*
|
||||
* @param $string The path
|
||||
* @param string $string The path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -397,7 +401,7 @@ abstract class Utils
|
||||
if (strlen($string) <= 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$languages_enabled = self::getGrav()['config']->get('system.languages.supported', []);
|
||||
|
||||
if ($string[0] == '/' && $string[3] == '/' && in_array(substr($string, 1, 2), $languages_enabled)) {
|
||||
@@ -410,7 +414,8 @@ abstract class Utils
|
||||
/**
|
||||
* Get the timestamp of a date
|
||||
*
|
||||
* @param $date a String expressed in the system.pages.dateformat.default format, with fallback to a strtotime argument
|
||||
* @param string $date a String expressed in the system.pages.dateformat.default format, with fallback to a
|
||||
* strtotime argument
|
||||
*
|
||||
* @return int the timestamp
|
||||
*/
|
||||
@@ -437,9 +442,9 @@ abstract class Utils
|
||||
/**
|
||||
* Get value of an array element using dot notation
|
||||
*
|
||||
* @param array $array the Array to check
|
||||
* @param string $path the dot notation path to check
|
||||
* @param $default a value to be returned if $path is not found in $array
|
||||
* @param array $array the Array to check
|
||||
* @param string $path the dot notation path to check
|
||||
* @param mixed $default a value to be returned if $path is not found in $array
|
||||
*
|
||||
* @return mixed the value found
|
||||
*/
|
||||
@@ -477,7 +482,7 @@ abstract class Utils
|
||||
* with reverse proxy setups.
|
||||
*
|
||||
* @param string $action
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
*
|
||||
* @return string the nonce string
|
||||
*/
|
||||
@@ -496,7 +501,7 @@ abstract class Utils
|
||||
$i++;
|
||||
}
|
||||
|
||||
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
}
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
@@ -517,7 +522,8 @@ abstract class Utils
|
||||
if ($plusOneTick) {
|
||||
$i++;
|
||||
}
|
||||
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
|
||||
return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -531,15 +537,16 @@ abstract class Utils
|
||||
private static function nonceTick()
|
||||
{
|
||||
$secondsInHalfADay = 60 * 60 * 12;
|
||||
return (int)ceil(time() / ( $secondsInHalfADay ));
|
||||
|
||||
return (int)ceil(time() / ($secondsInHalfADay));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hashed nonce tied to the passed action. Tied to the current user and time. The nonce for a given
|
||||
* action is the same for 12 hours.
|
||||
*
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
*
|
||||
* @return string the nonce
|
||||
*/
|
||||
@@ -572,7 +579,7 @@ abstract class Utils
|
||||
/**
|
||||
* Verify the passed nonce for the give action
|
||||
*
|
||||
* @param string $nonce the nonce to verify
|
||||
* @param string $nonce the nonce to verify
|
||||
* @param string $action the action to verify the nonce to
|
||||
*
|
||||
* @return boolean verified or not
|
||||
|
||||
@@ -24,6 +24,8 @@ class CleanCommand extends Command
|
||||
* @var array
|
||||
*/
|
||||
protected $paths_to_remove = [
|
||||
'codeception.yml',
|
||||
'tests/',
|
||||
'user/plugins/email/vendor/swiftmailer/swiftmailer/.travis.yml',
|
||||
'user/plugins/email/vendor/swiftmailer/swiftmailer/build.xml',
|
||||
'user/plugins/email/vendor/swiftmailer/swiftmailer/composer.json',
|
||||
|
||||
@@ -55,6 +55,7 @@ class SandboxCommand extends ConsoleCommand
|
||||
'/system' => '/system',
|
||||
'/vendor' => '/vendor',
|
||||
'/webserver-configs' => '/webserver-configs',
|
||||
'/codeception.yml' => '/codeception.yml',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
use Codeception\Util\Fixtures;
|
||||
|
||||
/**
|
||||
* Class AssetsTest
|
||||
*/
|
||||
class AssetsTest extends \Codeception\TestCase\Test
|
||||
{
|
||||
/**
|
||||
@@ -38,22 +41,59 @@ class AssetsTest extends \Codeception\TestCase\Test
|
||||
$css = $assets->css();
|
||||
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
|
||||
|
||||
$array = $assets->getCss();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.css',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'group' => 'head'
|
||||
]);
|
||||
|
||||
$assets->add('test.js');
|
||||
$js = $assets->js();
|
||||
$this->assertSame($js, '<script src="/test.js" type="text/javascript" ></script>' . PHP_EOL);
|
||||
|
||||
$array = $assets->getCss();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.css',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'group' => 'head'
|
||||
]);
|
||||
|
||||
//test addCss(). Test adding asset to a separate group
|
||||
$assets->reset();
|
||||
$assets->addCSS('test.css');
|
||||
$css = $assets->css();
|
||||
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
|
||||
|
||||
$array = $assets->getCss();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.css',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'group' => 'head'
|
||||
]);
|
||||
|
||||
//test addJs()
|
||||
$assets->reset();
|
||||
$assets->addJs('test.js');
|
||||
$js = $assets->js();
|
||||
$this->assertSame($js, '<script src="/test.js" type="text/javascript" ></script>' . PHP_EOL);
|
||||
|
||||
$array = $assets->getJs();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.js',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'loading' => '',
|
||||
'group' => 'head'
|
||||
]);
|
||||
|
||||
//Test CSS Groups
|
||||
$assets->reset();
|
||||
$assets->addCSS('test.css', null, true, 'footer');
|
||||
@@ -62,6 +102,15 @@ class AssetsTest extends \Codeception\TestCase\Test
|
||||
$css = $assets->css('footer');
|
||||
$this->assertSame($css, '<link href="/test.css" type="text/css" rel="stylesheet" />' . PHP_EOL);
|
||||
|
||||
$array = $assets->getCss();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.css',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'group' => 'footer'
|
||||
]);
|
||||
|
||||
//Test JS Groups
|
||||
$assets->reset();
|
||||
$assets->addJs('test.js', null, true, null, 'footer');
|
||||
@@ -70,17 +119,46 @@ class AssetsTest extends \Codeception\TestCase\Test
|
||||
$js = $assets->js('footer');
|
||||
$this->assertSame($js, '<script src="/test.js" type="text/javascript" ></script>' . PHP_EOL);
|
||||
|
||||
$array = $assets->getJs();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.js',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'loading' => '',
|
||||
'group' => 'footer'
|
||||
]);
|
||||
|
||||
//Test async / defer
|
||||
$assets->reset();
|
||||
$assets->addJs('test.js', null, true, 'async', null);
|
||||
$js = $assets->js();
|
||||
$this->assertSame($js, '<script src="/test.js" type="text/javascript" async></script>' . PHP_EOL);
|
||||
|
||||
$array = $assets->getJs();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.js',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'loading' => 'async',
|
||||
'group' => 'head'
|
||||
]);
|
||||
|
||||
$assets->reset();
|
||||
$assets->addJs('test.js', null, true, 'defer', null);
|
||||
$js = $assets->js();
|
||||
$this->assertSame($js, '<script src="/test.js" type="text/javascript" defer></script>' . PHP_EOL);
|
||||
|
||||
|
||||
$array = $assets->getJs();
|
||||
$this->assertSame(reset($array), [
|
||||
'asset' => '/test.js',
|
||||
'priority' => 10,
|
||||
'order' => 0,
|
||||
'pipeline' => true,
|
||||
'loading' => 'defer',
|
||||
'group' => 'head'
|
||||
]);
|
||||
}
|
||||
|
||||
public function testAddingAssetPropertiesWithArray()
|
||||
@@ -254,7 +332,142 @@ class AssetsTest extends \Codeception\TestCase\Test
|
||||
$assets->reset();
|
||||
$assets->addInlineJs('alert("test")');
|
||||
$js = $assets->js();
|
||||
$this->assertSame($js, PHP_EOL. '<script>' .PHP_EOL . 'alert("test")' . PHP_EOL.PHP_EOL .'</script>' . PHP_EOL);
|
||||
$this->assertSame($js,
|
||||
PHP_EOL . '<script>' . PHP_EOL . 'alert("test")' . PHP_EOL . PHP_EOL . '</script>' . PHP_EOL);
|
||||
}
|
||||
|
||||
}
|
||||
public function testGetCollections()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
|
||||
$this->assertTrue(is_array($assets->getCollections()));
|
||||
$this->assertTrue(in_array('jquery', array_keys($assets->getCollections())));
|
||||
$this->assertTrue(in_array('system://assets/jquery/jquery-2.x.min.js', $assets->getCollections()));
|
||||
}
|
||||
|
||||
public function testExists()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
|
||||
$this->assertTrue($assets->exists('jquery'));
|
||||
$this->assertFalse($assets->exists('another-unexisting-library'));
|
||||
}
|
||||
|
||||
public function testRegisterCollection()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
|
||||
$assets->registerCollection('debugger', ['/system/assets/debugger.css']);
|
||||
$this->assertTrue($assets->exists('debugger'));
|
||||
$this->assertTrue(in_array('debugger', array_keys($assets->getCollections())));
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
|
||||
$assets->addInlineJs('alert("test")');
|
||||
$assets->reset();
|
||||
$this->assertTrue(count($assets->js()) == 0);
|
||||
|
||||
$assets->addAsyncJs('jquery');
|
||||
$assets->reset();
|
||||
|
||||
$this->assertTrue(count($assets->js()) == 0);
|
||||
|
||||
$assets->addInlineCss('body { color: black }');
|
||||
$assets->reset();
|
||||
|
||||
$this->assertTrue(count($assets->css()) == 0);
|
||||
|
||||
$assets->add('/system/assets/debugger.css', null, true);
|
||||
$assets->reset();
|
||||
|
||||
$this->assertTrue(count($assets->css()) == 0);
|
||||
}
|
||||
|
||||
public function testResetJs()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
|
||||
$assets->addInlineJs('alert("test")');
|
||||
$assets->resetJs();
|
||||
$this->assertTrue(count($assets->js()) == 0);
|
||||
|
||||
$assets->addAsyncJs('jquery');
|
||||
$assets->resetJs();
|
||||
|
||||
$this->assertTrue(count($assets->js()) == 0);
|
||||
}
|
||||
|
||||
public function testResetCss()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
|
||||
$this->assertTrue(count($assets->js()) == 0);
|
||||
|
||||
$assets->addInlineCss('body { color: black }');
|
||||
$assets->resetCss();
|
||||
|
||||
$this->assertTrue(count($assets->css()) == 0);
|
||||
|
||||
$assets->add('/system/assets/debugger.css', null, true);
|
||||
$assets->resetCss();
|
||||
|
||||
$this->assertTrue(count($assets->css()) == 0);
|
||||
}
|
||||
|
||||
public function testAddDirCss()
|
||||
{
|
||||
$assets = $this->assets();
|
||||
$assets->reset();
|
||||
$assets->addDirCss('/system');
|
||||
|
||||
$this->assertTrue(is_array($assets->getCss()));
|
||||
$this->assertTrue(count($assets->getCss()) > 0);
|
||||
$this->assertTrue(is_array($assets->getJs()));
|
||||
$this->assertTrue(count($assets->getJs()) == 0);
|
||||
|
||||
$assets->reset();
|
||||
$assets->addDirCss('/system/assets');
|
||||
|
||||
$this->assertTrue(is_array($assets->getCss()));
|
||||
$this->assertTrue(count($assets->getCss()) > 0);
|
||||
$this->assertTrue(is_array($assets->getJs()));
|
||||
$this->assertTrue(count($assets->getJs()) == 0);
|
||||
|
||||
$assets->reset();
|
||||
$assets->addDirJs('/system');
|
||||
|
||||
$this->assertTrue(is_array($assets->getCss()));
|
||||
$this->assertTrue(count($assets->getCss()) == 0);
|
||||
$this->assertTrue(is_array($assets->getJs()));
|
||||
$this->assertTrue(count($assets->getJs()) > 0);
|
||||
|
||||
$assets->reset();
|
||||
$assets->addDirJs('/system/assets');
|
||||
|
||||
$this->assertTrue(is_array($assets->getCss()));
|
||||
$this->assertTrue(count($assets->getCss()) == 0);
|
||||
$this->assertTrue(is_array($assets->getJs()));
|
||||
$this->assertTrue(count($assets->getJs()) > 0);
|
||||
|
||||
$assets->reset();
|
||||
$assets->addDir('/system/assets');
|
||||
|
||||
$this->assertTrue(is_array($assets->getCss()));
|
||||
$this->assertTrue(count($assets->getCss()) > 0);
|
||||
$this->assertTrue(is_array($assets->getJs()));
|
||||
$this->assertTrue(count($assets->getJs()) > 0);
|
||||
|
||||
//Use streams
|
||||
$assets->reset();
|
||||
$assets->addDir('system://assets');
|
||||
|
||||
$this->assertTrue(is_array($assets->getCss()));
|
||||
$this->assertTrue(count($assets->getCss()) > 0);
|
||||
$this->assertTrue(is_array($assets->getJs()));
|
||||
$this->assertTrue(count($assets->getJs()) > 0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
74
tests/unit/Grav/Common/MarkdownTest.php
Normal file
74
tests/unit/Grav/Common/MarkdownTest.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Fixtures;
|
||||
|
||||
/**
|
||||
* Class AssetsTest
|
||||
*/
|
||||
class MarkdownTest extends \Codeception\TestCase\Test
|
||||
{
|
||||
/**
|
||||
* @var \UnitTester
|
||||
*/
|
||||
protected $tester;
|
||||
protected $parsedown;
|
||||
|
||||
protected function _before()
|
||||
{
|
||||
$defaults = [
|
||||
'extra' => false,
|
||||
'auto_line_breaks' => false,
|
||||
'auto_url_links' => false,
|
||||
'escape_markup' => false,
|
||||
'special_chars' => ['>' => 'gt', '<' => 'lt'],
|
||||
];
|
||||
$page = new \Grav\Common\Page\Page();
|
||||
|
||||
$this->parsedown = new Parsedown($page, $defaults);
|
||||
}
|
||||
|
||||
protected function _after()
|
||||
{
|
||||
}
|
||||
|
||||
public function grav()
|
||||
{
|
||||
$grav = Fixtures::get('grav');
|
||||
return $grav;
|
||||
}
|
||||
|
||||
public function stripLeadingWhitespace($string)
|
||||
{
|
||||
return preg_replace('/^\s*(.*)/', '', $string);
|
||||
}
|
||||
|
||||
|
||||
public function testMarkdownSpecialProtocols()
|
||||
{
|
||||
$this->assertSame($this->parsedown->text('[mailto](mailto:user@domain.com)'), '<p><a href="mailto:user@domain.com">mailto</a></p>');
|
||||
$this->assertSame($this->parsedown->text('[xmpp](xmpp:xyx@domain.com)'), '<p><a href="xmpp:xyx@domain.com">xmpp</a></p>');
|
||||
$this->assertSame($this->parsedown->text('[tel](tel:123-555-12345)'), '<p><a href="tel:123-555-12345">tel</a></p>');
|
||||
$this->assertSame($this->parsedown->text('[sms](sms:123-555-12345)'), '<p><a href="sms:123-555-12345">sms</a></p>');
|
||||
}
|
||||
|
||||
public function testMarkdownReferenceLinks()
|
||||
{
|
||||
$sample = '[relative link][r_relative]
|
||||
[r_relative]: ../03.assets#blah';
|
||||
$this->assertSame($this->parsedown->text($sample), '<p><a href="../03.assets#blah">relative link</a></p>');
|
||||
|
||||
$sample = '[absolute link][r_absolute]
|
||||
[r_absolute]: /blog/focus-and-blur#blah';
|
||||
$this->assertSame($this->parsedown->text($sample), '<p><a href="/blog/focus-and-blur#blah">absolute link</a></p>');
|
||||
|
||||
$sample = '[external link][r_external]
|
||||
[r_external]: http://www.cnn.com';
|
||||
$this->assertSame($this->parsedown->text($sample), '<p><a href="http://www.cnn.com">external link</a></p>');
|
||||
}
|
||||
|
||||
public function testMarkdownExternalLinks()
|
||||
{
|
||||
$this->assertSame($this->parsedown->text('[cnn.com](http://www.cnn.com)'), '<p><a href="http://www.cnn.com">cnn.com</a></p>');
|
||||
$this->assertSame($this->parsedown->text('[google.com](https://www.google.com)'), '<p><a href="https://www.google.com">google.com</a></p>');
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
use Codeception\Util\Fixtures;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
class UriTest extends \Codeception\TestCase\Test
|
||||
@@ -419,7 +420,7 @@ class UriTest extends \Codeception\TestCase\Test
|
||||
'port' => '8080',
|
||||
];
|
||||
|
||||
$this->assertSame($this->grav()['uri']::buildUrl($parsed_url), 'http://localhost:8080');
|
||||
$this->assertSame(Uri::buildUrl($parsed_url), 'http://localhost:8080');
|
||||
|
||||
$parsed_url = [
|
||||
'scheme' => 'http',
|
||||
@@ -432,7 +433,7 @@ class UriTest extends \Codeception\TestCase\Test
|
||||
'fragment' => 'xxx',
|
||||
];
|
||||
|
||||
$this->assertSame($this->grav()['uri']::buildUrl($parsed_url), 'http://foo:bar@localhost:8080/test?x=2#xxx');
|
||||
$this->assertSame(Uri::buildUrl($parsed_url), 'http://foo:bar@localhost:8080/test?x=2#xxx');
|
||||
}
|
||||
|
||||
public function testConvertUrl()
|
||||
@@ -443,12 +444,12 @@ class UriTest extends \Codeception\TestCase\Test
|
||||
public function testAddNonce()
|
||||
{
|
||||
$url = 'http://localhost/foo';
|
||||
$this->assertStringStartsWith($url, $this->grav()['uri']::addNonce($url, 'test-action'));
|
||||
$this->assertStringStartsWith($url . '/nonce:', $this->grav()['uri']::addNonce($url, 'test-action'));
|
||||
$this->assertStringStartsWith($url, Uri::addNonce($url, 'test-action'));
|
||||
$this->assertStringStartsWith($url . '/nonce:', Uri::addNonce($url, 'test-action'));
|
||||
|
||||
$uri = $this->getURI();
|
||||
|
||||
$uri->initializeWithURL($this->grav()['uri']::addNonce($url, 'test-action'))->init();
|
||||
$uri->initializeWithURL(Uri::addNonce($url, 'test-action'))->init();
|
||||
$this->assertTrue(is_string($uri->param('nonce')));
|
||||
$this->assertSame($uri->param('nonce'), Utils::getNonce('test-action'));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user