diff --git a/README.md b/README.md index 01ce1fb0d..df4706876 100644 --- a/README.md +++ b/README.md @@ -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! diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index ecde4be87..7b2bd00ad 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -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 diff --git a/system/config/site.yaml b/system/config/site.yaml index 177a4e7bf..840d7227e 100644 --- a/system/config/site.yaml +++ b/system/config/site.yaml @@ -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) diff --git a/system/config/system.yaml b/system/config/system.yaml index b5d6e875e..4099b6f67 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -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] diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 5790370fc..d482a4710 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -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 .= '' . "\n"; + $output .= '' . "\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; } /** diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index cf3689b28..a3dedc886 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -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) { diff --git a/system/src/Grav/Common/Browser.php b/system/src/Grav/Common/Browser.php index f39ac1539..3272901d3 100644 --- a/system/src/Grav/Common/Browser.php +++ b/system/src/Grav/Common/Browser.php @@ -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]); } diff --git a/system/src/Grav/Common/Cache.php b/system/src/Grav/Common/Cache.php index f7a6d4bae..e938c32b9 100644 --- a/system/src/Grav/Common/Cache.php +++ b/system/src/Grav/Common/Cache.php @@ -1,7 +1,7 @@ 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 . '/*'); diff --git a/system/src/Grav/Common/Composer.php b/system/src/Grav/Common/Composer.php index 5efde8912..804bc4c15 100644 --- a/system/src/Grav/Common/Composer.php +++ b/system/src/Grav/Common/Composer.php @@ -35,6 +35,11 @@ class Composer return $path; } + /** + * Return the composer executable file path + * + * @return string + */ public static function getComposerExecutor() { $executor = PHP_BINARY . ' '; diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index 9387effba..f8e0c3119 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -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) { diff --git a/system/src/Grav/Common/Debugger.php b/system/src/Grav/Common/Debugger.php index 64824ff69..219fa6a1c 100644 --- a/system/src/Grav/Common/Debugger.php +++ b/system/src/Grav/Common/Debugger.php @@ -1,8 +1,10 @@ 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; } } diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 81d610898..26e90fe31 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -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) { diff --git a/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php b/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php index aa9fd4a84..a84a51906 100644 --- a/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php +++ b/system/src/Grav/Common/Filesystem/RecursiveFolderFilterIterator.php @@ -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(); diff --git a/system/src/Grav/Common/GPM/Response.php b/system/src/Grav/Common/GPM/Response.php index 87ba44e9b..578b5c3fc 100644 --- a/system/src/Grav/Common/GPM/Response.php +++ b/system/src/Grav/Common/GPM/Response.php @@ -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']); diff --git a/system/src/Grav/Common/Getters.php b/system/src/Grav/Common/Getters.php index 857dccaba..8db51d324 100644 --- a/system/src/Grav/Common/Getters.php +++ b/system/src/Grav/Common/Getters.php @@ -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; } } diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 4f01f62fb..f53f39bf7 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -1,8 +1,11 @@ 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); diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php index 171017363..a8f86826c 100644 --- a/system/src/Grav/Common/GravTrait.php +++ b/system/src/Grav/Common/GravTrait.php @@ -1,6 +1,11 @@ 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; diff --git a/system/src/Grav/Common/Iterator.php b/system/src/Grav/Common/Iterator.php index 287b925ae..9afd9dbd0 100644 --- a/system/src/Grav/Common/Iterator.php +++ b/system/src/Grav/Common/Iterator.php @@ -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); diff --git a/system/src/Grav/Common/Language/Language.php b/system/src/Grav/Common/Language/Language.php index 6a9e3f18c..eb69adcf1 100644 --- a/system/src/Grav/Common/Language/Language.php +++ b/system/src/Grav/Common/Language/Language.php @@ -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); diff --git a/system/src/Grav/Common/Markdown/Parsedown.php b/system/src/Grav/Common/Markdown/Parsedown.php index f453a544a..95ead42d2 100644 --- a/system/src/Grav/Common/Markdown/Parsedown.php +++ b/system/src/Grav/Common/Markdown/Parsedown.php @@ -1,10 +1,20 @@ init($page, $defaults); diff --git a/system/src/Grav/Common/Markdown/ParsedownExtra.php b/system/src/Grav/Common/Markdown/ParsedownExtra.php index 526e5f905..515d1dc9c 100644 --- a/system/src/Grav/Common/Markdown/ParsedownExtra.php +++ b/system/src/Grav/Common/Markdown/ParsedownExtra.php @@ -1,10 +1,20 @@ 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); } } diff --git a/system/src/Grav/Common/Page/Collection.php b/system/src/Grav/Common/Page/Collection.php index cc1593c28..861f55b74 100644 --- a/system/src/Grav/Common/Page/Collection.php +++ b/system/src/Grav/Common/Page/Collection.php @@ -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; } - - - - - } diff --git a/system/src/Grav/Common/Page/Header.php b/system/src/Grav/Common/Page/Header.php index 4be82629d..ad59c26d3 100644 --- a/system/src/Grav/Common/Page/Header.php +++ b/system/src/Grav/Common/Page/Header.php @@ -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; diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index e9eeff101..dd1a38110 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -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 diff --git a/system/src/Grav/Common/Page/Medium/Medium.php b/system/src/Grav/Common/Page/Medium/Medium.php index 714eeb5e8..f1ce336fd 100644 --- a/system/src/Grav/Common/Page/Medium/Medium.php +++ b/system/src/Grav/Common/Page/Medium/Medium.php @@ -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) { diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index d394b769c..67bfe1db8 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -28,7 +28,7 @@ define('PAGE_ORDER_PREFIX_REGEX', '/^[0-9]+\./u'); * can be retrieved via public functions. Also each page can potentially contain an array of sub-pages. * Recursively traversing the page structure allows Grav to create navigation systems. * - * @author RocketTheme + * @author RocketTheme * @license MIT */ class Page @@ -106,8 +106,7 @@ class Page /** @var Config $config */ $config = self::getGrav()['config']; - - $this->taxonomy = array(); + $this->taxonomy = []; $this->process = $config->get('system.pages.process'); $this->published = true; } @@ -126,7 +125,7 @@ class Page $this->home_route = $config->get('system.home.alias'); $this->filePath($file->getPathName()); $this->modified($file->getMTime()); - $this->id($this->modified().md5($this->filePath())); + $this->id($this->modified() . md5($this->filePath())); $this->routable(true); $this->header(); $this->date(); @@ -140,7 +139,7 @@ class Page // some extension logic if (empty($extension)) { - $this->extension('.'.$file->getExtension()); + $this->extension('.' . $file->getExtension()); } else { $this->extension($extension); } @@ -162,13 +161,15 @@ class Page $translatedLanguages = []; foreach ($languages as $language) { - $path = $this->path . DS . $this->folder . DS . $filename . '.' . $language .'.md'; + $path = $this->path . DS . $this->folder . DS . $filename . '.' . $language . '.md'; if (file_exists($path)) { $aPage = new Page(); - $aPage->init(new \SplFileInfo($path), $language .'.md'); + $aPage->init(new \SplFileInfo($path), $language . '.md'); $route = isset($aPage->header()->routes['default']) ? $aPage->header()->routes['default'] : $aPage->rawRoute(); - if (!$route) $route = $aPage->slug(); + if (!$route) { + $route = $aPage->slug(); + } $translatedLanguages[$language] = $route; } @@ -189,7 +190,7 @@ class Page $untranslatedLanguages = []; foreach ($languages as $language) { - $path = $this->path . DS . $this->folder . DS . $filename . '.' . $language .'.md'; + $path = $this->path . DS . $this->folder . DS . $filename . '.' . $language . '.md'; if (!file_exists($path)) { $untranslatedLanguages[] = $language; } @@ -202,6 +203,7 @@ class Page * Gets and Sets the raw data * * @param string $var Raw content string + * * @return Object Raw content string */ public function raw($var = null) @@ -216,32 +218,41 @@ class Page // Reset header and content. $this->modified = time(); - $this->id($this->modified().md5($this->filePath())); + $this->id($this->modified() . md5($this->filePath())); $this->header = null; $this->content = null; $this->summary = null; } + return $file ? $file->raw() : ''; } + /** + * Gets and Sets the page frontmatter + * + * @param string|null $var + * + * @return string + */ public function frontmatter($var = null) { if ($var) { - $this->frontmatter = (string) $var; + $this->frontmatter = (string)$var; // Update also file object. $file = $this->file(); if ($file) { - $file->frontmatter((string) $var); + $file->frontmatter((string)$var); } // Force content re-processing. - $this->id(time().md5($this->filePath())); + $this->id(time() . md5($this->filePath())); } if (!$this->frontmatter) { $this->header(); } + return $this->frontmatter; } @@ -249,21 +260,22 @@ class Page * Gets and Sets the header based on the YAML configuration at the top of the .md file * * @param object|array $var a YAML object representing the configuration for the file + * * @return object the current YAML configuration */ public function header($var = null) { if ($var) { - $this->header = (object) $var; + $this->header = (object)$var; // Update also file object. $file = $this->file(); if ($file) { - $file->header((array) $var); + $file->header((array)$var); } // Force content re-processing. - $this->id(time().md5($this->filePath())); + $this->id(time() . md5($this->filePath())); } if (!$this->header) { $file = $this->file(); @@ -275,7 +287,13 @@ class Page $this->frontmatter = $file->frontmatter(); $this->header = (object)$file->header(); } catch (ParseException $e) { - $file->raw(self::getGrav()['language']->translate(['FRONTMATTER_ERROR_PAGE', $this->slug(), $file->filename(), $e->getMessage(), $file->raw()])); + $file->raw(self::getGrav()['language']->translate([ + 'FRONTMATTER_ERROR_PAGE', + $this->slug(), + $file->filename(), + $e->getMessage(), + $file->raw() + ])); $this->raw_content = $file->markdown(); $this->frontmatter = $file->frontmatter(); $this->header = (object)$file->header(); @@ -304,10 +322,10 @@ class Page $this->menu = trim($this->header->menu); } if (isset($this->header->routable)) { - $this->routable = (bool) $this->header->routable; + $this->routable = (bool)$this->header->routable; } if (isset($this->header->visible)) { - $this->visible = (bool) $this->header->visible; + $this->visible = (bool)$this->header->visible; } if (isset($this->header->redirect)) { $this->redirect = trim($this->header->redirect); @@ -328,7 +346,7 @@ class Page $this->markdown_extra = (bool)$this->header->markdown_extra; } if (isset($this->header->taxonomy)) { - foreach ((array) $this->header->taxonomy as $taxonomy => $taxitems) { + foreach ((array)$this->header->taxonomy as $taxonomy => $taxitems) { $this->taxonomy[$taxonomy] = (array)$taxitems; } } @@ -336,12 +354,12 @@ class Page $this->max_count = intval($this->header->max_count); } if (isset($this->header->process)) { - foreach ((array) $this->header->process as $process => $status) { - $this->process[$process] = (bool) $status; + foreach ((array)$this->header->process as $process => $status) { + $this->process[$process] = (bool)$status; } } if (isset($this->header->published)) { - $this->published = (bool) $this->header->published; + $this->published = (bool)$this->header->published; } if (isset($this->header->publish_date)) { $this->publishDate($this->header->publish_date); @@ -353,10 +371,10 @@ class Page $this->expires = intval($this->header->expires); } if (isset($this->header->etag)) { - $this->etag = (bool) $this->header->etag; + $this->etag = (bool)$this->header->etag; } if (isset($this->header->last_modified)) { - $this->last_modified = (bool) $this->header->last_modified; + $this->last_modified = (bool)$this->header->last_modified; } } @@ -393,12 +411,13 @@ class Page /** * Get the summary. * - * @param int $size Max summary size. + * @param int $size Max summary size. + * * @return string */ public function summary($size = null) { - $config = (array) self::getGrav()['config']->get('site.summary'); + $config = (array)self::getGrav()['config']->get('site.summary'); if (isset($this->header->summary)) { $config = array_merge($config, $this->header->summary); } @@ -420,7 +439,7 @@ class Page // Return calculated summary based on summary divider's position $format = $config['format']; // Return entire page content on wrong/ unknown format - if (!in_array($format, array('short', 'long'))) { + if (!in_array($format, ['short', 'long'])) { return $content; } elseif (($format === 'short') && isset($summary_size)) { return mb_substr($content, 0, $summary_size); @@ -434,7 +453,7 @@ class Page // If the size is zero, return the entire page content if ($size === 0) { return $content; - // Return calculated summary based on defaults + // Return calculated summary based on defaults } elseif (!is_numeric($size) || ($size < 0)) { $size = 300; } @@ -445,7 +464,7 @@ class Page /** * Sets the summary of the page * - * @param string $var Summary + * @param string $summary Summary */ public function setSummary($summary) { @@ -456,6 +475,7 @@ class Page * Gets and Sets the content based on content portion of the .md file * * @param string $var Content + * * @return string Content */ public function content($var = null) @@ -470,7 +490,7 @@ class Page } // Force re-processing. - $this->id(time().md5($this->filePath())); + $this->id(time() . md5($this->filePath())); $this->content = null; } // If no content, process it @@ -484,13 +504,15 @@ class Page // Load cached content /** @var Cache $cache */ $cache = self::getGrav()['cache']; - $cache_id = md5('page'.$this->id()); + $cache_id = md5('page' . $this->id()); $this->content = $cache->fetch($cache_id); $process_markdown = $this->shouldProcess('markdown'); $process_twig = $this->shouldProcess('twig'); - $cache_enable = isset($this->header->cache_enable) ? $this->header->cache_enable : $config->get('system.cache.enabled', true); - $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : $config->get('system.pages.twig_first', true); + $cache_enable = isset($this->header->cache_enable) ? $this->header->cache_enable : $config->get('system.cache.enabled', + true); + $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : $config->get('system.pages.twig_first', + true); // if no cached-content run everything @@ -548,7 +570,7 @@ class Page /** @var Config $config */ $config = self::getGrav()['config']; - $defaults = (array) $config->get('system.pages.markdown'); + $defaults = (array)$config->get('system.pages.markdown'); if (isset($this->header()->markdown)) { $defaults = array_merge($defaults, $this->header()->markdown); } @@ -584,7 +606,7 @@ class Page private function cachePageContent() { $cache = self::getGrav()['cache']; - $cache_id = md5('page'.$this->id()); + $cache_id = md5('page' . $this->id()); $cache->save($cache_id, $this->content); } @@ -611,8 +633,9 @@ class Page /** * Get value from a page variable (used mostly for creating edit forms). * - * @param string $name Variable name. - * @param mixed $default + * @param string $name Variable name. + * @param mixed $default + * * @return mixed */ public function value($name, $default = null) @@ -625,21 +648,24 @@ class Page } if ($name == 'order') { $order = $this->order(); - return $order ? (int) $this->order() : ''; + + return $order ? (int)$this->order() : ''; } if ($name == 'ordering') { - return (bool) $this->order(); + return (bool)$this->order(); } if ($name == 'folder') { $regex = '/^[0-9]+\./u'; + return preg_replace($regex, '', $this->folder); } if ($name == 'name') { $language = $this->language() ? '.' . $this->language() : ''; - $name_val = str_replace($language .'.md', '', $this->name()); + $name_val = str_replace($language . '.md', '', $this->name()); if ($this->modular()) { return 'modular/' . $name_val; } + return $name_val; } if ($name == 'media') { @@ -683,6 +709,13 @@ class Page return $default; } + /** + * Gets and Sets the Page raw content + * + * @param null $var + * + * @return null + */ public function rawMarkdown($var = null) { if ($var !== null) { @@ -702,11 +735,13 @@ class Page if ($this->name) { return MarkdownFile::instance($this->filePath()); } + return null; } /** * Save page if there's a file assigned to it. + * * @param bool $reorder Internal use. */ public function save($reorder = true) @@ -717,7 +752,7 @@ class Page $file = $this->file(); if ($file) { $file->filename($this->filePath()); - $file->header((array) $this->header()); + $file->header((array)$this->header()); $file->markdown($this->raw_content); $file->save(); } @@ -729,6 +764,7 @@ class Page * You need to call $this->save() in order to perform the move. * * @param Page $parent New parent page. + * * @return $this */ public function move(Page $parent) @@ -740,16 +776,16 @@ class Page $this->_action = 'move'; $this->parent($parent); - $this->id(time().md5($this->filePath())); + $this->id(time() . md5($this->filePath())); if ($parent->path()) { $this->path($parent->path() . '/' . $this->folder()); } if ($parent->route()) { - $this->route($parent->route() . '/'. $this->slug()); + $this->route($parent->route() . '/' . $this->slug()); } else { - $this->route(self::getGrav()['pages']->root()->route() . '/'. $this->slug()); + $this->route(self::getGrav()['pages']->root()->route() . '/' . $this->slug()); } return $this; @@ -762,6 +798,7 @@ class Page * You need to call $this->save() in order to perform the move. * * @param Page $parent New parent page. + * * @return $this */ public function copy($parent) @@ -842,6 +879,7 @@ class Page public function extra() { $blueprints = $this->blueprints(); + return $blueprints->extra($this->toArray()['header'], 'header.'); } @@ -852,10 +890,10 @@ class Page */ public function toArray() { - return array( - 'header' => (array) $this->header(), - 'content' => (string) $this->value('content') - ); + return [ + 'header' => (array)$this->header(), + 'content' => (string)$this->value('content') + ]; } /** @@ -882,6 +920,7 @@ class Page * Gets and sets the associated media as found in the page folder. * * @param Media $var Representation of associated media. + * * @return Media Representation of associated media. */ public function media($var = null) @@ -894,13 +933,14 @@ class Page } if ($this->media === null) { // Use cached media if possible. - $media_cache_id = md5('media'.$this->id()); + $media_cache_id = md5('media' . $this->id()); if (!$media = $cache->fetch($media_cache_id)) { $media = new Media($this->path()); $cache->save($media_cache_id, $media); } $this->media = $media; } + return $this->media; } @@ -908,6 +948,7 @@ class Page * Gets and sets the name field. If no name field is set, it will return 'default.md'. * * @param string $var The name of this page. + * * @return string The name of this page. */ public function name($var = null) @@ -915,6 +956,7 @@ class Page if ($var !== null) { $this->name = $var; } + return empty($this->name) ? 'default.md' : $this->name; } @@ -925,7 +967,7 @@ class Page */ public function childType() { - return isset($this->header->child_type) ? (string) $this->header->child_type : 'default'; + return isset($this->header->child_type) ? (string)$this->header->child_type : 'default'; } /** @@ -933,6 +975,7 @@ class Page * If no field is set, it will return the name without the .md extension * * @param string $var the template name + * * @return string the template name */ public function template($var = null) @@ -943,6 +986,7 @@ class Page if (empty($this->template)) { $this->template = ($this->modular() ? 'modular/' : '') . str_replace($this->extension(), '', $this->name()); } + return $this->template; } @@ -950,6 +994,7 @@ class Page * Gets and sets the extension field. * * @param null $var + * * @return null|string */ public function extension($var = null) @@ -960,6 +1005,7 @@ class Page if (empty($this->extension)) { $this->extension = '.' . pathinfo($this->name(), PATHINFO_EXTENSION); } + return $this->extension; } @@ -986,14 +1032,16 @@ class Page /** * Gets and sets the expires field. If not set will return the default * - * @param string $var The name of this page. - * @return string The name of this page. + * @param int $var The new expires value. + * + * @return int The expires value */ public function expires($var = null) { if ($var !== null) { $this->expires = $var; } + return empty($this->expires) ? self::getGrav()['config']->get('system.pages.expires') : $this->expires; } @@ -1001,6 +1049,7 @@ class Page * Gets and sets the title for this Page. If no title is set, it will use the slug() to get a name * * @param string $var the title of the Page + * * @return string the title of the Page */ public function title($var = null) @@ -1011,6 +1060,7 @@ class Page if (empty($this->title)) { $this->title = ucfirst($this->slug()); } + return $this->title; } @@ -1019,6 +1069,7 @@ class Page * If no menu field is set, it will use the title() * * @param string $var the menu field for the page + * * @return string the menu field for the page */ public function menu($var = null) @@ -1029,6 +1080,7 @@ class Page if (empty($this->menu)) { $this->menu = $this->title(); } + return $this->menu; } @@ -1036,12 +1088,13 @@ class Page * Gets and Sets whether or not this Page is visible for navigation * * @param bool $var true if the page is visible + * * @return bool true if the page is visible */ public function visible($var = null) { if ($var !== null) { - $this->visible = (bool) $var; + $this->visible = (bool)$var; } if ($this->visible === null) { @@ -1054,6 +1107,7 @@ class Page $this->visible = false; } } + return $this->visible; } @@ -1061,12 +1115,13 @@ class Page * Gets and Sets whether or not this Page is considered published * * @param bool $var true if the page is published + * * @return bool true if the page is published */ public function published($var = null) { if ($var !== null) { - $this->published = (bool) $var; + $this->published = (bool)$var; } // If not published, should not be visible in menus either @@ -1081,6 +1136,7 @@ class Page * Gets and Sets the Page publish date * * @param string $var string representation of a date + * * @return int unix timestamp representation of the date */ public function publishDate($var = null) @@ -1096,6 +1152,7 @@ class Page * Gets and Sets the Page unpublish date * * @param string $var string representation of a date + * * @return int|null unix timestamp representation of the date */ public function unpublishDate($var = null) @@ -1113,12 +1170,13 @@ class Page * The page must be *routable* and *published* * * @param bool $var true if the page is routable + * * @return bool true if the page is routable */ public function routable($var = null) { if ($var !== null) { - $this->routable = (bool) $var; + $this->routable = (bool)$var; } return $this->routable && $this->published(); @@ -1129,13 +1187,15 @@ class Page * a simple array of arrays with the form array("markdown"=>true) for example * * @param array $var an Array of name value pairs where the name is the process and value is true or false + * * @return array an Array of name value pairs where the name is the process and value is true or false */ public function process($var = null) { if ($var !== null) { - $this->process = (array) $var; + $this->process = (array)$var; } + return $this->process; } @@ -1144,12 +1204,13 @@ class Page * that can then be rendered in the page. * * @param array $var an Array of metadata values to set + * * @return array an Array of metadata values for the page */ public function metadata($var = null) { if ($var !== null) { - $this->metadata = (array) $var; + $this->metadata = (array)$var; } // if not metadata yet, process it. @@ -1163,7 +1224,7 @@ class Page $metadata['generator'] = 'GravCMS'; // Get initial metadata for the page - $metadata = array_merge($metadata, self::getGrav()['config']->get('site.metadata')); + $metadata = array_merge($metadata, self::getGrav()['config']->get('site.metadata')); if (isset($this->header->metadata)) { // Merge any site.metadata settings in with page metadata @@ -1175,16 +1236,22 @@ class Page // If this is a property type metadata: "og", "twitter", "facebook" etc if (is_array($value)) { foreach ($value as $property => $prop_value) { - $prop_key = $key.":".$property; - $this->metadata[$prop_key] = array('property'=>$prop_key, 'content'=>htmlspecialchars($prop_value, ENT_QUOTES)); + $prop_key = $key . ":" . $property; + $this->metadata[$prop_key] = [ + 'property' => $prop_key, + 'content' => htmlspecialchars($prop_value, ENT_QUOTES) + ]; } - // If it this is a standard meta data type + // If it this is a standard meta data type } else { if ($value) { if (in_array($key, $header_tag_http_equivs)) { - $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES)); + $this->metadata[$key] = [ + 'http_equiv' => $key, + 'content' => htmlspecialchars($value, ENT_QUOTES) + ]; } else { - $this->metadata[$key] = array('name'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES)); + $this->metadata[$key] = ['name' => $key, 'content' => htmlspecialchars($value, ENT_QUOTES)]; } } } @@ -1200,6 +1267,7 @@ class Page * the parent folder from the path * * @param string $var the slug, e.g. 'my-blog' + * * @return string the slug */ public function slug($var = null) @@ -1219,6 +1287,7 @@ class Page * Get/set order number of this page. * * @param int $var + * * @return int|bool */ public function order($var = null) @@ -1245,6 +1314,7 @@ class Page * Gets the URL for a page - alias of url(). * * @param bool $include_host + * * @return string the permalink */ public function link($include_host = false) @@ -1255,8 +1325,9 @@ class Page /** * Gets the url for the Page. * - * @param bool $include_host Defaults false, but true would include http://yourhost.com - * @param bool $canonical true to return the canonical URL + * @param bool $include_host Defaults false, but true would include http://yourhost.com + * @param bool $canonical true to return the canonical URL + * @param bool $include_lang * * @return string The url. */ @@ -1270,7 +1341,7 @@ class Page // get pre-route if ($include_lang && $language->enabled()) { - $pre_route = $language->getLanguageURLPrefix(); + $pre_route = $language->getLanguageURLPrefix(); } else { $pre_route = ''; } @@ -1287,7 +1358,7 @@ class Page $rootUrl = $uri->rootUrl($include_host) . $pages->base(); - $url = $rootUrl.'/'.trim($route, '/') . $this->urlExtension(); + $url = $rootUrl . '/' . trim($route, '/') . $this->urlExtension(); // trim trailing / if not root if ($url !== '/') { @@ -1301,7 +1372,7 @@ class Page * Gets the route for the page based on the route headers if available, else from * the parents route and the current Page's slug. * - * @param string $var Set new default route. + * @param string $var Set new default route. * * @return string The route for the Page. */ @@ -1320,15 +1391,16 @@ class Page if ($this->hide_home_route && $parent->route() == $this->home_route) { $baseRoute = ''; } else { - $baseRoute = (string) $parent->route(); + $baseRoute = (string)$parent->route(); } } - $this->route = isset($baseRoute) ? $baseRoute . '/'. $this->slug() : null; + $this->route = isset($baseRoute) ? $baseRoute . '/' . $this->slug() : null; if (!empty($this->routes) && isset($this->routes['default'])) { $this->routes['aliases'][] = $this->route; $this->route = $this->routes['default']; + return $this->route; } } @@ -1345,6 +1417,13 @@ class Page unset($this->slug); } + /** + * Gets and Sets the page raw route + * + * @param null $var + * + * @return null|string + */ public function rawRoute($var = null) { if ($var !== null) { @@ -1352,12 +1431,12 @@ class Page } if (empty($this->raw_route)) { - $baseRoute = $this->parent ? (string) $this->parent()->rawRoute() : null; + $baseRoute = $this->parent ? (string)$this->parent()->rawRoute() : null; $regex = '/^[0-9]+\./u'; $slug = preg_replace($regex, '', $this->folder); - $this->raw_route = isset($baseRoute) ? $baseRoute . '/'. $slug : null; + $this->raw_route = isset($baseRoute) ? $baseRoute . '/' . $slug : null; } return $this->raw_route; @@ -1366,14 +1445,14 @@ class Page /** * Gets the route aliases for the page based on page headers. * - * @param array $var list of route aliases + * @param array $var list of route aliases * * @return array The route aliases for the Page. */ public function routeAliases($var = null) { if ($var !== null) { - $this->routes['aliases'] = (array) $var; + $this->routes['aliases'] = (array)$var; } if (!empty($this->routes) && isset($this->routes['aliases'])) { @@ -1408,6 +1487,7 @@ class Page * Gets and sets the identifier for this Page object. * * @param string $var the identifier + * * @return string the identifier */ public function id($var = null) @@ -1415,6 +1495,7 @@ class Page if ($var !== null) { $this->id = $var; } + return $this->id; } @@ -1422,6 +1503,7 @@ class Page * Gets and sets the modified timestamp. * * @param int $var modified unix timestamp + * * @return int modified unix timestamp */ public function modified($var = null) @@ -1437,6 +1519,7 @@ class Page * Gets the redirect set in the header. * * @param string $var redirect url + * * @return array */ public function redirect($var = null) @@ -1444,6 +1527,7 @@ class Page if ($var !== null) { $this->redirect = $var; } + return $this->redirect; } @@ -1451,6 +1535,7 @@ class Page * Gets and sets the option to show the etag header for the page. * * @param boolean $var show etag header + * * @return boolean show etag header */ public function eTag($var = null) @@ -1459,8 +1544,9 @@ class Page $this->etag = $var; } if (!isset($this->etag)) { - $this->etag = (bool) self::getGrav()['config']->get('system.pages.etag'); + $this->etag = (bool)self::getGrav()['config']->get('system.pages.etag'); } + return $this->etag; } @@ -1468,6 +1554,7 @@ class Page * Gets and sets the option to show the last_modified header for the page. * * @param boolean $var show last_modified header + * * @return boolean show last_modified header */ public function lastModified($var = null) @@ -1476,8 +1563,9 @@ class Page $this->last_modified = $var; } if (!isset($this->last_modified)) { - $this->last_modified = (bool) self::getGrav()['config']->get('system.pages.last_modified'); + $this->last_modified = (bool)self::getGrav()['config']->get('system.pages.last_modified'); } + return $this->last_modified; } @@ -1485,6 +1573,7 @@ class Page * Gets and sets the path to the .md file for this Page object. * * @param string $var the file path + * * @return string|null the file path */ public function filePath($var = null) @@ -1497,6 +1586,7 @@ class Page // Path to the page. $this->path = dirname(dirname($var)); } + return $this->path . '/' . $this->folder . '/' . ($this->name ?: ''); } @@ -1508,6 +1598,7 @@ class Page public function filePathClean() { $path = str_replace(ROOT_DIR, '', $this->filePath()); + return $path; } @@ -1516,7 +1607,8 @@ class Page */ public function relativePagePath() { - $path = str_replace('/'.$this->name, '', $this->filePathClean()); + $path = str_replace('/' . $this->name, '', $this->filePathClean()); + return $path; } @@ -1525,6 +1617,7 @@ class Page * This is equivalent to the filePath but without the filename. * * @param string $var the path + * * @return string|null the path */ public function path($var = null) @@ -1535,6 +1628,7 @@ class Page // Path to the page. $this->path = dirname($var); } + return $this->path ? $this->path . '/' . $this->folder : null; } @@ -1542,6 +1636,7 @@ class Page * Get/set the folder. * * @param string $var Optional path + * * @return string|null */ public function folder($var = null) @@ -1549,6 +1644,7 @@ class Page if ($var !== null) { $this->folder = $var; } + return $this->folder; } @@ -1556,6 +1652,7 @@ class Page * Gets and sets the date for this Page object. This is typically passed in via the page headers * * @param string $var string representation of a date + * * @return int unix timestamp representation of the date */ public function date($var = null) @@ -1573,7 +1670,9 @@ class Page /** * Gets and sets the order by which any sub-pages should be sorted. + * * @param string $var the order, either "asc" or "desc" + * * @return string the order, either "asc" or "desc" */ public function orderDir($var = null) @@ -1584,6 +1683,7 @@ class Page if (empty($this->order_dir)) { $this->order_dir = 'asc'; } + return $this->order_dir; } @@ -1596,6 +1696,7 @@ class Page * folder - is the order based on the name of the folder with any numerics omitted * * @param string $var supported options include "default", "title", "date", and "folder" + * * @return string supported options include "default", "title", "date", and "folder" */ public function orderBy($var = null) @@ -1603,6 +1704,7 @@ class Page if ($var !== null) { $this->order_by = $var; } + return $this->order_by; } @@ -1610,6 +1712,7 @@ class Page * Gets the manual order set in the header. * * @param string $var supported options include "default", "title", "date", and "folder" + * * @return array */ public function orderManual($var = null) @@ -1617,7 +1720,8 @@ class Page if ($var !== null) { $this->order_manual = $var; } - return (array) $this->order_manual; + + return (array)$this->order_manual; } /** @@ -1625,18 +1729,20 @@ class Page * sub_pages header property is set for this page object. * * @param int $var the maximum number of sub-pages + * * @return int the maximum number of sub-pages */ public function maxCount($var = null) { if ($var !== null) { - $this->max_count = (int) $var; + $this->max_count = (int)$var; } if (empty($this->max_count)) { /** @var Config $config */ $config = self::getGrav()['config']; - $this->max_count = (int) $config->get('system.pages.list.count'); + $this->max_count = (int)$config->get('system.pages.list.count'); } + return $this->max_count; } @@ -1644,6 +1750,7 @@ class Page * Gets and sets the taxonomy array which defines which taxonomies this page identifies itself with. * * @param array $var an array of taxonomies + * * @return array an array of taxonomies */ public function taxonomy($var = null) @@ -1651,13 +1758,15 @@ class Page if ($var !== null) { $this->taxonomy = $var; } + return $this->taxonomy; } - /** + /** * Gets and sets the modular var that helps identify this parent page contains modular pages. * * @param bool $var true if modular_twig + * * @return bool true if modular_twig */ public function modular($var = null) @@ -1670,12 +1779,13 @@ class Page * twig processing handled differently from a regular page. * * @param bool $var true if modular_twig + * * @return bool true if modular_twig */ public function modularTwig($var = null) { if ($var !== null) { - $this->modular_twig = (bool) $var; + $this->modular_twig = (bool)$var; if ($var) { $this->process['twig'] = true; $this->visible(false); @@ -1685,6 +1795,7 @@ class Page } } } + return $this->modular_twig; } @@ -1692,23 +1803,26 @@ class Page * Gets the configured state of the processing method. * * @param string $process the process, eg "twig" or "markdown" + * * @return bool whether or not the processing method is enabled for this Page */ public function shouldProcess($process) { - return isset($this->process[$process]) ? (bool) $this->process[$process] : false; + return isset($this->process[$process]) ? (bool)$this->process[$process] : false; } /** * Gets and Sets the parent object for this page * * @param Page $var the parent page object + * * @return Page|null the parent page object if it exists. */ public function parent(Page $var = null) { if ($var) { $this->parent = $var->path(); + return $var; } @@ -1752,6 +1866,7 @@ class Page { /** @var Pages $pages */ $pages = self::getGrav()['pages']; + return $pages->children($this->path()); } @@ -1767,6 +1882,7 @@ class Page if ($collection instanceof Collection) { return $collection->isFirst($this->path()); } + return true; } @@ -1781,6 +1897,7 @@ class Page if ($collection instanceof Collection) { return $collection->isLast($this->path()); } + return true; } @@ -1808,6 +1925,7 @@ class Page * Returns the adjacent sibling based on a direction. * * @param integer $direction either -1 or +1 + * * @return Page the sibling page */ public function adjacentSibling($direction = 1) @@ -1816,6 +1934,7 @@ class Page if ($collection instanceof Collection) { return $collection->adjacentSibling($this->path(), $direction); } + return false; } @@ -1835,6 +1954,7 @@ class Page } } + return false; } @@ -1852,6 +1972,7 @@ class Page $routes = self::getGrav()['pages']->routes(); if (isset($routes[$uri_path])) { + /** @var Page $child_page */ $child_page = $pages->dispatch($uri->route())->parent(); if ($child_page) { while (!$child_page->root()) { @@ -1893,8 +2014,8 @@ class Page /** * Helper method to return a page. * - * @param string $url the url of the page - * @param bool $all + * @param string $url the url of the page + * @param bool $all * * @return \Grav\Common\Page\Page page you were looking for if it exists */ @@ -1902,6 +2023,7 @@ class Page { /** @var Pages $pages */ $pages = self::getGrav()['pages']; + return $pages->dispatch($url, $all); } @@ -1909,20 +2031,21 @@ class Page * Get a collection of pages in the current context. * * @param string|array $params - * @param boolean $pagination + * @param boolean $pagination + * * @return Collection * @throws \InvalidArgumentException */ public function collection($params = 'content', $pagination = true) { if (is_string($params)) { - $params = (array) $this->value('header.'.$params); + $params = (array)$this->value('header.' . $params); } elseif (!is_array($params)) { throw new \InvalidArgumentException('Argument should be either header variable name or array of parameters'); } if (!isset($params['items'])) { - return array(); + return []; } $collection = $this->evaluate($params['items']); @@ -1939,7 +2062,7 @@ class Page $process_taxonomy = isset($params['url_taxonomy_filters']) ? $params['url_taxonomy_filters'] : $config->get('system.pages.url_taxonomy_filters'); if ($process_taxonomy) { - foreach ((array) $config->get('site.taxonomies') as $taxonomy) { + foreach ((array)$config->get('site.taxonomies') as $taxonomy) { if ($uri->param($taxonomy)) { $items = explode(',', $uri->param($taxonomy)); $collection->setParams(['taxonomies' => [$taxonomy => $items]]); @@ -1950,8 +2073,9 @@ class Page continue; } foreach ($items as $item) { - if (empty($page->taxonomy[$taxonomy]) - || !in_array(htmlspecialchars_decode($item, ENT_QUOTES), $page->taxonomy[$taxonomy])) { + if (empty($page->taxonomy[$taxonomy]) || !in_array(htmlspecialchars_decode($item, + ENT_QUOTES), $page->taxonomy[$taxonomy]) + ) { $collection->remove(); } } @@ -2007,21 +2131,22 @@ class Page if (is_string($value)) { // Format: @command.param $cmd = $value; - $params = array(); + $params = []; } elseif (is_array($value) && count($value) == 1 && !is_int(key($value))) { // Format: @command.param: { attr1: value1, attr2: value2 } - $cmd = (string) key($value); - $params = (array) current($value); + $cmd = (string)key($value); + $params = (array)current($value); } else { $result = []; - foreach($value as $key => $val) { + foreach ($value as $key => $val) { if (is_int($key)) { $result = $result + $this->evaluate($val)->toArray(); } else { - $result = $result + $this->evaluate([$key=>$val])->toArray(); + $result = $result + $this->evaluate([$key => $val])->toArray(); } } + return new Collection($result); } @@ -2036,7 +2161,9 @@ class Page $parts = explode('.', $cmd); $current = array_shift($parts); + /** @var Collection $results */ $results = new Collection(); + switch ($current) { case '@self': if (!empty($parts)) { @@ -2145,6 +2272,7 @@ class Page if ($this->name) { return true; } + return false; } @@ -2166,6 +2294,7 @@ class Page public function exists() { $file = $this->file(); + return $file && $file->exists(); } @@ -2173,6 +2302,7 @@ class Page * Cleans the path. * * @param string $path the path + * * @return string the path */ protected function cleanPath($path) @@ -2181,6 +2311,7 @@ class Page if (strpos($lastchunk, ':') !== false) { $path = str_replace($lastchunk, '', $path); } + return $path; } @@ -2188,6 +2319,10 @@ class Page * Moves or copies the page in filesystem. * * @internal + * + * @param bool $reorder + * + * @throws Exception */ protected function doRelocation($reorder) { @@ -2203,7 +2338,7 @@ class Page $parent = $this->parent(); // Extract visible children from the parent page. - $list = array(); + $list = []; /** @var Page $page */ foreach ($parent->children()->visible() as $page) { if ($page->order()) { @@ -2220,21 +2355,21 @@ class Page // Then add it back to the new location (if needed). if ($this->order()) { - array_splice($list, min($this->order()-1, count($list)), 0, array($this->path())); + array_splice($list, min($this->order() - 1, count($list)), 0, [$this->path()]); } // Reorder all moved pages. foreach ($list as $order => $path) { if ($path == $this->path()) { // Handle current page; we do want to change ordering number, but nothing else. - $this->order($order+1); + $this->order($order + 1); } else { // Handle all the other pages. $page = $pages->get($path); - if ($page && $page->exists() && !$page->_action && $page->order() != $order+1) { + if ($page && $page->exists() && !$page->_action && $page->order() != $order + 1) { $page = $page->move($parent); - $page->order($order+1); + $page->order($order + 1); $page->save(false); } } diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 2dd1bbadf..df5259899 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -1,15 +1,15 @@ $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]; } diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index bee2c69f6..f066bff20 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -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; } diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index 1b0bd510b..eebd3e7ee 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -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://'); diff --git a/system/src/Grav/Common/Session.php b/system/src/Grav/Common/Session.php index bb34d3b2c..c73ddcfca 100644 --- a/system/src/Grav/Common/Session.php +++ b/system/src/Grav/Common/Session.php @@ -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') { diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php index e280e81f7..ea01c9907 100644 --- a/system/src/Grav/Common/Taxonomy.php +++ b/system/src/Grav/Common/Taxonomy.php @@ -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; } } diff --git a/system/src/Grav/Common/Theme.php b/system/src/Grav/Common/Theme.php index 2f4ed468c..f76e5f0b7 100644 --- a/system/src/Grav/Common/Theme.php +++ b/system/src/Grav/Common/Theme.php @@ -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; } diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 358275fab..7490cef8e 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -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); } } diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index a478646b9..5900622a1 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -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; } } diff --git a/system/src/Grav/Common/User/Authentication.php b/system/src/Grav/Common/User/Authentication.php index fc26bf8d7..4d3660385 100644 --- a/system/src/Grav/Common/User/Authentication.php +++ b/system/src/Grav/Common/User/Authentication.php @@ -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) diff --git a/system/src/Grav/Common/User/Group.php b/system/src/Grav/Common/User/Group.php index 965fde5f6..0a424f418 100644 --- a/system/src/Grav/Common/User/Group.php +++ b/system/src/Grav/Common/User/Group.php @@ -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) diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index 0690d9e06..da51c1235 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -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 */ diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index eb88c1937..597bae22a 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -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 diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index adcf87638..ff6d28614 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -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', diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index de965df5e..be692dc02 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -55,6 +55,7 @@ class SandboxCommand extends ConsoleCommand '/system' => '/system', '/vendor' => '/vendor', '/webserver-configs' => '/webserver-configs', + '/codeception.yml' => '/codeception.yml', ); /** diff --git a/tests/unit/Grav/Common/AssetsTest.php b/tests/unit/Grav/Common/AssetsTest.php index ec6508a15..82f37ba22 100644 --- a/tests/unit/Grav/Common/AssetsTest.php +++ b/tests/unit/Grav/Common/AssetsTest.php @@ -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, '' . 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, '' . 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, '' . 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, '' . 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, '' . 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, '' . 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, '' . 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, '' . 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. '' . PHP_EOL); + $this->assertSame($js, + PHP_EOL . '' . PHP_EOL); } -} \ No newline at end of file + 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); + + } +} diff --git a/tests/unit/Grav/Common/MarkdownTest.php b/tests/unit/Grav/Common/MarkdownTest.php new file mode 100644 index 000000000..9b08c5169 --- /dev/null +++ b/tests/unit/Grav/Common/MarkdownTest.php @@ -0,0 +1,74 @@ + 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)'), '

