mirror of
https://github.com/getgrav/grav.git
synced 2026-07-13 16:02:35 +02:00
Merge branch 'develop' of github.com:getgrav/grav into feature-multimedia
* 'develop' of github.com:getgrav/grav: updated changelog Added async and defer loading of JavaScript files Updated web.config - Assets accesible fixed date version update removed some unused vars Removed some duplicate code via a trait Broke out iterators into their own class files only use files for last modified, so children don't affect the modified time of their parent page prevent a page from taken it's parent into account when detecting modified time Fixed `nth()` and added `first()` `last()` and `reverse()` methods Revert "Replace constant with streams. (need for multisite)." Replace constant with streams. (need for multisite).
This commit is contained in:
26
CHANGELOG.md
26
CHANGELOG.md
@@ -1,3 +1,27 @@
|
||||
# v0.9.20
|
||||
## 02/XX/2015
|
||||
|
||||
1. [](#new)
|
||||
* Added `addAsyncJs()` and `addDeferJs()` to Assets manager
|
||||
2. [](#improved)
|
||||
*
|
||||
3. [](#bugfix)
|
||||
*
|
||||
|
||||
# v0.9.19
|
||||
## 02/28/2015
|
||||
|
||||
1. [](#new)
|
||||
* Added named assets capability and bundled jQuery into Grav core
|
||||
* Added `first()` and `last()` to `Iterator` class
|
||||
2. [](#improved)
|
||||
* Improved page modification routine to skip _dot files_
|
||||
* Only use files to calculate page modification dates
|
||||
* Broke out Folder iterators into their own classes
|
||||
* Various Sensiolabs Insight fixes
|
||||
3. [](#bugfix)
|
||||
* Fixed `Iterator.nth()` method
|
||||
|
||||
# v0.9.18
|
||||
## 02/19/2015
|
||||
|
||||
@@ -11,7 +35,7 @@
|
||||
* Added new `processTemplate()` method to Twig object for on-the-fly processing of twig template
|
||||
* Added `rcopy()` and `contains()` helper methods in Utils
|
||||
2. [](#improved)
|
||||
* Provied new `param_sep` variable to better support Apache on Windows
|
||||
* Provided new `param_sep` variable to better support Apache on Windows
|
||||
* Moved parsedown configuration into the trait
|
||||
* Added optional **deep-copy** option to `mergeConfig()` for plugins
|
||||
* Updated bundled `composer.phar` package
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '0.9.18');
|
||||
define('GRAV_VERSION', '0.9.19');
|
||||
define('DS', '/');
|
||||
|
||||
// Directories and Paths
|
||||
|
||||
@@ -265,10 +265,11 @@ class Assets
|
||||
* @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)
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addJs($asset, $priority = 10, $pipeline = true)
|
||||
public function addJs($asset, $priority = 10, $pipeline = true, $loading = '')
|
||||
{
|
||||
if (is_array($asset)) {
|
||||
foreach ($asset as $a) {
|
||||
@@ -290,13 +291,42 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => $priority,
|
||||
'order' => count($this->js),
|
||||
'pipeline' => $pipeline
|
||||
'pipeline' => $pipeline,
|
||||
'loading' => $loading
|
||||
];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for async loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
*
|
||||
* @return \Grav\Common\Assets
|
||||
*/
|
||||
public function addAsyncJs($asset, $priority = 10, $pipeline = true)
|
||||
{
|
||||
return $this->addJs($asset, $priority, $pipeline, 'async');
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience wrapper for deferred loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
*
|
||||
* @return \Grav\Common\Assets
|
||||
*/
|
||||
public function addDeferJs($asset, $priority = 10, $pipeline = true)
|
||||
{
|
||||
return $this->addJs($asset, $priority, $pipeline, 'defer');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an inline CSS asset.
|
||||
*
|
||||
@@ -450,11 +480,11 @@ class Assets
|
||||
if ($this->js_pipeline) {
|
||||
$output .= '<script src="' . $this->pipeline(JS_ASSET) . '"' . $attributes . ' ></script>' . "\n";
|
||||
foreach ($this->js_no_pipeline as $file) {
|
||||
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ></script>' . "\n";
|
||||
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ' . $file['loading']. '></script>' . "\n";
|
||||
}
|
||||
} else {
|
||||
foreach ($this->js as $file) {
|
||||
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ></script>' . "\n";
|
||||
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ' . $file['loading'].'></script>' . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use RocketTheme\Toolbox\ArrayTraits\Export;
|
||||
*/
|
||||
class Blueprint
|
||||
{
|
||||
use Export;
|
||||
use Export, DataMutatorTrait;
|
||||
|
||||
public $name;
|
||||
|
||||
@@ -46,68 +46,6 @@ class Blueprint
|
||||
$this->filter = array_flip($filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->get('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function get($name, $default = null, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = $this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current) && isset($current->{$field})) {
|
||||
$current = $current->{$field};
|
||||
} elseif (is_array($current) && isset($current[$field])) {
|
||||
$current = $current[$field];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sey value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->set('this.is.my.nested.variable', true);
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*/
|
||||
public function set($name, $value, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = &$this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$field})) {
|
||||
$current->{$field} = array();
|
||||
}
|
||||
$current = &$current->{$field};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!is_array($current)) {
|
||||
$current = array($field => array());
|
||||
} elseif (!isset($current[$field])) {
|
||||
$current[$field] = array();
|
||||
}
|
||||
$current = &$current[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$current = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all form fields.
|
||||
*
|
||||
@@ -146,10 +84,9 @@ class Blueprint
|
||||
*
|
||||
* @param array $data1
|
||||
* @param array $data2
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public function mergeData(array $data1, array $data2, $name = null)
|
||||
public function mergeData(array $data1, array $data2)
|
||||
{
|
||||
// Initialize data
|
||||
$this->fields();
|
||||
@@ -213,7 +150,7 @@ class Blueprint
|
||||
$bref = array_merge($bref, array($key => $head[$key]));
|
||||
}
|
||||
}
|
||||
} while(count($head_stack));
|
||||
} while (count($head_stack));
|
||||
|
||||
$this->items = $blueprints;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use RocketTheme\Toolbox\File\FileInterface;
|
||||
*/
|
||||
class Data implements DataInterface
|
||||
{
|
||||
use ArrayAccessWithGetters, Countable, Export;
|
||||
use ArrayAccessWithGetters, Countable, Export, DataMutatorTrait;
|
||||
|
||||
protected $gettersVariable = 'items';
|
||||
protected $items;
|
||||
@@ -56,67 +56,6 @@ class Data implements DataInterface
|
||||
return $this->get($name, $default, $separator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->get('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function get($name, $default = null, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = $this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current) && isset($current->{$field})) {
|
||||
$current = $current->{$field};
|
||||
} elseif (is_array($current) && isset($current[$field])) {
|
||||
$current = $current[$field];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sey value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->set('this.is.my.nested.variable', true);
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*/
|
||||
public function set($name, $value, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = &$this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$field})) {
|
||||
$current->{$field} = array();
|
||||
}
|
||||
$current = &$current->{$field};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!is_array($current)) {
|
||||
$current = array($field => array());
|
||||
} elseif (!isset($current[$field])) {
|
||||
$current[$field] = array();
|
||||
}
|
||||
$current = &$current[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$current = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
|
||||
68
system/src/Grav/Common/Data/DataMutatorTrait.php
Normal file
68
system/src/Grav/Common/Data/DataMutatorTrait.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace Grav\Common\Data;
|
||||
|
||||
trait DataMutatorTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->get('this.is.my.nested.variable');
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $default Default value (or null).
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
* @return mixed Value.
|
||||
*/
|
||||
public function get($name, $default = null, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = $this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current) && isset($current->{$field})) {
|
||||
$current = $current->{$field};
|
||||
} elseif (is_array($current) && isset($current[$field])) {
|
||||
$current = $current[$field];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sey value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
* @example $value = $data->set('this.is.my.nested.variable', true);
|
||||
*
|
||||
* @param string $name Dot separated path to the requested value.
|
||||
* @param mixed $value New value.
|
||||
* @param string $separator Separator, defaults to '.'
|
||||
*/
|
||||
public function set($name, $value, $separator = '.')
|
||||
{
|
||||
$path = explode($separator, $name);
|
||||
$current = &$this->items;
|
||||
foreach ($path as $field) {
|
||||
if (is_object($current)) {
|
||||
// Handle objects.
|
||||
if (!isset($current->{$field})) {
|
||||
$current->{$field} = array();
|
||||
}
|
||||
$current = &$current->{$field};
|
||||
} else {
|
||||
// Handle arrays and scalars.
|
||||
if (!is_array($current)) {
|
||||
$current = array($field => array());
|
||||
} elseif (!isset($current[$field])) {
|
||||
$current[$field] = array();
|
||||
}
|
||||
$current = &$current[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$current = $value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,7 +20,7 @@ abstract class Folder
|
||||
$last_modified = 0;
|
||||
|
||||
$dirItr = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
$filterItr = new GravRecursiveFolderFilterIterator($dirItr);
|
||||
$filterItr = new RecursiveFolderFilterIterator($dirItr);
|
||||
$itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
@@ -45,7 +45,7 @@ abstract class Folder
|
||||
$last_modified = 0;
|
||||
|
||||
$dirItr = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
$filterItr = new GravRecursiveFileFilterIterator($dirItr);
|
||||
$filterItr = new RecursiveFileFilterIterator($dirItr);
|
||||
$itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
@@ -301,23 +301,3 @@ abstract class Folder
|
||||
return @rmdir($folder);
|
||||
}
|
||||
}
|
||||
|
||||
class GravRecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
{
|
||||
public function accept()
|
||||
{
|
||||
// only accept directories
|
||||
return $this->current()->isDir();
|
||||
}
|
||||
}
|
||||
|
||||
class GravRecursiveFileFilterIterator extends \RecursiveFilterIterator
|
||||
{
|
||||
public static $FILTERS = ['.DS_Store'];
|
||||
|
||||
public function accept()
|
||||
{
|
||||
// Ensure any filtered file names are skipped
|
||||
return !in_array($this->current()->getFilename(), self::$FILTERS, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace Grav\Common\Filesystem;
|
||||
|
||||
class RecursiveFileFilterIterator extends \RecursiveFilterIterator
|
||||
{
|
||||
public static $FILTERS = ['.DS_Store'];
|
||||
|
||||
public function accept()
|
||||
{
|
||||
// Ensure any filtered file names are skipped
|
||||
return !in_array($this->current()->getFilename(), self::$FILTERS, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace Grav\Common\Filesystem;
|
||||
|
||||
class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
{
|
||||
public function accept()
|
||||
{
|
||||
// only accept directories
|
||||
return $this->current()->isDir();
|
||||
}
|
||||
}
|
||||
@@ -24,8 +24,6 @@ class Collection extends Iterator {
|
||||
private $repository;
|
||||
private $cache;
|
||||
|
||||
private $plugins, $themes;
|
||||
|
||||
public function __construct($repository = null)
|
||||
{
|
||||
if ($repository === null) {
|
||||
|
||||
@@ -84,10 +84,43 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*/
|
||||
public function nth($key)
|
||||
{
|
||||
$items = array_values($this->items);
|
||||
$items = array_keys($this->items);
|
||||
return (isset($items[$key])) ? $this->offsetGet($items[$key]) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the first item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
return $this->offsetGet(array_shift($items));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the last item
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function last()
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
return $this->offsetGet(array_pop($items));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the Iterator
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function reverse()
|
||||
{
|
||||
$this->items = array_reverse($this->items);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $needle Searched value.
|
||||
* @return string|bool Key if found, otherwise false.
|
||||
|
||||
@@ -90,10 +90,8 @@ class Page
|
||||
|
||||
/**
|
||||
* Page Object Constructor
|
||||
*
|
||||
* @param array $array An array of existing page objects
|
||||
*/
|
||||
public function __construct($array = array())
|
||||
public function __construct()
|
||||
{
|
||||
/** @var Config $config */
|
||||
$config = self::getGrav()['config'];
|
||||
|
||||
@@ -523,19 +523,30 @@ class Pages
|
||||
|
||||
/** @var \DirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
|
||||
if ($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$name = $file->getFilename();
|
||||
$modified = $file->getMTime();
|
||||
|
||||
if ($file->isFile() && Utils::endsWith($name, CONTENT_EXT)) {
|
||||
if ($file->isFile()) {
|
||||
|
||||
$page->init($file);
|
||||
$content_exists = true;
|
||||
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
|
||||
// Update the last modified if it's newer than already found
|
||||
if ($file->getBasename() !== '.DS_Store' && ($modified = $file->getMTime()) > $last_modified) {
|
||||
$last_modified = $modified;
|
||||
}
|
||||
|
||||
} elseif ($file->isDir() && !$file->isDot()) {
|
||||
if (Utils::endsWith($name, CONTENT_EXT)) {
|
||||
|
||||
$page->init($file);
|
||||
$content_exists = true;
|
||||
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onPageProcessed', new Event(['page' => $page]));
|
||||
}
|
||||
}
|
||||
} elseif ($file->isDir()) {
|
||||
|
||||
if (!$page->path()) {
|
||||
$page->path($file->getPath());
|
||||
@@ -554,11 +565,6 @@ class Pages
|
||||
$this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
|
||||
}
|
||||
}
|
||||
|
||||
// Update the last modified if it's newer than already found
|
||||
if ($modified > $last_modified) {
|
||||
$last_modified = $modified;
|
||||
}
|
||||
}
|
||||
|
||||
// Set routability to false if no page found
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<action type="Redirect" url="error" redirectType="Permanent" />
|
||||
</rule>
|
||||
<rule name="system" stopProcessing="true">
|
||||
<match url="^system/(.*)$" ignoreCase="false" />
|
||||
<match url="^system/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$" ignoreCase="false" />
|
||||
<action type="Redirect" url="error" redirectType="Permanent" />
|
||||
</rule>
|
||||
<rule name="vendor" stopProcessing="true">
|
||||
|
||||
Reference in New Issue
Block a user