mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 15:29:57 +01:00
Compare commits
139 Commits
1.0.0-rc.2
...
1.0.0-rc.5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50c6e81c09 | ||
|
|
2a0a9a225c | ||
|
|
aee92b58c7 | ||
|
|
16db950009 | ||
|
|
bde33e7188 | ||
|
|
267efbe164 | ||
|
|
f9e137c994 | ||
|
|
e7f9751403 | ||
|
|
06d663680c | ||
|
|
1bbdca5032 | ||
|
|
c1654a988e | ||
|
|
18a540c867 | ||
|
|
99fc8df322 | ||
|
|
2d21cb8b1e | ||
|
|
d8008654b9 | ||
|
|
146295fb1e | ||
|
|
63e083ea37 | ||
|
|
b1630feb5d | ||
|
|
1185a91c90 | ||
|
|
dce6d7894b | ||
|
|
375ee0d1fa | ||
|
|
ce0574f897 | ||
|
|
c515111446 | ||
|
|
7d6393628e | ||
|
|
24fde7261a | ||
|
|
3d922abf1a | ||
|
|
7f1d3a94fe | ||
|
|
3d774b7585 | ||
|
|
b0083548b6 | ||
|
|
905dae3b16 | ||
|
|
d79979371b | ||
|
|
c4bff94f7d | ||
|
|
7c4fd3858c | ||
|
|
3b9af8883d | ||
|
|
29b34d7de0 | ||
|
|
5193551d04 | ||
|
|
d2660e0755 | ||
|
|
2d8ac27fdd | ||
|
|
49a5b38589 | ||
|
|
6e2f792bb9 | ||
|
|
da098fd46a | ||
|
|
3e081b340f | ||
|
|
698015a03d | ||
|
|
000a10f936 | ||
|
|
c764e31c8a | ||
|
|
c18021d52a | ||
|
|
3d0cc67415 | ||
|
|
3f94a6fda9 | ||
|
|
7f0eefbde5 | ||
|
|
280377985f | ||
|
|
d5b3f070a5 | ||
|
|
3505ef046d | ||
|
|
a6bc565356 | ||
|
|
a1ee3cf4e4 | ||
|
|
e96445abe3 | ||
|
|
c22fae0d3d | ||
|
|
3cf6e8762c | ||
|
|
f0cdd7c03e | ||
|
|
5e40201888 | ||
|
|
f2c2debb28 | ||
|
|
0e3e7497ac | ||
|
|
72313ac9ec | ||
|
|
dc80228f0b | ||
|
|
a83642a7e3 | ||
|
|
00d8403095 | ||
|
|
e1ec8e9742 | ||
|
|
0725af5367 | ||
|
|
65e543af02 | ||
|
|
b49e8315eb | ||
|
|
c5a89112b4 | ||
|
|
94ec474ffa | ||
|
|
da4593fdc1 | ||
|
|
b8413cefaf | ||
|
|
d3097e4fd0 | ||
|
|
51753f0716 | ||
|
|
b7ada873b8 | ||
|
|
ed8b08a9e4 | ||
|
|
e1fdb6803d | ||
|
|
5cb9f2f42f | ||
|
|
fcf48ed2e5 | ||
|
|
050512536a | ||
|
|
99207fca13 | ||
|
|
77d80f12f3 | ||
|
|
e400207a65 | ||
|
|
4b68036a1b | ||
|
|
a95b716aa7 | ||
|
|
dc8efded34 | ||
|
|
e016b17276 | ||
|
|
b99876f0b4 | ||
|
|
66abc842b7 | ||
|
|
9f36158c67 | ||
|
|
18c1ca3919 | ||
|
|
0c729e5b0a | ||
|
|
55f3b78ab1 | ||
|
|
a73b796ca7 | ||
|
|
bb0bca7ef1 | ||
|
|
b3144ee921 | ||
|
|
a86ce7cb28 | ||
|
|
ccf2a780b6 | ||
|
|
b0c1dbe4b7 | ||
|
|
ec73eef695 | ||
|
|
467d68344e | ||
|
|
8899b3ebb8 | ||
|
|
5478cfaf9f | ||
|
|
4b6a85f30a | ||
|
|
e62ff07726 | ||
|
|
a045107cc7 | ||
|
|
c97edb60a5 | ||
|
|
695793b752 | ||
|
|
c953ffb471 | ||
|
|
3d7fa06129 | ||
|
|
49d4fbcf3d | ||
|
|
fc18a40c35 | ||
|
|
1e81d5e38c | ||
|
|
daf8b53c0d | ||
|
|
8de55a745d | ||
|
|
6bf669815d | ||
|
|
8ba49e163d | ||
|
|
26918d90ab | ||
|
|
929b0806dc | ||
|
|
3e32e61db1 | ||
|
|
038693bffb | ||
|
|
9445aa43e6 | ||
|
|
bb16dbab78 | ||
|
|
658212e7be | ||
|
|
e91554770c | ||
|
|
8f9671ad32 | ||
|
|
7f134e39f4 | ||
|
|
c87e3f419d | ||
|
|
07b2767ac9 | ||
|
|
0ca24a9786 | ||
|
|
c84c1366e7 | ||
|
|
ebf9bb5c18 | ||
|
|
70b67a0805 | ||
|
|
545b97716f | ||
|
|
f7140522f6 | ||
|
|
bd2f7088e9 | ||
|
|
5260c181a1 | ||
|
|
a9538adf2b |
12
.htaccess
12
.htaccess
@@ -44,15 +44,17 @@ RewriteRule .* index.php [L]
|
||||
|
||||
## Begin - Security
|
||||
# Block all direct access for these folders
|
||||
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [L]
|
||||
# Block access to specific file types for these folders
|
||||
RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L]
|
||||
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [F]
|
||||
# Block access to specific file types for these system folders
|
||||
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
|
||||
# Block access to specific file types for these user folders
|
||||
RewriteRule ^(user)/(.*)\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
|
||||
# Block all direct access to .md files:
|
||||
RewriteRule \.md$ error [L]
|
||||
RewriteRule \.md$ error [F]
|
||||
# Block all direct access to files and folders beginning with a dot
|
||||
RewriteRule (^\.|/\.) - [F]
|
||||
# Block access to specific files in the root folder
|
||||
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config)$ error [F]
|
||||
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess)$ error [F]
|
||||
## End - Security
|
||||
|
||||
</IfModule>
|
||||
|
||||
63
CHANGELOG.md
63
CHANGELOG.md
@@ -1,3 +1,66 @@
|
||||
# v1.0.0-rc.5
|
||||
## 11/20/2015
|
||||
|
||||
1. [](#new)
|
||||
* Added **nonce** functionality for all admin forms for improved security
|
||||
* Implemented the ability for Plugins to provide their own CLI commands through `bin/plugin`
|
||||
* Added Croatian translation
|
||||
* Added missing `umask_fix` property to `system.yaml`
|
||||
* Added current theme's config to global config. E.g. `config.theme.dropdown_enabled`
|
||||
* Added `append_url_extension` option to system config & page headers
|
||||
* Users have a new `state` property to allow disabling/banning
|
||||
* Added new `Page.relativePagePath()` helper method
|
||||
* Added new `|pad` Twig filter for strings (uses `str_pad()`)
|
||||
* Added `lighttpd.conf` for Lightly web server
|
||||
1. [](#improved)
|
||||
* Clear previously applied operations when doing a reset on image media
|
||||
* Password no longer required when editing user
|
||||
* Improved support for trailing `/` URLs
|
||||
* Improved `.nginx.conf` configuration file
|
||||
* Improved `.htaccess` security
|
||||
* Updated vendor libs
|
||||
* Updated `composer.phar`
|
||||
* Use streams instead of paths for `clearCache()`
|
||||
* Use PCRE_UTF8 so unicode strings can be regexed in Truncator
|
||||
* Handle case when login plugin is disabled
|
||||
* Improved `quality` functionality in media handling
|
||||
* Added some missing translation strings
|
||||
* Deprecated `bin/grav newuser` in favor of `bin/plugin login new-user`
|
||||
* Moved fallback types to use any valid media type
|
||||
* Renamed `system.pages.fallback_types` to `system.media.allowed_fallback_types`
|
||||
* Removed version number in default `generator` meta tag
|
||||
* Disable time limit in case of slow downloads
|
||||
* Removed default hash in `system.yaml`
|
||||
1. [](#bugfix)
|
||||
* Fix for media using absolute URLs causing broken links
|
||||
* Fix theme auto-loading #432
|
||||
* Don't create empty `<style>` or `<script>` scripts if no data
|
||||
* Code cleanups
|
||||
* Fix undefined variable in Config class
|
||||
* Fix exception message when label is not set
|
||||
* Check in `Plugins::get()` to ensure plugins exists
|
||||
* Fixed GZip compression making output buffering work correctly with all servers and browsers
|
||||
* Fixed date representation in system config
|
||||
|
||||
# v1.0.0-rc.4
|
||||
## 10/29/2015
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed a fatal error if you have a collection with missing or invalid `@page: /route`
|
||||
|
||||
# v1.0.0-rc.3
|
||||
## 10/29/2015
|
||||
|
||||
1. [](#new)
|
||||
* New Page collection options! `@self.parent, @self.siblings, @self.descendants` + more
|
||||
* Whitelist of file types for fallback route functionality (images by default)
|
||||
1. [](#improved)
|
||||
* Assets switched from defines to streams
|
||||
1. [](#bugfix)
|
||||
* README.md typos fixed
|
||||
* Fixed issue with routes that have lang string in them (`/en/english`)
|
||||
* Trim strings before validation so whitespace is not satisfy 'required'
|
||||
|
||||
# v1.0.0-rc.2
|
||||
## 10/27/2015
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ The underlying architecture of Grav is designed to use well-established and _bes
|
||||
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface
|
||||
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation
|
||||
* [YAML](http://yaml.org): for simple configuration
|
||||
* [Parsedown](http://parsedown.org/): for fast Markdown and Mardown Extra support
|
||||
* [Parsedown](http://parsedown.org/): for fast Markdown and Markdown Extra support
|
||||
* [Doctrine Cache](http://docs.doctrine-project.org/en/2.0.x/reference/caching.html): layer for performance
|
||||
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability
|
||||
* [Symfony Event Dispacher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
|
||||
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface
|
||||
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
|
||||
|
||||
@@ -53,7 +53,7 @@ You can download [plugins](http://getgrav.org/downloads/plugins) or [themes](htt
|
||||
$ bin/gpm index
|
||||
```
|
||||
|
||||
This will display all the available plugins and then you can install one ore more with:
|
||||
This will display all the available plugins and then you can install one or more with:
|
||||
|
||||
```
|
||||
$ bin/gpm install <plugin/theme>
|
||||
@@ -76,7 +76,7 @@ $ bin/gpm update
|
||||
|
||||
# Contributing
|
||||
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement.
|
||||
However, we ask that any contribution follow our simple guidelines in order to be properly received.
|
||||
However, we ask that any contributions follow our simple guidelines in order to be properly received.
|
||||
|
||||
All our projects follow the [GitFlow branching model][gitflow-model], from development to release. If you are not familiar with it, there are several guides and tutorials to make you understand what it is about.
|
||||
|
||||
|
||||
Binary file not shown.
116
bin/plugin
Executable file
116
bin/plugin
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
define('GRAV_CLI', true);
|
||||
|
||||
if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) {
|
||||
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
|
||||
}
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')) {
|
||||
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
|
||||
}
|
||||
|
||||
use Grav\Common\Composer;
|
||||
|
||||
if (!file_exists(__DIR__ . '/../vendor')) {
|
||||
// Before we can even start, we need to run composer first
|
||||
$composer = Composer::getComposerExecutor();
|
||||
echo "Preparing to install vendor dependencies...\n\n";
|
||||
echo system($composer . ' --working-dir="' . __DIR__ . '/../" --no-interaction --no-dev --prefer-dist -o install');
|
||||
echo "\n\n";
|
||||
}
|
||||
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
|
||||
$autoload = require_once(__DIR__ . '/../vendor/autoload.php');
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT_DIR . 'index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav['config']->init();
|
||||
$grav['streams'];
|
||||
$grav['plugins']->init();
|
||||
$grav['themes']->init();
|
||||
|
||||
$app = new Application('Grav Plugins Commands', GRAV_VERSION);
|
||||
$pattern = '/([A-Z]\w+Command\.php)$/usm';
|
||||
|
||||
// get arguments and strip the application name
|
||||
if (null === $argv) {
|
||||
$argv = $_SERVER['argv'];
|
||||
}
|
||||
|
||||
$bin = array_shift($argv);
|
||||
$name = array_shift($argv);
|
||||
$argv = array_merge([$bin], $argv);
|
||||
|
||||
$input = new ArgvInput($argv);
|
||||
|
||||
$plugin = $grav['plugins']->get($name);
|
||||
|
||||
$output = new ConsoleOutput();
|
||||
$output->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, array('bold')));
|
||||
$output->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, array('bold')));
|
||||
|
||||
if (!$name) {
|
||||
$output->writeln('');
|
||||
$output->writeln("<red>Usage:</red>");
|
||||
$output->writeln(" {$bin} [slug] [command] [arguments]");
|
||||
$output->writeln('');
|
||||
$output->writeln("<red>Example:</red>");
|
||||
$output->writeln(" {$bin} error log -l 1 --trace");
|
||||
$list = Folder::all('plugins://', ['compare' => 'Pathname', 'pattern' => '\/cli\/' . $pattern]);
|
||||
|
||||
if (count($list)) {
|
||||
$available = [];
|
||||
$output->writeln('');
|
||||
$output->writeln('<red>Plugins with CLI available:</red>');
|
||||
foreach ($list as $index => $entry) {
|
||||
$split = explode('/', $entry);
|
||||
$entry = array_shift($split);
|
||||
$index = str_pad($index++ + 1, 2, '0', STR_PAD_LEFT);
|
||||
|
||||
if (in_array($entry, $available)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$available[] = $entry;
|
||||
$output->writeln(' ' . $index . ". <red>" . str_pad($entry, 15) . "</red> <white>${bin} ${entry} list</white>");
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($plugin === null) {
|
||||
$output->writeln("<red>Grav Plugin <white>'{$name}'</white> is not installed</red>");
|
||||
exit;
|
||||
}
|
||||
|
||||
$path = 'plugins://' . $name . '/cli';
|
||||
|
||||
try {
|
||||
$commands = Folder::all($path, ['compare' => 'Filename', 'pattern' => $pattern]);
|
||||
} catch (\RuntimeException $e) {
|
||||
$output->writeln("<red>No Console Commands for <white>'{$name}'</white> where found in <white>'{$path}'</white></red>");
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($commands as $command) {
|
||||
require_once "plugins://{$name}/cli/{$command}";
|
||||
$command = 'Grav\Plugin\Console\\' . preg_replace('/.php$/', '', $command);
|
||||
$app->add(new $command());
|
||||
}
|
||||
|
||||
$app->run($input);
|
||||
85
composer.lock
generated
85
composer.lock
generated
@@ -1,23 +1,24 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "e1db721096772d41f16003b39b47c85a",
|
||||
"content-hash": "294dd2282a332d96b19d163ad08e7ba7",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/cache",
|
||||
"version": "v1.4.2",
|
||||
"version": "v1.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/cache.git",
|
||||
"reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca"
|
||||
"reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca",
|
||||
"reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca",
|
||||
"url": "https://api.github.com/repos/doctrine/cache/zipball/2b9cec5a5e722010cbebc91713d4c11eaa064d5e",
|
||||
"reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -38,8 +39,8 @@
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/"
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -74,7 +75,7 @@
|
||||
"cache",
|
||||
"caching"
|
||||
],
|
||||
"time": "2015-08-31 12:36:41"
|
||||
"time": "2015-11-02 18:35:48"
|
||||
},
|
||||
{
|
||||
"name": "donatj/phpuseragentparser",
|
||||
@@ -216,12 +217,12 @@
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/filp/whoops.git",
|
||||
"reference": "9a393ceb80f7497b6513feb574638e87048fed55"
|
||||
"reference": "50a288b51058fa94cf5b37cfa4277535983cc9d5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/9a393ceb80f7497b6513feb574638e87048fed55",
|
||||
"reference": "9a393ceb80f7497b6513feb574638e87048fed55",
|
||||
"url": "https://api.github.com/repos/filp/whoops/zipball/50a288b51058fa94cf5b37cfa4277535983cc9d5",
|
||||
"reference": "50a288b51058fa94cf5b37cfa4277535983cc9d5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -266,7 +267,7 @@
|
||||
"whoops",
|
||||
"zf2"
|
||||
],
|
||||
"time": "2015-09-27 09:47:06"
|
||||
"time": "2015-11-14 20:08:27"
|
||||
},
|
||||
{
|
||||
"name": "gregwar/cache",
|
||||
@@ -714,16 +715,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v2.7.5",
|
||||
"version": "v2.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "06cb17c013a82f94a3d840682b49425cd00a2161"
|
||||
"reference": "5efd632294c8320ea52492db22292ff853a43766"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/06cb17c013a82f94a3d840682b49425cd00a2161",
|
||||
"reference": "06cb17c013a82f94a3d840682b49425cd00a2161",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/5efd632294c8320ea52492db22292ff853a43766",
|
||||
"reference": "5efd632294c8320ea52492db22292ff853a43766",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -732,7 +733,6 @@
|
||||
"require-dev": {
|
||||
"psr/log": "~1.0",
|
||||
"symfony/event-dispatcher": "~2.1",
|
||||
"symfony/phpunit-bridge": "~2.7",
|
||||
"symfony/process": "~2.1"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -767,20 +767,20 @@
|
||||
],
|
||||
"description": "Symfony Console Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-09-25 08:32:23"
|
||||
"time": "2015-10-20 14:38:46"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v2.7.5",
|
||||
"version": "v2.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "ae4dcc2a8d3de98bd794167a3ccda1311597c5d9"
|
||||
"reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ae4dcc2a8d3de98bd794167a3ccda1311597c5d9",
|
||||
"reference": "ae4dcc2a8d3de98bd794167a3ccda1311597c5d9",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87a5db5ea887763fa3a31a5471b512ff1596d9b8",
|
||||
"reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -791,7 +791,6 @@
|
||||
"symfony/config": "~2.0,>=2.0.5",
|
||||
"symfony/dependency-injection": "~2.6",
|
||||
"symfony/expression-language": "~2.6",
|
||||
"symfony/phpunit-bridge": "~2.7",
|
||||
"symfony/stopwatch": "~2.3"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -825,28 +824,25 @@
|
||||
],
|
||||
"description": "Symfony EventDispatcher Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-09-22 13:49:29"
|
||||
"time": "2015-10-11 09:39:48"
|
||||
},
|
||||
{
|
||||
"name": "symfony/var-dumper",
|
||||
"version": "v2.7.5",
|
||||
"version": "v2.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/var-dumper.git",
|
||||
"reference": "ba8c9a0edf18f70a7efcb8d3eb35323a10263338"
|
||||
"reference": "eb033050050916b6bfa51be71009ef67b16046c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/ba8c9a0edf18f70a7efcb8d3eb35323a10263338",
|
||||
"reference": "ba8c9a0edf18f70a7efcb8d3eb35323a10263338",
|
||||
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/eb033050050916b6bfa51be71009ef67b16046c9",
|
||||
"reference": "eb033050050916b6bfa51be71009ef67b16046c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-symfony_debug": ""
|
||||
},
|
||||
@@ -884,28 +880,25 @@
|
||||
"debug",
|
||||
"dump"
|
||||
],
|
||||
"time": "2015-09-22 14:41:01"
|
||||
"time": "2015-10-25 17:17:38"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.7.5",
|
||||
"version": "v2.7.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770"
|
||||
"reference": "eca9019c88fbe250164affd107bc8057771f3f4d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/31cb2ad0155c95b88ee55fe12bc7ff92232c1770",
|
||||
"reference": "31cb2ad0155c95b88ee55fe12bc7ff92232c1770",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/eca9019c88fbe250164affd107bc8057771f3f4d",
|
||||
"reference": "eca9019c88fbe250164affd107bc8057771f3f4d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.9"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@@ -933,20 +926,20 @@
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "https://symfony.com",
|
||||
"time": "2015-09-14 14:14:09"
|
||||
"time": "2015-10-11 09:39:48"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.22.3",
|
||||
"version": "v1.23.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "ebfc36b7e77b0c1175afe30459cf943010245540"
|
||||
"reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/ebfc36b7e77b0c1175afe30459cf943010245540",
|
||||
"reference": "ebfc36b7e77b0c1175afe30459cf943010245540",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6",
|
||||
"reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -959,7 +952,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.22-dev"
|
||||
"dev-master": "1.23-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -994,7 +987,7 @@
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2015-10-13 07:07:02"
|
||||
"time": "2015-11-05 12:49:06"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
||||
12
htaccess.txt
12
htaccess.txt
@@ -44,15 +44,17 @@ RewriteRule .* index.php [L]
|
||||
|
||||
## Begin - Security
|
||||
# Block all direct access for these folders
|
||||
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [L]
|
||||
# Block access to specific file types for these folders
|
||||
RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L]
|
||||
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [F]
|
||||
# Block access to specific file types for these system folders
|
||||
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
|
||||
# Block access to specific file types for these user folders
|
||||
RewriteRule ^(user)/(.*)\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
|
||||
# Block all direct access to .md files:
|
||||
RewriteRule \.md$ error [L]
|
||||
RewriteRule \.md$ error [F]
|
||||
# Block all direct access to files and folders beginning with a dot
|
||||
RewriteRule (^\.|/\.) - [F]
|
||||
# Block access to specific files in the root folder
|
||||
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config)$ error [F]
|
||||
RewriteRule ^(LICENSE|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess)$ error [F]
|
||||
## End - Security
|
||||
|
||||
</IfModule>
|
||||
|
||||
48
lighttpd.conf
Normal file
48
lighttpd.conf
Normal file
@@ -0,0 +1,48 @@
|
||||
############# DO NOT FORGET TO CHANGE "grav_path" BY YOUR ACTUAL GRAV INSTALLATION FOLDER #############
|
||||
############# IF GRAV IS AT THE ROOT OF YOUR WEBSITE, ie http://yoursite.tld POINTS TO #############
|
||||
############# GRAV DIRECTLY, THEN JUST REMOVE ANY "/grav_path/" MENTION BELOW. OTHERWISE #############
|
||||
############# WE ASSUME YOU RUN AN INSTALLATION SUCH AS http://yoursite.tld/grav_path/ #############
|
||||
#######################################################################################################
|
||||
### GRAV RULES FOR LIGHTTPD ###
|
||||
### By Mr3ase ###
|
||||
### Last Rev. 2015/11/20 ###
|
||||
|
||||
#PREVENTING EXPLOITS
|
||||
$HTTP["querystring"] =~ "base64_encode[^(]*\([^)]*\)" {
|
||||
url.redirect = (".*" => "/grav_path/index.php" )
|
||||
}
|
||||
$HTTP["querystring"] =~ "(<|%3C)([^s]*s)+cript.*(>|%3E)" {
|
||||
url.redirect = (".*" => "/grav_path/index.php" )
|
||||
}
|
||||
$HTTP["querystring"] =~ "GLOBALS(=|\[|\%[0-9A-Z])" {
|
||||
url.redirect = (".*" => "/grav_path/index.php" )
|
||||
}
|
||||
$HTTP["querystring"] =~ "_REQUEST(=|\[|\%[0-9A-Z])" {
|
||||
url.redirect = (".*" => "/grav_path/index.php" )
|
||||
}
|
||||
|
||||
#REROUTING TO THE INDEX PAGE
|
||||
url.rewrite-if-not-file = (
|
||||
"^/grav_path/(.*)$" => "/grav_path/index.php"
|
||||
)
|
||||
|
||||
#IMPROVING SECURITY
|
||||
$HTTP["url"] =~ "^/grav_path/(LICENSE|composer.json|composer.lock|nginx.conf|web.config)$" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
$HTTP["url"] =~ "^/grav_path/(.git|cache|bin|logs|backup)/(.*)" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
$HTTP["url"] =~ "^/grav_path/(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
$HTTP["url"] =~ "^/grav_path/(\.(.*))|(\.(.*)/)" {
|
||||
url.access-deny = ("")
|
||||
}
|
||||
url.access-deny = (".md","~",".inc")
|
||||
|
||||
#PREVENT BROWSING AND SET INDEXES
|
||||
$HTTP["url"] =~ "^/grav_path($|/)" {
|
||||
dir-listing.activate = "disable"
|
||||
index-file.names = ( "index.php", "index.html" , "index.htm" )
|
||||
}
|
||||
121
nginx.conf
121
nginx.conf
@@ -1,87 +1,44 @@
|
||||
worker_processes 1;
|
||||
server {
|
||||
#listen 80;
|
||||
index index.html index.php;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include mime.types;
|
||||
default_type application/octet-stream;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root html;
|
||||
}
|
||||
|
||||
location / {
|
||||
root html;
|
||||
index index.php;
|
||||
if (!-e $request_filename){ rewrite ^(.*)$ /index.php last; }
|
||||
}
|
||||
|
||||
# if you want grav in a sub-directory of your main site
|
||||
# (for example, example.com/mygrav) then you need this rewrite:
|
||||
location /mygrav {
|
||||
index index.php;
|
||||
if (!-e $request_filename){ rewrite ^(.*)$ /mygrav/$2 last; }
|
||||
try_files $uri $uri/ /index.php?$args;
|
||||
}
|
||||
|
||||
# if using grav in a sub-directory of your site,
|
||||
# prepend the actual path to each location
|
||||
# for example: /mygrav/images
|
||||
# and: /mygrav/user
|
||||
# and: /mygrav/cache
|
||||
# and so on
|
||||
|
||||
location /images/ {
|
||||
# Serve images as static
|
||||
}
|
||||
|
||||
location /user {
|
||||
rewrite ^/user/accounts/(.*)$ /error redirect;
|
||||
rewrite ^/user/config/(.*)$ /error redirect;
|
||||
rewrite ^/user/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect;
|
||||
}
|
||||
|
||||
location /cache {
|
||||
rewrite ^/cache/(.*) /error redirect;
|
||||
}
|
||||
|
||||
location /bin {
|
||||
rewrite ^/bin/(.*)$ /error redirect;
|
||||
}
|
||||
|
||||
location /backup {
|
||||
rewrite ^/backup/(.*) /error redirect;
|
||||
}
|
||||
|
||||
location /system {
|
||||
rewrite ^/system/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect;
|
||||
}
|
||||
|
||||
location /vendor {
|
||||
rewrite ^/vendor/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect;
|
||||
}
|
||||
|
||||
# Remember to change 127.0.0.1:9000 to the Ip/port
|
||||
# you configured php-cgi.exe to run from
|
||||
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass 127.0.0.1:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
## Begin - Server Info
|
||||
root /home/user/www/html;
|
||||
server_name localhost;
|
||||
## End - Server Info
|
||||
|
||||
## Begin - Index
|
||||
# for subfolders, simply adjust:
|
||||
# `location /subfolder {`
|
||||
# and the rewrite to use `/subfolder/index.php`
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
if (!-e $request_filename){ rewrite ^(.*)$ /index.php last; }
|
||||
}
|
||||
## End - Index
|
||||
|
||||
## Begin - PHP
|
||||
location ~ \.php$ {
|
||||
# Choose either a socket or TCP/IP address
|
||||
fastcgi_pass unix:/var/run/php5-fpm.sock;
|
||||
# fastcgi_pass 127.0.0.1:9000;
|
||||
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
|
||||
}
|
||||
## End - PHP
|
||||
|
||||
## Begin - Security
|
||||
# deny all direct access for these folders
|
||||
location ~* /(.git|cache|bin|logs|backups)/.*$ { return 403; }
|
||||
# deny running scripts inside core system folders
|
||||
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
|
||||
# deny running scripts inside user folder
|
||||
location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
|
||||
# deny access to specific files in the root folder
|
||||
location ~ /(LICENSE|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess) { return 403; }
|
||||
## End - Security
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ form:
|
||||
options:
|
||||
"F jS \\a\\t g:ia": Date1
|
||||
"l jS \\of F g:i A": Date2
|
||||
"D, m M Y G:i:s": Date3
|
||||
"D, d M Y G:i:s": Date3
|
||||
"d-m-y G:i": Date4
|
||||
"jS M Y": Date5
|
||||
|
||||
@@ -86,7 +86,7 @@ form:
|
||||
options:
|
||||
"F jS \\a\\t g:ia": Date1
|
||||
"l jS \\of F g:i A": Date2
|
||||
"D, m M Y G:i:s": Date3
|
||||
"D, d M Y G:i:s": Date3
|
||||
"d-m-y G:i": Date4
|
||||
"jS M Y": Date5
|
||||
|
||||
@@ -142,6 +142,12 @@ form:
|
||||
twig: Twig Events
|
||||
use: keys
|
||||
|
||||
pages.append_url_extension:
|
||||
type: text
|
||||
placeholder: "e.g. .html"
|
||||
label: PLUGIN_ADMIN.APPEND_URL_EXT
|
||||
help: PLUGIN_ADMIN.APPEND_URL_EXT_HELP
|
||||
|
||||
pages.redirect_default_route:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.REDIRECT_DEFAULT_ROUTE
|
||||
@@ -225,6 +231,7 @@ form:
|
||||
languages.supported:
|
||||
type: selectize
|
||||
size: large
|
||||
placeholder: "e.g. en, fr"
|
||||
label: PLUGIN_ADMIN.SUPPORTED
|
||||
help: PLUGIN_ADMIN.SUPPORTED_HELP
|
||||
classes: fancy
|
||||
@@ -711,6 +718,26 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
|
||||
|
||||
media.allowed_fallback_types:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.FALLBACK_TYPES
|
||||
help: PLUGIN_ADMIN.FALLBACK_TYPES_HELP
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
media.unsupported_inline_types:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.INLINE_TYPES
|
||||
help: PLUGIN_ADMIN.INLINE_TYPES_HELP
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
session:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.SESSION
|
||||
@@ -774,6 +801,7 @@ form:
|
||||
|
||||
param_sep:
|
||||
type: select
|
||||
size: medium
|
||||
label: PLUGIN_ADMIN.PARAMETER_SEPARATOR
|
||||
classes: fancy
|
||||
help: PLUGIN_ADMIN.PARAMETER_SEPARATOR_HELP
|
||||
|
||||
@@ -29,7 +29,6 @@ form:
|
||||
|
||||
content:
|
||||
type: markdown
|
||||
label: PLUGIN_ADMIN.CONTENT
|
||||
validate:
|
||||
type: textarea
|
||||
|
||||
@@ -88,7 +87,6 @@ form:
|
||||
placeholder_key: PLUGIN_ADMIN.METADATA_KEY
|
||||
placeholder_value: PLUGIN_ADMIN.METADATA_VALUE
|
||||
|
||||
|
||||
taxonomies:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.TAXONOMIES
|
||||
@@ -264,6 +262,12 @@ form:
|
||||
default: default
|
||||
'@data-options': '\Grav\Common\Page\Pages::types'
|
||||
|
||||
header.append_url_extension:
|
||||
type: text
|
||||
label: PLUGIN_ADMIN.APPEND_URL_EXT
|
||||
toggleable: true
|
||||
help: PLUGIN_ADMIN.APPEND_URL_EXT_HELP
|
||||
|
||||
header.order_by:
|
||||
type: hidden
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ form:
|
||||
|
||||
content:
|
||||
type: markdown
|
||||
label: PLUGIN_ADMIN.CONTENT
|
||||
|
||||
uploads:
|
||||
type: pagemedia
|
||||
|
||||
@@ -25,7 +25,6 @@ form:
|
||||
|
||||
content:
|
||||
type: markdown
|
||||
label: PLUGIN_ADMIN.CONTENT
|
||||
|
||||
uploads:
|
||||
type: pagemedia
|
||||
|
||||
@@ -29,7 +29,7 @@ form:
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.PASSWORD
|
||||
validate:
|
||||
required: true
|
||||
required: false
|
||||
message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE
|
||||
pattern: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}'
|
||||
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
schemes:
|
||||
asset:
|
||||
type: ReadOnlyStream
|
||||
paths:
|
||||
- assets
|
||||
|
||||
image:
|
||||
type: ReadOnlyStream
|
||||
paths:
|
||||
|
||||
@@ -1,111 +1,113 @@
|
||||
absolute_urls: false # Absolute or relative URLs for `base_url`
|
||||
timezone: '' # Valid values: http://php.net/manual/en/timezones.php
|
||||
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
|
||||
absolute_urls: false # Absolute or relative URLs for `base_url`
|
||||
timezone: '' # Valid values: http://php.net/manual/en/timezones.php
|
||||
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
|
||||
|
||||
languages:
|
||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
||||
include_default_lang: true # Include the default lang prefix in all URLs
|
||||
translations: true # Enable translations by default
|
||||
translations_fallback: true # Fallback through supported translations if active lang doesn't exist
|
||||
session_store_active: false # Store active language in session
|
||||
http_accept_language: false # Attempt to set the language based on http_accept_language header in the browser
|
||||
override_locale: false # Override the default or system locale with language specific one
|
||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
||||
include_default_lang: true # Include the default lang prefix in all URLs
|
||||
translations: true # Enable translations by default
|
||||
translations_fallback: true # Fallback through supported translations if active lang doesn't exist
|
||||
session_store_active: false # Store active language in session
|
||||
http_accept_language: false # Attempt to set the language based on http_accept_language header in the browser
|
||||
override_locale: false # Override the default or system locale with language specific one
|
||||
|
||||
home:
|
||||
alias: '/home' # Default path for home, ie /
|
||||
alias: '/home' # Default path for home, ie /
|
||||
|
||||
pages:
|
||||
theme: antimatter # Default theme (defaults to "antimatter" theme)
|
||||
theme: antimatter # Default theme (defaults to "antimatter" theme)
|
||||
order:
|
||||
by: default # Order pages by "default", "alpha" or "date"
|
||||
dir: asc # Default ordering direction, "asc" or "desc"
|
||||
by: default # Order pages by "default", "alpha" or "date"
|
||||
dir: asc # Default ordering direction, "asc" or "desc"
|
||||
list:
|
||||
count: 20 # Default item count per page
|
||||
count: 20 # Default item count per page
|
||||
dateformat:
|
||||
default: # The default date format Grav expects in the `date: ` field
|
||||
short: 'jS M Y' # Short date format
|
||||
long: 'F jS \a\t g:ia' # Long date format
|
||||
publish_dates: true # automatically publish/unpublish based on dates
|
||||
default: # The default date format Grav expects in the `date: ` field
|
||||
short: 'jS M Y' # Short date format
|
||||
long: 'F jS \a\t g:ia' # Long date format
|
||||
publish_dates: true # automatically publish/unpublish based on dates
|
||||
process:
|
||||
markdown: true # Process Markdown
|
||||
twig: false # Process Twig
|
||||
markdown: true # Process Markdown
|
||||
twig: false # Process Twig
|
||||
events:
|
||||
page: true # Enable page level events
|
||||
twig: true # Enable twig level events
|
||||
page: true # Enable page level events
|
||||
twig: true # Enable twig level events
|
||||
markdown:
|
||||
extra: false # Enable support for Markdown Extra support (GFM by default)
|
||||
auto_line_breaks: false # Enable automatic line breaks
|
||||
auto_url_links: false # Enable automatic HTML links
|
||||
escape_markup: false # Escape markup tags into entities
|
||||
special_chars: # List of special characters to automatically convert to entities
|
||||
extra: false # Enable support for Markdown Extra support (GFM by default)
|
||||
auto_line_breaks: false # Enable automatic line breaks
|
||||
auto_url_links: false # Enable automatic HTML links
|
||||
escape_markup: false # Escape markup tags into entities
|
||||
special_chars: # List of special characters to automatically convert to entities
|
||||
'>': 'gt'
|
||||
'<': 'lt'
|
||||
types: [txt,xml,html,json,rss,atom] # list of valid page types
|
||||
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
|
||||
last_modified: false # Set the last modified date header based on file modifcation timestamp
|
||||
etag: false # Set the etag header tag
|
||||
vary_accept_encoding: false # Add `Vary: Accept-Encoding` header
|
||||
redirect_default_route: false # Automatically redirect to a page's default route
|
||||
redirect_default_code: 301 # Default code to use for redirects
|
||||
redirect_trailing_slash: true # Handle automatically or 301 redirect a trailing / URL
|
||||
ignore_files: [.DS_Store] # Files to ignore in Pages
|
||||
ignore_folders: [.git, .idea] # Folders to ignore in Pages
|
||||
ignore_hidden: true # Ignore all Hidden files and folders
|
||||
url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections
|
||||
types: [txt,xml,html,htm,json,rss,atom] # list of valid page types
|
||||
append_url_extension: '' # Append page's extension in Page urls (e.g. '.html' results in /path/page.html)
|
||||
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
|
||||
last_modified: false # Set the last modified date header based on file modifcation timestamp
|
||||
etag: false # Set the etag header tag
|
||||
vary_accept_encoding: false # Add `Vary: Accept-Encoding` header
|
||||
redirect_default_route: false # Automatically redirect to a page's default route
|
||||
redirect_default_code: 301 # Default code to use for redirects
|
||||
redirect_trailing_slash: true # Handle automatically or 301 redirect a trailing / URL
|
||||
ignore_files: [.DS_Store] # Files to ignore in Pages
|
||||
ignore_folders: [.git, .idea] # Folders to ignore in Pages
|
||||
ignore_hidden: true # Ignore all Hidden files and folders
|
||||
url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections
|
||||
|
||||
cache:
|
||||
enabled: true # Set to true to enable caching
|
||||
enabled: true # Set to true to enable caching
|
||||
check:
|
||||
method: file # Method to check for updates in pages: file|folder|none
|
||||
driver: auto # One of: auto|file|apc|xcache|memcache|wincache
|
||||
prefix: 'g' # Cache prefix string (prevents cache conflicts)
|
||||
lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite)
|
||||
gzip: false # GZip compress the page output
|
||||
method: file # Method to check for updates in pages: file|folder|none
|
||||
driver: auto # One of: auto|file|apc|xcache|memcache|wincache
|
||||
prefix: 'g' # Cache prefix string (prevents cache conflicts)
|
||||
lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite)
|
||||
gzip: false # GZip compress the page output
|
||||
|
||||
twig:
|
||||
cache: true # Set to true to enable twig caching
|
||||
debug: false # Enable Twig debug
|
||||
auto_reload: true # Refresh cache on changes
|
||||
autoescape: false # Autoescape Twig vars
|
||||
undefined_functions: true # Allow undefined functions
|
||||
undefined_filters: true # Allow undefined filters
|
||||
cache: true # Set to true to enable twig caching
|
||||
debug: false # Enable Twig debug
|
||||
auto_reload: true # Refresh cache on changes
|
||||
autoescape: false # Autoescape Twig vars
|
||||
undefined_functions: true # Allow undefined functions
|
||||
undefined_filters: true # Allow undefined filters
|
||||
umask_fix: false # By default Twig creates cached files as 755, fix switches this to 775
|
||||
|
||||
assets: # Configuration for Assets Manager (JS, CSS)
|
||||
css_pipeline: false # The CSS pipeline is the unification of multiple CSS resources into one file
|
||||
css_minify: true # Minify the CSS during pipelining
|
||||
css_minify_windows: false # Minify Override for Windows platforms. False by default due to ThreadStackSize
|
||||
css_rewrite: true # Rewrite any CSS relative URLs during pipelining
|
||||
js_pipeline: false # The JS pipeline is the unification of multiple JS resources into one file
|
||||
js_minify: true # Minify the JS during pipelining
|
||||
enable_asset_timestamp: false # Enable asset timestamps
|
||||
assets: # Configuration for Assets Manager (JS, CSS)
|
||||
css_pipeline: false # The CSS pipeline is the unification of multiple CSS resources into one file
|
||||
css_minify: true # Minify the CSS during pipelining
|
||||
css_minify_windows: false # Minify Override for Windows platforms. False by default due to ThreadStackSize
|
||||
css_rewrite: true # Rewrite any CSS relative URLs during pipelining
|
||||
js_pipeline: false # The JS pipeline is the unification of multiple JS resources into one file
|
||||
js_minify: true # Minify the JS during pipelining
|
||||
enable_asset_timestamp: false # Enable asset timestamps
|
||||
collections:
|
||||
jquery: system://assets/jquery/jquery-2.1.4.min.js
|
||||
|
||||
errors:
|
||||
display: false # Display full backtrace-style error page
|
||||
log: true # Log errors to /logs folder
|
||||
display: false # Display full backtrace-style error page
|
||||
log: true # Log errors to /logs folder
|
||||
|
||||
debugger:
|
||||
enabled: false # Enable Grav debugger and following settings
|
||||
enabled: false # Enable Grav debugger and following settings
|
||||
shutdown:
|
||||
close_connection: true # Close the connection before calling onShutdown(). false for debugging
|
||||
close_connection: true # Close the connection before calling onShutdown(). false for debugging
|
||||
|
||||
images:
|
||||
default_image_quality: 85 # Default image quality to use when resampling images (85%)
|
||||
cache_all: false # Cache all image by default
|
||||
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
|
||||
default_image_quality: 85 # Default image quality to use when resampling images (85%)
|
||||
cache_all: false # Cache all image by default
|
||||
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
|
||||
|
||||
media:
|
||||
enable_media_timestamp: false # Enable media timetsamps
|
||||
upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited)
|
||||
unsupported_inline_types: [] # Array of unsupported media file types to try to display inline
|
||||
enable_media_timestamp: false # Enable media timetsamps
|
||||
upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited)
|
||||
unsupported_inline_types: [] # Array of supported media types to try to display inline
|
||||
allowed_fallback_types: [] # Array of allowed media types of files found if accessed via Page route
|
||||
|
||||
session:
|
||||
enabled: true # Enable Session support
|
||||
timeout: 1800 # Timeout in seconds
|
||||
name: grav-site # Name prefix of the session cookie
|
||||
enabled: true # Enable Session support
|
||||
timeout: 1800 # Timeout in seconds
|
||||
name: grav-site # Name prefix of the session cookie
|
||||
|
||||
|
||||
security:
|
||||
default_hash: $2y$10$kwsyMVwM8/7j0K/6LHT.g.Fs49xOCTp2b8hh/S5.dPJuJcJB6T.UK
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.0.0-rc.2');
|
||||
define('GRAV_VERSION', '1.0.0-rc.5');
|
||||
define('DS', '/');
|
||||
|
||||
// Directories and Paths
|
||||
@@ -13,14 +13,14 @@ define('ROOT_DIR', GRAV_ROOT . '/');
|
||||
define('USER_PATH', 'user/');
|
||||
define('USER_DIR', ROOT_DIR . USER_PATH);
|
||||
define('SYSTEM_DIR', ROOT_DIR .'system/');
|
||||
define('ASSETS_DIR', ROOT_DIR . 'assets/');
|
||||
define('CACHE_DIR', ROOT_DIR . 'cache/');
|
||||
define('IMAGES_DIR', ROOT_DIR . 'images/');
|
||||
define('LOG_DIR', ROOT_DIR .'logs/');
|
||||
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
|
||||
define('PAGES_DIR', USER_DIR .'pages/');
|
||||
|
||||
// DEPRECATED: Do not use!
|
||||
define('ASSETS_DIR', ROOT_DIR . 'assets/');
|
||||
define('IMAGES_DIR', ROOT_DIR . 'images/');
|
||||
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
|
||||
define('PAGES_DIR', USER_DIR .'pages/');
|
||||
define('DATA_DIR', USER_DIR .'data/');
|
||||
define('LIB_DIR', SYSTEM_DIR .'src/');
|
||||
define('PLUGINS_DIR', USER_DIR .'plugins/');
|
||||
|
||||
@@ -92,3 +92,6 @@ NICETIME:
|
||||
MO_PLURAL: mos
|
||||
YR_PLURAL: yrs
|
||||
DEC_PLURAL: decs
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>Validation failed:</b>
|
||||
INVALID_INPUT: Invalid input in
|
||||
|
||||
46
system/languages/hr.yaml
Normal file
46
system/languages/hr.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'Osoba'
|
||||
'man': 'Čovjek'
|
||||
'child': 'Dijete'
|
||||
'sex': 'Spol'
|
||||
'move': 'Pomakni'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Datum nije upisan
|
||||
BAD_DATE: Pogrešan datum
|
||||
AGO: prije
|
||||
FROM_NOW: od sad
|
||||
SECOND: sekundi
|
||||
MINUTE: minuta
|
||||
HOUR: godina
|
||||
DAY: dan
|
||||
WEEK: tjedan
|
||||
MONTH: mjesec
|
||||
YEAR: godina
|
||||
DECADE: desetljeće
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: sat
|
||||
DAY: dan
|
||||
WK: t
|
||||
MO: m
|
||||
YR: g
|
||||
DEC: des
|
||||
SECOND_PLURAL: sekundi
|
||||
MINUTE_PLURAL: minuta
|
||||
HOUR_PLURAL: sati
|
||||
DAY_PLURAL: dana
|
||||
WEEK_PLURAL: tjedana
|
||||
MONTH_PLURAL: mjeseci
|
||||
YEAR_PLURAL: godina
|
||||
DECADE_PLURAL: desetljeća
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: sat
|
||||
DAY_PLURAL: dan
|
||||
WK_PLURAL: t
|
||||
MO_PLURAL: m
|
||||
YR_PLURAL: g
|
||||
DEC_PLURAL: des
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>Validacija nije uspjela:</b>
|
||||
INVALID_INPUT: Unos nije valjan
|
||||
37
system/languages/tr.yaml
Normal file
37
system/languages/tr.yaml
Normal file
@@ -0,0 +1,37 @@
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Tarih yok
|
||||
BAD_DATE: Yanlış tarih
|
||||
AGO: önce
|
||||
FROM_NOW: (şimdiden)
|
||||
SECOND: saniye
|
||||
MINUTE: dakika
|
||||
HOUR: saat
|
||||
DAY: gün
|
||||
WEEK: hafta
|
||||
MONTH: ay
|
||||
YEAR: yıl
|
||||
DECADE: onyıl
|
||||
SEC: sn
|
||||
MIN: dk
|
||||
HR: sa
|
||||
DAY: gün
|
||||
WK: hft
|
||||
MO: ay
|
||||
YR: yl
|
||||
DEC: onyl
|
||||
SECOND_PLURAL: saniye
|
||||
MINUTE_PLURAL: dakika
|
||||
HOUR_PLURAL: saat
|
||||
DAY_PLURAL: gün
|
||||
WEEK_PLURAL: hafta
|
||||
MONTH_PLURAL: ay
|
||||
YEAR_PLURAL: yıl
|
||||
DECADE_PLURAL: onyıl
|
||||
SEC_PLURAL: sn
|
||||
MIN_PLURAL: dk
|
||||
HR_PLURAL: sa
|
||||
DAY_PLURAL: gün
|
||||
WK_PLURAL: hft
|
||||
MO_PLURAL: ay
|
||||
YR_PLURAL: yl
|
||||
DEC_PLURAL: onyl
|
||||
@@ -74,6 +74,8 @@ class Assets
|
||||
protected $config;
|
||||
protected $base_url;
|
||||
protected $timestamp = '';
|
||||
protected $assets_dir;
|
||||
protected $assets_url;
|
||||
|
||||
// Default values for pipeline settings
|
||||
protected $css_minify = true;
|
||||
@@ -117,7 +119,7 @@ class Assets
|
||||
}
|
||||
|
||||
// Pipeline requires public dir
|
||||
if (($this->js_pipeline || $this->css_pipeline) && !is_dir(ASSETS_DIR)) {
|
||||
if (($this->js_pipeline || $this->css_pipeline) && !is_dir($this->assets_dir)) {
|
||||
throw new \Exception('Assets: Public dir not found');
|
||||
}
|
||||
|
||||
@@ -175,6 +177,11 @@ class Assets
|
||||
$base_url = self::getGrav()['base_url'];
|
||||
$asset_config = (array)$config->get('system.assets');
|
||||
|
||||
/** @var Locator $locator */
|
||||
$locator = self::$grav['locator'];
|
||||
$this->assets_dir = self::getGrav()['locator']->findResource('asset://') . DS;
|
||||
$this->assets_url = self::getGrav()['locator']->findResource('asset://', false);
|
||||
|
||||
$this->config($asset_config);
|
||||
$this->base_url = $base_url . '/';
|
||||
|
||||
@@ -406,7 +413,7 @@ class Assets
|
||||
}
|
||||
|
||||
$key = md5($asset);
|
||||
if (is_string($asset) && !array_key_exists($key, $this->inline_css)) {
|
||||
if ($asset && is_string($asset) && !array_key_exists($key, $this->inline_css)) {
|
||||
$this->inline_css[$key] = $data;
|
||||
}
|
||||
|
||||
@@ -453,7 +460,7 @@ class Assets
|
||||
}
|
||||
|
||||
$key = md5($asset);
|
||||
if (is_string($asset) && !array_key_exists($key, $this->inline_js)) {
|
||||
if ($asset && is_string($asset) && !array_key_exists($key, $this->inline_js)) {
|
||||
$this->inline_js[$key] = $data;
|
||||
}
|
||||
|
||||
@@ -621,8 +628,8 @@ class Assets
|
||||
|
||||
$file = md5(json_encode($this->css) . $this->css_minify . $this->css_rewrite . $group) . '.css';
|
||||
|
||||
$relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}";
|
||||
$absolute_path = ASSETS_DIR . $file;
|
||||
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
|
||||
$absolute_path = $this->assets_dir . $file;
|
||||
|
||||
// If pipeline exist return it
|
||||
if (file_exists($absolute_path)) {
|
||||
@@ -689,8 +696,8 @@ class Assets
|
||||
|
||||
$file = md5(json_encode($this->js) . $this->js_minify . $group) . '.js';
|
||||
|
||||
$relative_path = "{$this->base_url}" . basename(ASSETS_DIR) . "/{$file}";
|
||||
$absolute_path = ASSETS_DIR . $file;
|
||||
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
|
||||
$absolute_path = $this->assets_dir . $file;
|
||||
|
||||
// If pipeline exist return it
|
||||
if (file_exists($absolute_path)) {
|
||||
@@ -852,12 +859,12 @@ class Assets
|
||||
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
|
||||
{
|
||||
// Check if public_dir exists
|
||||
if (!is_dir(ASSETS_DIR)) {
|
||||
if (!is_dir($this->assets_dir)) {
|
||||
throw new Exception('Assets: Public dir not found');
|
||||
}
|
||||
|
||||
// Get files
|
||||
$files = $this->rglob(ASSETS_DIR . DIRECTORY_SEPARATOR . $directory, $pattern, ASSETS_DIR);
|
||||
$files = $this->rglob($this->assets_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->assets_dir);
|
||||
|
||||
// No luck? Nothing to do
|
||||
if (!$files) {
|
||||
|
||||
@@ -21,6 +21,8 @@ use Grav\Common\Filesystem\Folder;
|
||||
*/
|
||||
class Cache extends Getters
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/**
|
||||
* @var string Cache key.
|
||||
*/
|
||||
@@ -44,30 +46,30 @@ class Cache extends Getters
|
||||
protected $cache_dir;
|
||||
|
||||
protected static $standard_remove = [
|
||||
'cache/twig/',
|
||||
'cache/doctrine/',
|
||||
'cache/compiled/',
|
||||
'cache/validated-',
|
||||
'images/',
|
||||
'assets/',
|
||||
'cache://twig/',
|
||||
'cache://doctrine/',
|
||||
'cache://compiled/',
|
||||
'cache://validated-',
|
||||
'cache://images',
|
||||
'asset://',
|
||||
];
|
||||
|
||||
protected static $all_remove = [
|
||||
'cache/',
|
||||
'images/',
|
||||
'assets/'
|
||||
'cache://',
|
||||
'cache://images',
|
||||
'asset://'
|
||||
];
|
||||
|
||||
protected static $assets_remove = [
|
||||
'assets/'
|
||||
'asset://'
|
||||
];
|
||||
|
||||
protected static $images_remove = [
|
||||
'images/'
|
||||
'cache://images'
|
||||
];
|
||||
|
||||
protected static $cache_remove = [
|
||||
'cache/'
|
||||
'cache://'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -221,7 +223,7 @@ class Cache extends Getters
|
||||
*/
|
||||
public static function clearCache($remove = 'standard')
|
||||
{
|
||||
|
||||
$locator = self::getGrav()['locator'];
|
||||
$output = [];
|
||||
$user_config = USER_DIR . 'config/system.yaml';
|
||||
|
||||
@@ -243,10 +245,16 @@ class Cache extends Getters
|
||||
}
|
||||
|
||||
|
||||
foreach ($remove_paths as $path) {
|
||||
foreach ($remove_paths as $stream) {
|
||||
|
||||
// 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)
|
||||
throw new \RuntimeException("Stream '{$stream}' not found", 500);
|
||||
|
||||
$anything = false;
|
||||
$files = glob(ROOT_DIR . $path . '*');
|
||||
$files = glob($path . '/*');
|
||||
|
||||
if (is_array($files)) {
|
||||
foreach ($files as $file) {
|
||||
@@ -263,7 +271,7 @@ class Cache extends Getters
|
||||
}
|
||||
|
||||
if ($anything) {
|
||||
$output[] = '<red>Cleared: </red>' . $path . '*';
|
||||
$output[] = '<red>Cleared: </red>' . $path . '/*';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,12 @@ class Config extends Data
|
||||
'' => ['user'],
|
||||
]
|
||||
],
|
||||
'asset' => [
|
||||
'type' => 'ReadOnlyStream',
|
||||
'prefixes' => [
|
||||
'' => ['assets'],
|
||||
]
|
||||
],
|
||||
'blueprints' => [
|
||||
'type' => 'ReadOnlyStream',
|
||||
'prefixes' => [
|
||||
@@ -194,7 +200,7 @@ class Config extends Data
|
||||
$checkConfig = $this->get('system.cache.check.config', true);
|
||||
$checkSystem = $this->get('system.cache.check.system', true);
|
||||
|
||||
if (!$checkBlueprints && !!$checkLanguages && $checkConfig && !$checkSystem) {
|
||||
if (!$checkBlueprints && !$checkLanguages && !$checkConfig && !$checkSystem) {
|
||||
$this->messages[] = 'Skip configuration timestamp check.';
|
||||
return false;
|
||||
}
|
||||
@@ -286,6 +292,7 @@ class Config extends Data
|
||||
|
||||
protected function loadCompiledConfig($configs, $plugins, $filename = null)
|
||||
{
|
||||
$checksum = md5(json_encode($configs));
|
||||
$filename = $filename
|
||||
? CACHE_DIR . 'compiled/config/' . $filename . '-' . $this->environment . '.php'
|
||||
: CACHE_DIR . 'compiled/config/' . $checksum . '-' . $this->environment . '.php';
|
||||
|
||||
@@ -76,7 +76,9 @@ class Blueprint
|
||||
try {
|
||||
$this->validateArray($data, $this->nested);
|
||||
} catch (\RuntimeException $e) {
|
||||
throw new \RuntimeException(sprintf('<b>Validation failed:</b> %s', $e->getMessage()));
|
||||
$language = self::getGrav()['language'];
|
||||
$message = sprintf($language->translate('FORM.VALIDATION_FAIL', null, true) . ' %s', $e->getMessage());
|
||||
throw new \RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,7 +451,8 @@ class Blueprint
|
||||
if (isset($field['validate']['required'])
|
||||
&& $field['validate']['required'] === true
|
||||
&& empty($data[$name])) {
|
||||
throw new \RuntimeException("Missing required field: {$field['name']}");
|
||||
$value = isset($field['label']) ? $field['label'] : $field['name'];
|
||||
throw new \RuntimeException("Missing required field: {$value}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,16 +224,6 @@ class Data implements DataInterface
|
||||
return $this->file()->raw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data items.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or get the data storage.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
namespace Grav\Common\Data;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
@@ -37,7 +38,7 @@ class Validation
|
||||
$type = (string) isset($field['validate']['type']) ? $field['validate']['type'] : $field['type'];
|
||||
$method = 'type'.strtr($type, '-', '_');
|
||||
$name = ucfirst(isset($field['label']) ? $field['label'] : $field['name']);
|
||||
$message = (string) isset($field['validate']['message']) ? $field['validate']['message'] : 'Invalid input in "' . $language->translate($name) . '""';
|
||||
$message = (string) isset($field['validate']['message']) ? $field['validate']['message'] : $language->translate('FORM.INVALID_INPUT', null, true) . ' "' . $language->translate($name) . '"';
|
||||
|
||||
if (method_exists(__CLASS__, $method)) {
|
||||
$success = self::$method($value, $validate, $field);
|
||||
@@ -588,6 +589,10 @@ class Validation
|
||||
|
||||
public static function validateRequired($value, $params)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
|
||||
return (bool) $params !== true || !empty($value);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use Whoops\Run;
|
||||
* Class Debugger
|
||||
* @package Grav\Common
|
||||
*/
|
||||
class Errors extends \Whoops\Run
|
||||
class Errors extends Run
|
||||
{
|
||||
|
||||
public function pushHandler($handler, $key = null)
|
||||
|
||||
@@ -64,8 +64,8 @@ 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)
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
namespace Grav\Common\GPM\Local;
|
||||
|
||||
use Grav\Common\GPM\Common\AbstractPackageCollection as BaseCollection;
|
||||
use Grav\Common\GPM\Local\Package;
|
||||
|
||||
abstract class AbstractPackageCollection extends BaseCollection {
|
||||
|
||||
abstract class AbstractPackageCollection extends BaseCollection
|
||||
{
|
||||
public function __construct($items)
|
||||
{
|
||||
foreach ($items as $name => $data) {
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
namespace Grav\Common\GPM;
|
||||
|
||||
use Grav\Common\Data\Data;
|
||||
|
||||
/**
|
||||
* Interface Package
|
||||
* @package Grav\Common\GPM
|
||||
*/
|
||||
class Package
|
||||
{
|
||||
/**
|
||||
* @var Data
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
/**
|
||||
* @var \Grav\Common\Data\Blueprint
|
||||
*/
|
||||
protected $blueprints;
|
||||
|
||||
/**
|
||||
* @param Data $package
|
||||
* @param bool $package_type
|
||||
*/
|
||||
public function __construct(Data $package, $package_type = false);
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function isEnabled();
|
||||
|
||||
/**
|
||||
* @return Data
|
||||
*/
|
||||
public function getData();
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($key);
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString();
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function toJson();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
}
|
||||
@@ -3,7 +3,6 @@ namespace Grav\Common\GPM\Remote;
|
||||
|
||||
use Grav\Common\GPM\Common\AbstractPackageCollection as BaseCollection;
|
||||
use Grav\Common\GPM\Response;
|
||||
|
||||
use \Doctrine\Common\Cache\FilesystemCache;
|
||||
|
||||
class AbstractPackageCollection extends BaseCollection
|
||||
|
||||
@@ -16,6 +16,8 @@ class Plugins extends AbstractPackageCollection
|
||||
|
||||
/**
|
||||
* Local Plugins Constructor
|
||||
* @param bool $refresh
|
||||
* @param callable $callback Either a function or callback in array notation
|
||||
*/
|
||||
public function __construct($refresh = false, $callback = null)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,8 @@ class Themes extends AbstractPackageCollection
|
||||
|
||||
/**
|
||||
* Local Themes Constructor
|
||||
* @param bool $refresh
|
||||
* @param callable $callback Either a function or callback in array notation
|
||||
*/
|
||||
public function __construct($refresh = false, $callback = null)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Grav\Common\GPM;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
|
||||
class Response
|
||||
{
|
||||
/**
|
||||
@@ -50,6 +52,7 @@ class Response
|
||||
/**
|
||||
* Sets the preferred method to use for making HTTP calls.
|
||||
* @param string $method Default is `auto`
|
||||
* @return Response
|
||||
*/
|
||||
public static function setMethod($method = 'auto')
|
||||
{
|
||||
@@ -64,8 +67,9 @@ class Response
|
||||
|
||||
/**
|
||||
* Makes a request to the URL by using the preferred method
|
||||
* @param string $uri URL to call
|
||||
* @param array $options An array of parameters for both `curl` and `fopen`
|
||||
* @param string $uri URL to call
|
||||
* @param array $options An array of parameters for both `curl` and `fopen`
|
||||
* @param callable $callback Either a function or callback in array notation
|
||||
* @return string The response of the request
|
||||
*/
|
||||
public static function get($uri = '', $options = [], $callback = null)
|
||||
@@ -74,6 +78,11 @@ class Response
|
||||
throw new \RuntimeException('Could not start an HTTP request. `allow_url_open` is disabled and `cURL` is not available');
|
||||
}
|
||||
|
||||
// disable time limit if possible to help with slow downloads
|
||||
if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode')) {
|
||||
set_time_limit(0);
|
||||
}
|
||||
|
||||
$options = array_replace_recursive(self::$defaults, $options);
|
||||
$method = 'get' . ucfirst(strtolower(self::$method));
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ class Grav extends Container
|
||||
/** @var Uri $uri */
|
||||
$uri = $c['uri'];
|
||||
|
||||
$path = rtrim($uri->path(), '/');
|
||||
$path = $uri->path(); // Don't trim to support trailing slash default routes
|
||||
$path = $path ?: '/';
|
||||
|
||||
$page = $pages->dispatch($path);
|
||||
@@ -201,7 +201,10 @@ class Grav extends Container
|
||||
// Use output buffering to prevent headers from being sent too early.
|
||||
ob_start();
|
||||
if ($this['config']->get('system.cache.gzip')) {
|
||||
ob_start('ob_gzhandler');
|
||||
// Enable zip/deflate with a fallback in case of if browser does not support compressing.
|
||||
if(!ob_start("ob_gzhandler")) {
|
||||
ob_start();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the timezone
|
||||
@@ -296,7 +299,10 @@ class Grav extends Container
|
||||
if ($uri->isExternal($route)) {
|
||||
$url = $route;
|
||||
} else {
|
||||
$url = rtrim($uri->rootUrl(), '/') .'/'. trim($route, '/');
|
||||
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
|
||||
}
|
||||
|
||||
header("Location: {$url}", true, $code);
|
||||
@@ -413,22 +419,25 @@ class Grav extends Container
|
||||
public function shutdown()
|
||||
{
|
||||
if ($this['config']->get('system.debugger.shutdown.close_connection')) {
|
||||
//stop user abort
|
||||
// Prevent user abort.
|
||||
if (function_exists('ignore_user_abort')) {
|
||||
@ignore_user_abort(true);
|
||||
}
|
||||
|
||||
// close the session
|
||||
// Close the session.
|
||||
if (isset($this['session'])) {
|
||||
$this['session']->close();
|
||||
}
|
||||
|
||||
// flush buffer if gzip buffer was started
|
||||
if ($this['config']->get('system.cache.gzip')) {
|
||||
ob_end_flush(); // gzhandler buffer
|
||||
// Flush gzhandler buffer if gzip was enabled.
|
||||
ob_end_flush();
|
||||
} else {
|
||||
// Otherwise prevent server from compressing the output.
|
||||
header('Content-Encoding: none');
|
||||
}
|
||||
|
||||
// get lengh and close the connection
|
||||
// Get length and close the connection.
|
||||
header('Content-Length: ' . ob_get_length());
|
||||
header("Connection: close");
|
||||
|
||||
@@ -437,7 +446,7 @@ class Grav extends Container
|
||||
@ob_flush();
|
||||
flush();
|
||||
|
||||
// fix for fastcgi close connection issue
|
||||
// Fix for fastcgi close connection issue.
|
||||
if (function_exists('fastcgi_finish_request')) {
|
||||
@fastcgi_finish_request();
|
||||
}
|
||||
@@ -457,6 +466,20 @@ class Grav extends Container
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this['config'];
|
||||
|
||||
$uri_extension = $uri->extension();
|
||||
$fallback_types = $config->get('system.media.allowed_fallback_types', null);
|
||||
$supported_types = $config->get('media');
|
||||
|
||||
// Check whitelist first, then ensure extension is a valid media type
|
||||
if (!empty($fallback_types) && !in_array($uri_extension, $fallback_types)) {
|
||||
return;
|
||||
} elseif (!array_key_exists($uri_extension, $supported_types)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$path_parts = pathinfo($path);
|
||||
$page = $this['pages']->dispatch($path_parts['dirname'], true);
|
||||
if ($page) {
|
||||
@@ -478,7 +501,6 @@ class Grav extends Container
|
||||
}
|
||||
|
||||
// unsupported media type, try to download it...
|
||||
$uri_extension = $uri->extension();
|
||||
if ($uri_extension) {
|
||||
$extension = $uri_extension;
|
||||
} else {
|
||||
@@ -491,7 +513,7 @@ class Grav extends Container
|
||||
|
||||
if ($extension) {
|
||||
$download = true;
|
||||
if (in_array(ltrim($extension, '.'), $this['config']->get('system.media.unsupported_inline_types', []))) {
|
||||
if (in_array(ltrim($extension, '.'), $config->get('system.media.unsupported_inline_types', []))) {
|
||||
$download = false;
|
||||
}
|
||||
Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download);
|
||||
|
||||
@@ -131,7 +131,7 @@ class Truncator {
|
||||
$inner .= $txt;
|
||||
if ($remaining < 0) {
|
||||
if (static::ellipsable($node)) {
|
||||
$inner = preg_replace('/(?:[\s\pP]+|(?:&(?:[a-z]+|#[0-9]+);?))*$/', '', $inner).$opts['ellipsis'];
|
||||
$inner = preg_replace('/(?:[\s\pP]+|(?:&(?:[a-z]+|#[0-9]+);?))*$/u', '', $inner).$opts['ellipsis'];
|
||||
$opts['ellipsis'] = '';
|
||||
$opts['was_truncated'] = true;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ class Language
|
||||
*/
|
||||
public function setActiveFromUri($uri)
|
||||
{
|
||||
$regex = '/(^\/(' . $this->getAvailable() . ')).*/';
|
||||
$regex = '/(^\/(' . $this->getAvailable() . '))(?:\/.*|$)/i';
|
||||
|
||||
// if languages set
|
||||
if ($this->enabled()) {
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
<?php
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Debugger;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
/**
|
||||
* A trait to add some custom processing to the identifyLink() method in Parsedown and ParsedownExtra
|
||||
@@ -211,7 +207,7 @@ trait ParsedownGravTrait
|
||||
// if there is no scheme, the file is local
|
||||
if (!isset($url['scheme']) && (count($url) > 0)) {
|
||||
// convert the URl is required
|
||||
$excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type);
|
||||
$excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,18 @@ class Collection extends Iterator
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Create a copy of this collection
|
||||
@@ -96,6 +108,7 @@ class Collection extends Iterator
|
||||
* Remove item from the list.
|
||||
*
|
||||
* @param Page|string|null $key
|
||||
* @return $this|void
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function remove($key = null)
|
||||
@@ -110,6 +123,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
parent::remove($key);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
namespace Grav\Common\Page;
|
||||
|
||||
use Grav\Common\Getters;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Page\Medium\MediumFactory;
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Medium;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\Data;
|
||||
|
||||
class AudioMedium extends Medium
|
||||
{
|
||||
use StaticResizeTrait;
|
||||
|
||||
@@ -4,11 +4,20 @@ namespace Grav\Common\Page\Medium;
|
||||
use Grav\Common\GravTrait;
|
||||
use Gregwar\Image\Exceptions\GenerationError;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use Gregwar\Image\Image;
|
||||
|
||||
class ImageFile extends \Gregwar\Image\Image
|
||||
class ImageFile extends Image
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/**
|
||||
* Clear previously applied operations
|
||||
*/
|
||||
public function clearOperations()
|
||||
{
|
||||
$this->operations = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the same as the Gregwar Image class except this one fires a Grav Event on creation of new cached file
|
||||
*
|
||||
|
||||
@@ -52,7 +52,6 @@ class ImageMedium extends Medium
|
||||
'forceResize' => [ 0, 1 ],
|
||||
'cropResize' => [ 0, 1 ],
|
||||
'crop' => [ 0, 1, 2, 3 ],
|
||||
'cropResize' => [ 0, 1 ],
|
||||
'zoomCrop' => [ 0, 1 ]
|
||||
];
|
||||
|
||||
@@ -260,6 +259,7 @@ class ImageMedium extends Medium
|
||||
|
||||
if ($this->image) {
|
||||
$this->image();
|
||||
$this->image->clearOperations(); // Clear previously applied operations
|
||||
$this->filter();
|
||||
}
|
||||
|
||||
@@ -311,19 +311,23 @@ class ImageMedium extends Medium
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the quality of the image
|
||||
* Sets or gets the quality of the image
|
||||
*
|
||||
* @param int $quality 0-100 quality
|
||||
* @return Medium
|
||||
*/
|
||||
public function quality($quality)
|
||||
public function quality($quality = null)
|
||||
{
|
||||
if (!$this->image) {
|
||||
$this->image();
|
||||
if ($quality) {
|
||||
if (!$this->image) {
|
||||
$this->image();
|
||||
}
|
||||
|
||||
$this->quality = $quality;
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->quality = $quality;
|
||||
return $this;
|
||||
return $this->quality;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -359,6 +363,48 @@ class ImageMedium extends Medium
|
||||
return empty($this->sizes) ? '100vw' : $this->sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set the width attribute from Markdown or Twig
|
||||
* Examples: 
|
||||
* 
|
||||
* 
|
||||
* 
|
||||
* {{ page.media['myimg.png'].width().height().html }}
|
||||
* {{ page.media['myimg.png'].resize(100,200).width(100).height(200).html }}
|
||||
*
|
||||
* @param mixed $value A value or 'auto' or empty to use the width of the image
|
||||
* @return $this
|
||||
*/
|
||||
public function width($value = 'auto')
|
||||
{
|
||||
if (!$value || $value == 'auto')
|
||||
$this->attributes['width'] = $this->get('width');
|
||||
else
|
||||
$this->attributes['width'] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set the height attribute from Markdown or Twig
|
||||
* Examples: 
|
||||
* 
|
||||
* 
|
||||
* 
|
||||
* {{ page.media['myimg.png'].width().height().html }}
|
||||
* {{ page.media['myimg.png'].resize(100,200).width(100).height(200).html }}
|
||||
*
|
||||
* @param mixed $value A value or 'auto' or empty to use the height of the image
|
||||
* @return $this
|
||||
*/
|
||||
public function height($value = 'auto')
|
||||
{
|
||||
if (!$value || $value == 'auto')
|
||||
$this->attributes['height'] = $this->get('height');
|
||||
else
|
||||
$this->attributes['height'] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward the call to the image processing method.
|
||||
*
|
||||
@@ -470,4 +516,28 @@ class ImageMedium extends Medium
|
||||
$this->__call($method, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image higher quality version
|
||||
*
|
||||
* @return ImageMedium the alternative version with higher quality
|
||||
*/
|
||||
public function higherQualityAlternative()
|
||||
{
|
||||
if ($this->alternatives) {
|
||||
$max = reset($this->alternatives);
|
||||
foreach($this->alternatives as $alternative)
|
||||
{
|
||||
if($alternative->quality() > $max->quality())
|
||||
{
|
||||
$max = $alternative;
|
||||
}
|
||||
}
|
||||
|
||||
return $max;
|
||||
} else {
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -209,9 +209,13 @@ class Medium extends Data implements RenderableInterface
|
||||
|
||||
$style = '';
|
||||
foreach ($this->styleAttributes as $key => $value) {
|
||||
$style .= $key . ': ' . $value . ';';
|
||||
if (is_numeric($key)) // Special case for inline style attributes, refer to style() method
|
||||
$style .= $value;
|
||||
else
|
||||
$style .= $key . ': ' . $value . ';';
|
||||
}
|
||||
$attributes['style'] = $style;
|
||||
if ($style)
|
||||
$attributes['style'] = $style;
|
||||
|
||||
if (empty($attributes['title'])) {
|
||||
if (!empty($title)) {
|
||||
@@ -388,6 +392,19 @@ class Medium extends Data implements RenderableInterface
|
||||
return $this->link($reset, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to add an inline style attribute from Markdown or Twig
|
||||
* Example: 
|
||||
*
|
||||
* @param string $style
|
||||
* @return $this
|
||||
*/
|
||||
public function style($style)
|
||||
{
|
||||
$this->styleAttributes[] = rtrim($style, ';') . ';';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow any action to be called on this medium from twig or markdown
|
||||
*
|
||||
@@ -440,4 +457,5 @@ class Medium extends Data implements RenderableInterface
|
||||
|
||||
return $this->_thumbnail;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Medium;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\Data;
|
||||
|
||||
class VideoMedium extends Medium
|
||||
{
|
||||
use StaticResizeTrait;
|
||||
|
||||
@@ -41,6 +41,7 @@ class Page
|
||||
protected $folder;
|
||||
protected $path;
|
||||
protected $extension;
|
||||
protected $url_extension;
|
||||
|
||||
protected $id;
|
||||
protected $parent;
|
||||
@@ -128,6 +129,7 @@ class Page
|
||||
$this->modularTwig($this->slug[0] == '_');
|
||||
$this->setPublishState();
|
||||
$this->published();
|
||||
$this->urlExtension();
|
||||
|
||||
// some extension logic
|
||||
if (empty($extension)) {
|
||||
@@ -136,6 +138,7 @@ class Page
|
||||
$this->extension($extension);
|
||||
}
|
||||
|
||||
|
||||
// extract page language from page extension
|
||||
$language = trim(basename($this->extension(), 'md'), '.') ?: null;
|
||||
$this->language($language);
|
||||
@@ -349,7 +352,6 @@ class Page
|
||||
if (isset($this->header->last_modified)) {
|
||||
$this->last_modified = (bool) $this->header->last_modified;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this->header;
|
||||
@@ -957,6 +959,17 @@ class Page
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
public function urlExtension()
|
||||
{
|
||||
// if not set in the page get the value from system config
|
||||
if (empty($this->url_extension)) {
|
||||
$this->url_extension = trim(isset($this->header->append_url_extension) ? $this->header->append_url_extension : self::getGrav()['config']->get('system.pages.append_url_extension', false));
|
||||
}
|
||||
|
||||
return $this->url_extension;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and sets the expires field. If not set will return the default
|
||||
*
|
||||
@@ -1137,7 +1150,7 @@ class Page
|
||||
$this->metadata = [];
|
||||
|
||||
// Set the Generator tag
|
||||
$this->metadata['generator'] = array('name'=>'generator', 'content'=>'GravCMS ' . GRAV_VERSION);
|
||||
$this->metadata['generator'] = array('name'=>'generator', 'content'=>'GravCMS');
|
||||
|
||||
// Get initial metadata for the page
|
||||
$metadata = self::getGrav()['config']->get('site.metadata');
|
||||
@@ -1262,7 +1275,7 @@ class Page
|
||||
|
||||
$rootUrl = $uri->rootUrl($include_host) . $pages->base();
|
||||
|
||||
$url = $rootUrl.'/'.trim($route, '/');
|
||||
$url = $rootUrl.'/'.trim($route, '/') . $this->urlExtension();
|
||||
|
||||
// trim trailing / if not root
|
||||
if ($url !== '/') {
|
||||
@@ -1471,7 +1484,17 @@ class Page
|
||||
*/
|
||||
public function filePathClean()
|
||||
{
|
||||
return str_replace(ROOT_DIR, '', $this->filePath());
|
||||
$path = str_replace(ROOT_DIR, '', $this->filePath());
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the clean path to the page file
|
||||
*/
|
||||
public function relativePagePath()
|
||||
{
|
||||
$path = str_replace('/'.$this->name, '', $this->filePathClean());
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1935,7 +1958,7 @@ class Page
|
||||
// Format: @command.param
|
||||
$cmd = $value;
|
||||
$params = array();
|
||||
} elseif (is_array($value) && count($value) == 1) {
|
||||
} 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);
|
||||
@@ -1957,51 +1980,92 @@ class Page
|
||||
return $value;
|
||||
}
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = self::getGrav()['pages'];
|
||||
|
||||
$parts = explode('.', $cmd);
|
||||
$current = array_shift($parts);
|
||||
|
||||
$results = null;
|
||||
$results = new Collection();
|
||||
switch ($current) {
|
||||
case '@self':
|
||||
if (!empty($parts)) {
|
||||
switch ($parts[0]) {
|
||||
case 'modular':
|
||||
// @self.modular: false (alternative to @self.children)
|
||||
if (!empty($params) && $params[0] === false) {
|
||||
$results = $this->children()->nonModular()->published();
|
||||
$results = $this->children()->nonModular();
|
||||
break;
|
||||
}
|
||||
$results = $this->children()->modular()->published();
|
||||
$results = $this->children()->modular();
|
||||
break;
|
||||
case 'children':
|
||||
$results = $this->children()->nonModular()->published();
|
||||
$results = $this->children()->nonModular();
|
||||
break;
|
||||
|
||||
case 'parent':
|
||||
$collection = new Collection();
|
||||
$results = $collection->addPage($this->parent());
|
||||
break;
|
||||
|
||||
case 'siblings':
|
||||
$results = $this->parent()->children()->remove($this->path());
|
||||
break;
|
||||
|
||||
case 'descendants':
|
||||
$results = $pages->all($this)->remove($this->path())->nonModular();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$results = $results->published();
|
||||
break;
|
||||
|
||||
case '@page':
|
||||
$page = null;
|
||||
|
||||
if (!empty($params)) {
|
||||
/** @var Pages $pages */
|
||||
$pages = self::getGrav()['pages'];
|
||||
$page = $this->find($params[0]);
|
||||
}
|
||||
|
||||
list($what, $recurse) = array_pad($params, 2, null);
|
||||
// safety check in case page is not found
|
||||
if (!isset($page)) {
|
||||
return $results;
|
||||
}
|
||||
|
||||
if ($what == '@root') {
|
||||
$page = $pages->root();
|
||||
} else {
|
||||
$page = $this->find($what);
|
||||
// Handle a @page.descendants
|
||||
if (!empty($parts)) {
|
||||
switch ($parts[0]) {
|
||||
case 'self':
|
||||
$results = new Collection();
|
||||
$results = $results->addPage($page);
|
||||
break;
|
||||
|
||||
case 'descendants':
|
||||
$results = $pages->all($page)->remove($page->path());
|
||||
break;
|
||||
|
||||
case 'children':
|
||||
$results = $page->children();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$results = $page->children();
|
||||
}
|
||||
|
||||
if ($page) {
|
||||
if ($recurse) {
|
||||
$results = $pages->all($page)->nonModular()->published();
|
||||
} else {
|
||||
$results = $page->children()->nonModular()->published();
|
||||
}
|
||||
}
|
||||
$results = $results->nonModular()->published();
|
||||
|
||||
break;
|
||||
|
||||
case '@root':
|
||||
if (!empty($parts) && $parts[0] == 'descendants') {
|
||||
$results = $pages->all($pages->root())->nonModular()->published();
|
||||
} else {
|
||||
$results = $pages->root()->children()->nonModular()->published();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case '@taxonomy':
|
||||
// Gets a collection of pages by using one of the following formats:
|
||||
// @taxonomy.category: blog
|
||||
|
||||
@@ -272,6 +272,10 @@ class Pages
|
||||
{
|
||||
// Fetch page if there's a defined route to it.
|
||||
$page = isset($this->routes[$url]) ? $this->get($this->routes[$url]) : null;
|
||||
// Try without trailing slash
|
||||
if (!$page && Utils::endsWith($url, '/')) {
|
||||
$page = isset($this->routes[rtrim($url, '/')]) ? $this->get($this->routes[rtrim($url, '/')]) : null;
|
||||
}
|
||||
|
||||
// Are we in the admin? this is important!
|
||||
$not_admin = !isset($this->grav['admin']);
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Grav\Common;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Data\Blueprints;
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
use RocketTheme\Toolbox\Event\EventSubscriberInterface;
|
||||
@@ -122,6 +121,12 @@ class Plugins extends Iterator
|
||||
|
||||
// Load default configuration.
|
||||
$file = CompiledYamlFile::instance("plugins://{$name}/{$name}.yaml");
|
||||
|
||||
// ensure the plugin exists physically
|
||||
if (!$file->exists()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$obj = new Data($file->content(), $blueprint);
|
||||
|
||||
// Override with user configuration.
|
||||
|
||||
@@ -171,6 +171,8 @@ class Themes extends Iterator
|
||||
exit("Theme '$name' does not exist, unable to display page.");
|
||||
}
|
||||
|
||||
$this->config->set('theme', $config->get('themes.' . $name));
|
||||
|
||||
if (empty($class)) {
|
||||
$class = new Theme($grav, $config, $name);
|
||||
}
|
||||
@@ -282,11 +284,11 @@ class Themes extends Iterator
|
||||
$class = substr($class, strlen($prefix));
|
||||
|
||||
// Replace namespace tokens to directory separators
|
||||
$path = ltrim(preg_replace('#\\\|_(?!.+\\\)#', '/', $class), '/');
|
||||
$path = strtolower(ltrim(preg_replace('#\\\|_(?!.+\\\)#', '/', $class), '/'));
|
||||
$file = $locator->findResource("themes://{$path}/{$path}.php");
|
||||
|
||||
// Load class
|
||||
if (stream_resolve_include_path($file)) {
|
||||
if (file_exists($file)) {
|
||||
return include_once($file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ namespace Grav\Common\Twig;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Inflector;
|
||||
use Grav\Common\Utils;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<?php
|
||||
namespace Grav\Common\Twig;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
|
||||
/**
|
||||
* The Twig Environment class is a wrapper that handles configurable permissions
|
||||
* for the Twig cache files
|
||||
|
||||
@@ -70,6 +70,7 @@ class TwigExtension extends \Twig_Extension
|
||||
new \Twig_SimpleFilter('randomize', [$this,'randomizeFilter']),
|
||||
new \Twig_SimpleFilter('modulus', [$this,'modulusFilter']),
|
||||
new \Twig_SimpleFilter('rtrim', [$this, 'rtrimFilter']),
|
||||
new \Twig_SimpleFilter('pad', [$this, 'padFilter']),
|
||||
new \Twig_SimpleFilter('safe_email', [$this,'safeEmailFilter']),
|
||||
new \Twig_SimpleFilter('safe_truncate', ['\Grav\Common\Utils','safeTruncate']),
|
||||
new \Twig_SimpleFilter('safe_truncate_html', ['\Grav\Common\Utils','safeTruncateHTML']),
|
||||
@@ -94,14 +95,17 @@ class TwigExtension extends \Twig_Extension
|
||||
new \Twig_simpleFunction('authorize', [$this, 'authorize']),
|
||||
new \Twig_SimpleFunction('debug', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]),
|
||||
new \Twig_SimpleFunction('dump', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]),
|
||||
new \Twig_SimpleFunction('evaluate', [$this, 'evaluateFunc']),
|
||||
new \Twig_SimpleFunction('gist', [$this, 'gistFunc']),
|
||||
new \Twig_SimpleFunction('nonce_field', [$this, 'nonceFieldFunc']),
|
||||
new \Twig_simpleFunction('random_string', [$this, 'randomStringFunc']),
|
||||
new \Twig_SimpleFunction('repeat', [$this, 'repeatFunc']),
|
||||
new \Twig_SimpleFunction('string', [$this, 'stringFunc']),
|
||||
new \Twig_simpleFunction('t', [$this, 'translate']),
|
||||
new \Twig_simpleFunction('ta', [$this, 'translateArray']),
|
||||
new \Twig_SimpleFunction('url', [$this, 'urlFunc']),
|
||||
new \Twig_SimpleFunction('evaluate', [$this, 'evaluateFunc']),
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
@@ -534,6 +538,22 @@ class TwigExtension extends \Twig_Extension
|
||||
return Utils::generateRandomString($count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad a string to a certain length with another string
|
||||
*
|
||||
* @param $input
|
||||
* @param $pad_length
|
||||
* @param string $pad_string
|
||||
* @param int $pad_type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function padFilter($input, $pad_length, $pad_string = " ", $pad_type = STR_PAD_RIGHT)
|
||||
{
|
||||
return str_pad($input, (int) $pad_length, $pad_string, $pad_type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cast a value to array
|
||||
*
|
||||
@@ -595,4 +615,22 @@ class TwigExtension extends \Twig_Extension
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to add a nonce to a form. Call {{ nonce_field('action') }} specifying a string representing the action.
|
||||
*
|
||||
* For maximum protection, ensure that the string representing the action is as specific as possible.
|
||||
*
|
||||
* @todo evaluate if adding referrer or not
|
||||
*
|
||||
* @param string action the action
|
||||
* @param string nonceParamName a custom nonce param name
|
||||
*
|
||||
* @return string the nonce input field
|
||||
*/
|
||||
public function nonceFieldFunc($action, $nonceParamName = 'nonce')
|
||||
{
|
||||
$string = '<input type="hidden" id="' . $nonceParamName . '" name="' . $nonceParamName . '" value="' . Utils::getNonce($action) .'" />';
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
|
||||
/**
|
||||
* The URI object provides information about the current URL
|
||||
@@ -133,11 +132,16 @@ class Uri
|
||||
// set the original basename
|
||||
$this->basename = $parts['basename'];
|
||||
|
||||
// set the extension
|
||||
if (isset($parts['extension'])) {
|
||||
$this->extension = $parts['extension'];
|
||||
}
|
||||
|
||||
$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'];
|
||||
$this->extension = $parts['extension'];
|
||||
}
|
||||
|
||||
// set the new url
|
||||
@@ -481,12 +485,14 @@ class Uri
|
||||
/**
|
||||
* Converts links from absolute '/' or relative (../..) to a grav friendly format
|
||||
*
|
||||
* @param $page the current page to use as reference
|
||||
* @param Page|the $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
|
||||
*/
|
||||
public static function convertUrl(Page $page, $markdown_url, $type = 'link')
|
||||
public static function convertUrl(Page $page, $markdown_url, $type = 'link', $relative = null)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
@@ -500,7 +506,13 @@ class Uri
|
||||
}
|
||||
|
||||
$pages_dir = $grav['locator']->findResource('page://');
|
||||
$base_url = rtrim($grav['base_url'] . $grav['pages']->base(), '/') . $language_append;
|
||||
if (is_null($relative)) {
|
||||
$base = $grav['base_url'];
|
||||
} else {
|
||||
$base = $relative ? $grav['base_url_relative'] : $grav['base_url_absolute'];
|
||||
}
|
||||
|
||||
$base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append;
|
||||
|
||||
// if absolute and starts with a base_url move on
|
||||
if (pathinfo($markdown_url, PATHINFO_DIRNAME) == '.' && $page->url() == '/') {
|
||||
@@ -568,4 +580,20 @@ class Uri
|
||||
return $normalized_url;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the nonce to a URL for a specific 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
|
||||
*/
|
||||
public static function addNonce($url, $action, $nonceParamName = 'nonce')
|
||||
{
|
||||
$urlWithNonce = $url . '/' . $nonceParamName . Grav::instance()['config']->get('system.param_sep', ':') . Utils::getNonce($action);
|
||||
return $urlWithNonce;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ class User extends Data
|
||||
if (!isset($content['username'])) {
|
||||
$content['username'] = $username;
|
||||
}
|
||||
if (!isset($content['state'])) {
|
||||
$content['state'] = 'enabled';
|
||||
}
|
||||
$user = new User($content, $blueprint);
|
||||
$user->file($file);
|
||||
|
||||
@@ -139,6 +142,10 @@ class User extends Data
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($this->state) && $this->state !== 'enabled') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return Utils::isPositive($this->get("access.{$action}"));
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,9 @@ abstract class Utils
|
||||
return (object)array_merge((array)$obj1, (array)$obj2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function dateFormats()
|
||||
{
|
||||
$now = new DateTime();
|
||||
@@ -300,6 +303,19 @@ abstract class Utils
|
||||
return $root . implode('/', $ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $function
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isFunctionDisabled($function)
|
||||
{
|
||||
return in_array($function, explode(',', ini_get('disable_functions')));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function timezones()
|
||||
{
|
||||
$timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL);
|
||||
@@ -327,6 +343,12 @@ abstract class Utils
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $source
|
||||
* @param $fn
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFilterRecursive(Array $source, $fn)
|
||||
{
|
||||
$result = array();
|
||||
@@ -346,6 +368,11 @@ abstract class Utils
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function pathPrefixedByLangCode($string)
|
||||
{
|
||||
$languages_enabled = self::getGrav()['config']->get('system.languages.supported', []);
|
||||
@@ -357,6 +384,11 @@ abstract class Utils
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $date
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function date2timestamp($date)
|
||||
{
|
||||
$config = self::getGrav()['config'];
|
||||
@@ -384,7 +416,111 @@ abstract class Utils
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isPositive($value) {
|
||||
public static function isPositive($value)
|
||||
{
|
||||
return in_array($value, [true, 1, '1', 'yes', 'on', 'true'], true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates a nonce string to be hashed. Called by self::getNonce()
|
||||
*
|
||||
* @param string $action
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
*
|
||||
* @return string the nonce string
|
||||
*/
|
||||
private static function generateNonceString($action, $plusOneTick = false)
|
||||
{
|
||||
if (isset(self::getGrav()['user'])) {
|
||||
$user = self::getGrav()['user'];
|
||||
$username = $user->username;
|
||||
} else {
|
||||
$username = false;
|
||||
}
|
||||
|
||||
if (!$username) {
|
||||
$username = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
|
||||
}
|
||||
|
||||
$token = session_id();
|
||||
$i = self::nonceTick();
|
||||
|
||||
if ($plusOneTick) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
return ( $i . '|' . $action . '|' . $username . '|' . $token );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time-dependent variable for nonce creation.
|
||||
*
|
||||
* @todo now a tick lasts a day. Once the day is passed, the nonce is not valid any more. Find a better way
|
||||
* to ensure nonces issued near the end of the day do not expire in that small amount of time
|
||||
*
|
||||
* @return int the time part of the nonce. Changes once every 24 hours
|
||||
*/
|
||||
private static function nonceTick()
|
||||
{
|
||||
$secondsInHalfADay = 60 * 60 * 12;
|
||||
return (int)ceil(time() / ( $secondsInHalfADay ));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hash of given string
|
||||
*
|
||||
* @param string $data string to hash
|
||||
*
|
||||
* @return string hashed value of $data, cut to 10 characters
|
||||
*/
|
||||
private static function hash($data)
|
||||
{
|
||||
$hash = password_hash($data, PASSWORD_DEFAULT);
|
||||
return $hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
*
|
||||
* @return string the nonce
|
||||
*/
|
||||
public static function getNonce($action, $plusOneTick = false)
|
||||
{
|
||||
$nonce = self::hash(self::generateNonceString($action, $plusOneTick));
|
||||
$nonce = str_replace('/', 'SLASH', $nonce);
|
||||
return $nonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the passed nonce for the give action
|
||||
*
|
||||
* @param string $nonce the nonce to verify
|
||||
* @param string $action the action to verify the nonce to
|
||||
*
|
||||
* @return boolean verified or not
|
||||
*/
|
||||
public static function verifyNonce($nonce, $action)
|
||||
{
|
||||
$nonce = str_replace('SLASH', '/', $nonce);
|
||||
|
||||
//Nonce generated 0-12 hours ago
|
||||
if (password_verify(self::generateNonceString($action), $nonce)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Nonce generated 12-24 hours ago
|
||||
$plusOneTick = true;
|
||||
if (password_verify(self::generateNonceString($action, $plusOneTick), $nonce)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Invalid nonce
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,23 +2,17 @@
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Common\Backup\ZipBackup;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use RocketTheme\Toolbox\File\JsonFile;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Helper\ProgressBar;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class BackupCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class BackupCommand extends Command
|
||||
class BackupCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
protected $source;
|
||||
protected $progress;
|
||||
|
||||
@@ -42,21 +36,16 @@ class BackupCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$this->progress = new ProgressBar($output);
|
||||
$this->progress = new ProgressBar($this->output);
|
||||
$this->progress->setFormat('Archiving <cyan>%current%</cyan> files [<green>%bar%</green>] %elapsed:6s% %memory:6s%');
|
||||
|
||||
self::getGrav()['config']->init();
|
||||
|
||||
$destination = ($input->getArgument('destination')) ? $input->getArgument('destination') : null;
|
||||
$destination = ($this->input->getArgument('destination')) ? $this->input->getArgument('destination') : null;
|
||||
$log = JsonFile::instance(self::getGrav()['locator']->findResource("log://backup.log", true, true));
|
||||
$backup = ZipBackup::backup($destination, [$this, 'output']);
|
||||
|
||||
@@ -66,16 +55,13 @@ class BackupCommand extends Command
|
||||
]);
|
||||
$log->save();
|
||||
|
||||
$output->writeln('');
|
||||
$output->writeln('');
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $folder
|
||||
* @param $zipFile
|
||||
* @param $exclusiveLength
|
||||
* @param $progress
|
||||
* @param $args
|
||||
*/
|
||||
public function output($args)
|
||||
{
|
||||
|
||||
@@ -2,20 +2,14 @@
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
|
||||
/**
|
||||
* Class CleanCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class CleanCommand extends Command
|
||||
class CleanCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@@ -172,14 +166,10 @@ class CleanCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$this->cleanPaths();
|
||||
}
|
||||
|
||||
|
||||
@@ -2,29 +2,24 @@
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Common\Cache;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class ClearCacheCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class ClearCacheCommand extends Command
|
||||
class ClearCacheCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName("clear-cache")
|
||||
->setDescription("Clears Grav cache")
|
||||
->setName('clear-cache')
|
||||
->setAliases(['clearcache'])
|
||||
->setDescription('Clears Grav cache')
|
||||
->addOption('all', null, InputOption::VALUE_NONE, 'If set will remove all including compiled, twig, doctrine caches')
|
||||
->addOption('assets-only', null, InputOption::VALUE_NONE, 'If set will remove only assets/*')
|
||||
->addOption('images-only', null, InputOption::VALUE_NONE, 'If set will remove only images/*')
|
||||
@@ -33,14 +28,10 @@ class ClearCacheCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$this->cleanPaths();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
<?php
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Class ComposerCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class ComposerCommand extends Command
|
||||
class ComposerCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -59,24 +52,19 @@ class ComposerCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$action = $this->input->getOption('install') ? 'install' : ($this->input->getOption('update') ? 'update' : 'install');
|
||||
|
||||
$action = $input->getOption('install') ? 'install' : ($input->getOption('update') ? 'update' : 'install');
|
||||
|
||||
if ($input->getOption('install')) {
|
||||
if ($this->input->getOption('install')) {
|
||||
$action = 'install';
|
||||
}
|
||||
|
||||
// Updates composer first
|
||||
$output->writeln("\nInstalling vendor dependencies");
|
||||
$output->writeln($this->composerUpdate(GRAV_ROOT, $action));
|
||||
$this->output->writeln("\nInstalling vendor dependencies");
|
||||
$this->output->writeln($this->composerUpdate(GRAV_ROOT, $action));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
<?php
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* Class InstallCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class InstallCommand extends Command
|
||||
class InstallCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -51,24 +46,18 @@ class InstallCommand extends Command
|
||||
'destination',
|
||||
InputArgument::OPTIONAL,
|
||||
'Where to install the required bits (default to current project)'
|
||||
|
||||
)
|
||||
->setDescription("Installs the dependencies needed by Grav. Optionally can create symbolic links")
|
||||
->setHelp('The <info>install</info> command installs the dependencies needed by Grav. Optionally can create symbolic links');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$dependencies_file = '.dependencies';
|
||||
$this->destination = ($input->getArgument('destination')) ? $input->getArgument('destination') : ROOT_DIR;
|
||||
$this->destination = ($this->input->getArgument('destination')) ? $this->input->getArgument('destination') : ROOT_DIR;
|
||||
|
||||
// fix trailing slash
|
||||
$this->destination = rtrim($this->destination, DS) . DS;
|
||||
@@ -78,7 +67,7 @@ class InstallCommand extends Command
|
||||
$local_config_file = exec('eval echo ~/.grav/config');
|
||||
if (file_exists($local_config_file)) {
|
||||
$this->local_config = Yaml::parse($local_config_file);
|
||||
$output->writeln('Read local config from <cyan>' . $local_config_file . '</cyan>');
|
||||
$this->output->writeln('Read local config from <cyan>' . $local_config_file . '</cyan>');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,22 +77,22 @@ class InstallCommand extends Command
|
||||
} elseif (file_exists($this->destination . $dependencies_file)) {
|
||||
$this->config = Yaml::parse($this->destination . $dependencies_file);
|
||||
} else {
|
||||
$output->writeln('<red>ERROR</red> Missing .dependencies file in <cyan>user/</cyan> folder');
|
||||
$this->output->writeln('<red>ERROR</red> Missing .dependencies file in <cyan>user/</cyan> folder');
|
||||
}
|
||||
|
||||
// If yaml config, process
|
||||
if ($this->config) {
|
||||
if (!$input->getOption('symlink')) {
|
||||
if (!$this->input->getOption('symlink')) {
|
||||
// Updates composer first
|
||||
$output->writeln("\nInstalling vendor dependencies");
|
||||
$output->writeln($this->composerUpdate(GRAV_ROOT, 'install'));
|
||||
$this->output->writeln("\nInstalling vendor dependencies");
|
||||
$this->output->writeln($this->composerUpdate(GRAV_ROOT, 'install'));
|
||||
|
||||
$this->gitclone();
|
||||
} else {
|
||||
$this->symlink();
|
||||
}
|
||||
} else {
|
||||
$output->writeln('<red>ERROR</red> invalid YAML in ' . $dependencies_file);
|
||||
$this->output->writeln('<red>ERROR</red> invalid YAML in ' . $dependencies_file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,29 +1,25 @@
|
||||
<?php
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class NewProjectCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class NewProjectCommand extends Command
|
||||
class NewProjectCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName("new-project")
|
||||
->setName('new-project')
|
||||
->setAliases(['newproject'])
|
||||
->addArgument(
|
||||
'destination',
|
||||
InputArgument::REQUIRED,
|
||||
@@ -35,37 +31,32 @@ class NewProjectCommand extends Command
|
||||
InputOption::VALUE_NONE,
|
||||
'Symlink the required bits'
|
||||
)
|
||||
->setDescription("Creates a new Grav project with all the dependencies installed")
|
||||
->setHelp("The <info>new-project</info> command is a combination of the `setup` and `install` commands.\nCreates a new Grav instance and performs the installation of all the required dependencies.");
|
||||
->setDescription('Creates a new Grav project with all the dependencies installed')
|
||||
->setHelp('The <info>new-project</info> command is a combination of the `setup` and `install` commands.\nCreates a new Grav instance and performs the installation of all the required dependencies.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$sandboxCommand = $this->getApplication()->find('sandbox');
|
||||
$installCommand = $this->getApplication()->find('install');
|
||||
|
||||
$sandboxArguments = new ArrayInput(array(
|
||||
'command' => 'sandbox',
|
||||
'destination' => $input->getArgument('destination'),
|
||||
'-s' => $input->getOption('symlink')
|
||||
'destination' => $this->input->getArgument('destination'),
|
||||
'-s' => $this->input->getOption('symlink')
|
||||
));
|
||||
|
||||
$installArguments = new ArrayInput(array(
|
||||
'command' => 'install',
|
||||
'destination' => $input->getArgument('destination'),
|
||||
'-s' => $input->getOption('symlink')
|
||||
'destination' => $this->input->getArgument('destination'),
|
||||
'-s' => $this->input->getOption('symlink')
|
||||
));
|
||||
|
||||
$sandboxCommand->run($sandboxArguments, $output);
|
||||
$installCommand->run($installArguments, $output);
|
||||
$sandboxCommand->run($sandboxArguments, $this->output);
|
||||
$installCommand->run($installArguments, $this->output);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +1,34 @@
|
||||
<?php
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Common\Data\Blueprints;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\User\User;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Helper\Helper;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Console\Question\Question;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
|
||||
/**
|
||||
* Class CleanCommand
|
||||
*
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class NewUserCommand extends Command
|
||||
class NewUserCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* Configure the command
|
||||
*/
|
||||
protected function configure()
|
||||
{
|
||||
$this
|
||||
->setName("newuser")
|
||||
->setDescription("Creates a new user")
|
||||
->setHelp('The <info>newuser</info> creates a new user file in user/accounts/ folder');
|
||||
->setName('newuser')
|
||||
->setDescription('DEPRECATED: Creates a new user')
|
||||
->setHelp('The <info>newuser</info> from `bin/grav` has been deprecated. Please refer to `bin/plugin login new-user')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$helper = $this->getHelper('question');
|
||||
$data = [];
|
||||
|
||||
$this->output->writeln('<green>Create new user</green>');
|
||||
$this->output->writeln('');
|
||||
|
||||
// Get username and validate
|
||||
$question = new Question('Enter a <yellow>username</yellow>: ', 'admin');
|
||||
$question->setValidator(function ($value) {
|
||||
if (!preg_match('/^[a-z0-9_-]{3,16}$/', $value)) {
|
||||
throw new RuntimeException(
|
||||
'Username should be between 3 and 16 characters, including lowercase letters, numbers, underscores, and hyphens. Uppercase letters, spaces, and special characters are not allowed'
|
||||
);
|
||||
}
|
||||
if (file_exists(self::getGrav()['locator']->findResource('user://accounts/' . $value . YAML_EXT))) {
|
||||
throw new RuntimeException(
|
||||
'Username "'.$value.'" already exists, please pick another username'
|
||||
);
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
$username = $helper->ask($this->input, $this->output, $question);
|
||||
|
||||
// Get password and validate
|
||||
$password = $this->askForPassword($helper, 'Enter a <yellow>password</yellow>: ', function ($password1) use ($helper) {
|
||||
if (!preg_match('/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/', $password1)) {
|
||||
throw new RuntimeException('Password must contain at least one number and one uppercase and lowercase letter, and at least 8 or more characters');
|
||||
}
|
||||
// Since input is hidden when prompting for passwords, the user is asked to repeat the password
|
||||
return $this->askForPassword($helper, 'Repeat the <yellow>password</yellow>: ', function ($password2) use ($password1) {
|
||||
if (strcmp($password2, $password1)) {
|
||||
throw new RuntimeException('Passwords did not match.');
|
||||
}
|
||||
return $password2;
|
||||
});
|
||||
});
|
||||
$data['password'] = $password;
|
||||
|
||||
// Get email and validate
|
||||
$question = new Question('Enter an <yellow>email</yellow>: ');
|
||||
$question->setValidator(function ($value) {
|
||||
if (!preg_match('/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/', $value)) {
|
||||
throw new RuntimeException(
|
||||
'Not a valid email address'
|
||||
);
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
$data['email'] = $helper->ask($this->input, $this->output, $question);
|
||||
|
||||
// Choose permissions
|
||||
$question = new ChoiceQuestion(
|
||||
'Please choose a set of <yellow>permissions</yellow>:',
|
||||
array('a'=>'admin access', 's'=>'site access', 'b'=>'admin and site access'),
|
||||
'a'
|
||||
);
|
||||
$question->setErrorMessage('permissions %s is invalid.');
|
||||
$permissions_choice = $helper->ask($this->input, $this->output, $question);
|
||||
|
||||
switch ($permissions_choice) {
|
||||
case 'a':
|
||||
$data['access']['admin'] = ['login' => true, 'super' => true];
|
||||
break;
|
||||
case 's':
|
||||
$data['access']['site'] = ['login' => true];
|
||||
break;
|
||||
case 'b':
|
||||
$data['access']['admin'] = ['login' => true, 'super' => true];
|
||||
$data['access']['site'] = ['login' => true];
|
||||
}
|
||||
|
||||
// Get fullname
|
||||
$question = new Question('Enter a <yellow>fullname</yellow>: ');
|
||||
$question->setValidator(function ($value) {
|
||||
if ($value === null || trim($value) == '') {
|
||||
throw new RuntimeException(
|
||||
'Fullname is required'
|
||||
);
|
||||
}
|
||||
return $value;
|
||||
});
|
||||
$data['fullname'] = $helper->ask($this->input, $this->output, $question);
|
||||
|
||||
// Get title
|
||||
$question = new Question('Enter a <yellow>title</yellow>: ');
|
||||
$data['title'] = $helper->ask($this->input, $this->output, $question);
|
||||
|
||||
// Create user object and save it
|
||||
$user = new User($data);
|
||||
$file = CompiledYamlFile::instance(self::getGrav()['locator']->findResource('user://accounts/' . $username . YAML_EXT, true, true));
|
||||
$user->file($file);
|
||||
$user->save();
|
||||
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln('<green>Success!</green> User <cyan>'. $username .'</cyan> created.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get password and validate.
|
||||
*
|
||||
* @param Helper $helper
|
||||
* @param string $question
|
||||
* @param callable $validator
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function askForPassword(Helper $helper, $question, callable $validator)
|
||||
{
|
||||
$question = new Question($question);
|
||||
$question->setValidator($validator);
|
||||
$question->setHidden(true);
|
||||
$question->setHiddenFallback(true);
|
||||
return $helper->ask($this->input, $this->output, $question);
|
||||
$this->output->writeln('<red>DEPRECATED COMMAND</red>');
|
||||
$this->output->writeln(' <white>`bin/grav new-user`</white> has been <red>deprecated</red> in favor of the new <white>`bin/plugin login new-user`</white>');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,17 @@
|
||||
<?php
|
||||
namespace Grav\Console\Cli;
|
||||
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class SandboxCommand
|
||||
* @package Grav\Console\Cli
|
||||
*/
|
||||
class SandboxCommand extends Command
|
||||
class SandboxCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
@@ -96,18 +90,14 @@ class SandboxCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$this->destination = $input->getArgument('destination');
|
||||
$this->destination = $this->input->getArgument('destination');
|
||||
|
||||
// Symlink the Core Stuff
|
||||
if ($input->getOption('symlink')) {
|
||||
if ($this->input->getOption('symlink')) {
|
||||
// Create Some core stuff if it doesn't exist
|
||||
$this->createDirectories();
|
||||
|
||||
|
||||
35
system/src/Grav/Console/ConsoleCommand.php
Normal file
35
system/src/Grav/Console/ConsoleCommand.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace Grav\Console;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class ConsoleCommand
|
||||
*
|
||||
* @package Grav\Console
|
||||
*/
|
||||
class ConsoleCommand extends Command
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$this->serve();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function serve() { }
|
||||
|
||||
}
|
||||
@@ -2,20 +2,16 @@
|
||||
namespace Grav\Console\Gpm;
|
||||
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class IndexCommand
|
||||
*
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class IndexCommand extends Command
|
||||
class IndexCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -39,19 +35,15 @@ class IndexCommand extends Command
|
||||
'Force re-fetching the data from remote'
|
||||
)
|
||||
->setDescription("Lists the plugins and themes available for installation")
|
||||
->setHelp('The <info>index</info> command lists the plugins and themes available for installation');
|
||||
->setHelp('The <info>index</info> command lists the plugins and themes available for installation')
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$this->gpm = new GPM($this->input->getOption('force'));
|
||||
|
||||
$this->data = $this->gpm->getRepository();
|
||||
@@ -93,15 +85,15 @@ class IndexCommand extends Command
|
||||
*/
|
||||
private function versionDetails($package)
|
||||
{
|
||||
$list = $this->gpm->{'getUpdatable' . ucfirst($package->package_type)}();
|
||||
$package = isset($list[$package->slug]) ? $list[$package->slug] : $package;
|
||||
$type = ucfirst(preg_replace("/s$/", '', $package->package_type));
|
||||
$list = $this->gpm->{'getUpdatable' . ucfirst($package->package_type)}();
|
||||
$package = isset($list[$package->slug]) ? $list[$package->slug] : $package;
|
||||
$type = ucfirst(preg_replace("/s$/", '', $package->package_type));
|
||||
$updatable = $this->gpm->{'is' . $type . 'Updatable'}($package->slug);
|
||||
$installed = $this->gpm->{'is' . $type . 'Installed'}($package->slug);
|
||||
$local = $this->gpm->{'getInstalled' . $type}($package->slug);
|
||||
$local = $this->gpm->{'getInstalled' . $type}($package->slug);
|
||||
|
||||
if (!$installed || !$updatable) {
|
||||
$version = $installed ? $local->version : $package->version;
|
||||
$version = $installed ? $local->version : $package->version;
|
||||
$installed = !$installed ? ' (<magenta>not installed</magenta>)' : ' (<cyan>installed</cyan>)';
|
||||
|
||||
return str_pad(" [v<green>" . $version . "</green>]", 35) . $installed;
|
||||
|
||||
@@ -2,21 +2,16 @@
|
||||
namespace Grav\Console\Gpm;
|
||||
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class InfoCommand
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class InfoCommand extends Command
|
||||
class InfoCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -49,20 +44,16 @@ class InfoCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$this->gpm = new GPM($this->input->getOption('force'));
|
||||
|
||||
$foundPackage = $this->gpm->findPackage($input->getArgument('package'));
|
||||
$foundPackage = $this->gpm->findPackage($this->input->getArgument('package'));
|
||||
|
||||
if (!$foundPackage) {
|
||||
$this->output->writeln("The package <cyan>'" . $input->getArgument('package') . "'</cyan> was not found in the Grav repository.");
|
||||
$this->output->writeln("The package <cyan>'" . $this->input->getArgument('package') . "'</cyan> was not found in the Grav repository.");
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln("You can list all the available packages by typing:");
|
||||
$this->output->writeln(" <green>" . $this->argv . " index</green>");
|
||||
@@ -70,7 +61,7 @@ class InfoCommand extends Command
|
||||
exit;
|
||||
}
|
||||
|
||||
$this->output->writeln("Found package <cyan>'" . $input->getArgument('package') . "'</cyan> under the '<green>" . ucfirst($foundPackage->package_type) . "</green>' section");
|
||||
$this->output->writeln("Found package <cyan>'" . $this->input->getArgument('package') . "'</cyan> under the '<green>" . ucfirst($foundPackage->package_type) . "</green>' section");
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln("<cyan>" . $foundPackage->name . "</cyan> [" . $foundPackage->slug . "]");
|
||||
$this->output->writeln(str_repeat('-', strlen($foundPackage->name) + strlen($foundPackage->slug) + 3));
|
||||
|
||||
@@ -5,14 +5,10 @@ use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Common\GPM\Installer;
|
||||
use Grav\Common\GPM\Response;
|
||||
use Grav\Common\Inflector;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
use Symfony\Component\Console\Question\ChoiceQuestion;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
@@ -23,10 +19,8 @@ define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/
|
||||
* Class InstallCommand
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class InstallCommand extends Command
|
||||
class InstallCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -87,15 +81,10 @@ class InstallCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$this->gpm = new GPM($this->input->getOption('force'));
|
||||
$this->destination = realpath($this->input->getOption('destination'));
|
||||
|
||||
|
||||
@@ -5,22 +5,17 @@ use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\GPM\Installer;
|
||||
use Grav\Common\GPM\Response;
|
||||
use Grav\Common\GPM\Upgrader;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
|
||||
/**
|
||||
* Class SelfupgradeCommand
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class SelfupgradeCommand extends Command
|
||||
class SelfupgradeCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -75,14 +70,10 @@ class SelfupgradeCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
$this->upgrader = new Upgrader($this->input->getOption('force'));
|
||||
|
||||
$update = $this->upgrader->getAssets()['grav-update'];
|
||||
|
||||
@@ -1,25 +1,19 @@
|
||||
<?php
|
||||
namespace Grav\Console\Gpm;
|
||||
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Common\GPM\Installer;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
|
||||
/**
|
||||
* Class UninstallCommand
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class UninstallCommand extends Command
|
||||
class UninstallCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -64,15 +58,10 @@ class UninstallCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$this->gpm = new GPM();
|
||||
|
||||
$packages = array_map('strtolower', $this->input->getArgument('package'));
|
||||
|
||||
@@ -3,23 +3,18 @@ namespace Grav\Console\Gpm;
|
||||
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Common\GPM\Installer;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
|
||||
/**
|
||||
* Class UpdateCommand
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class UpdateCommand extends Command
|
||||
class UpdateCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -85,15 +80,10 @@ class UpdateCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$this->gpm = new GPM($this->input->getOption('force'));
|
||||
$this->destination = realpath($this->input->getOption('destination'));
|
||||
$skip_prompt = $this->input->getOption('all-yes');
|
||||
|
||||
@@ -3,21 +3,16 @@ namespace Grav\Console\Gpm;
|
||||
|
||||
use Grav\Common\GPM\GPM;
|
||||
use Grav\Common\GPM\Upgrader;
|
||||
use Grav\Console\ConsoleTrait;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
|
||||
/**
|
||||
* Class VersionCommand
|
||||
* @package Grav\Console\Gpm
|
||||
*/
|
||||
class VersionCommand extends Command
|
||||
class VersionCommand extends ConsoleCommand
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
@@ -46,15 +41,10 @@ class VersionCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
*
|
||||
* @return int|null|void
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function serve()
|
||||
{
|
||||
$this->setupConsole($input, $output);
|
||||
|
||||
$this->gpm = new GPM($this->input->getOption('force'));
|
||||
$packages = $this->input->getArgument('package');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user