mailto

'); + $this->assertSame($this->parsedown->text('[xmpp](xmpp:xyx@domain.com)'), '

xmpp

'); + $this->assertSame($this->parsedown->text('[tel](tel:123-555-12345)'), '

tel

'); + $this->assertSame($this->parsedown->text('[sms](sms:123-555-12345)'), '

sms

'); + } + + public function testMarkdownReferenceLinks() + { + $sample = '[relative link][r_relative] + [r_relative]: ../03.assets#blah'; + $this->assertSame($this->parsedown->text($sample), '

relative link

'); + + $sample = '[absolute link][r_absolute] + [r_absolute]: /blog/focus-and-blur#blah'; + $this->assertSame($this->parsedown->text($sample), '

absolute link

'); + + $sample = '[external link][r_external] + [r_external]: http://www.cnn.com'; + $this->assertSame($this->parsedown->text($sample), '

external link

'); + } + + public function testMarkdownExternalLinks() + { + $this->assertSame($this->parsedown->text('[cnn.com](http://www.cnn.com)'), '

cnn.com

'); + $this->assertSame($this->parsedown->text('[google.com](https://www.google.com)'), '

google.com

'); + } +} diff --git a/tests/unit/Grav/Common/UriTest.php b/tests/unit/Grav/Common/UriTest.php index 14cb9d7ae..94c2f6c88 100644 --- a/tests/unit/Grav/Common/UriTest.php +++ b/tests/unit/Grav/Common/UriTest.php @@ -1,6 +1,7 @@ '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')); }