update grav et plugin
This commit is contained in:
+127
-3
@@ -1,3 +1,127 @@
|
||||
# v1.6.27
|
||||
## 09/01/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Right trim route for safety
|
||||
* Use the proper ellipsis for summary [#2939](https://github.com/getgrav/grav/pull/2939)
|
||||
* Left pad schedule times with zeros [#2921](https://github.com/getgrav/grav/pull/2921)
|
||||
|
||||
# v1.6.26
|
||||
## 06/08/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Added new configuration option to control the supported attributes in markdown links [#2882](https://github.com/getgrav/grav/issues/2882)
|
||||
1. [](#bugfix)
|
||||
* Fixed blueprint for `system.pages.hide_empty_folders` [#1925](https://github.com/getgrav/grav/issues/2925)
|
||||
* JSON Route of homepage with no ‘route’ set is valid
|
||||
* Fix case-insensitive search of location header [form#425](https://github.com/getgrav/grav-plugin-form/issues/425)
|
||||
|
||||
# v1.6.25
|
||||
## 05/14/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Added system configuration support for `HTTP_X_Forwarded` headers (host disabled by default)
|
||||
* Updated `PHPUserAgentParser` to 1.0.0
|
||||
* Bump `Go` to version 1.13 in `travis.yaml`
|
||||
|
||||
# v1.6.24
|
||||
## 04/27/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Added support for `X-Forwarded-Host` [#2891](https://github.com/getgrav/grav/pull/2891)
|
||||
* Disable XDebug in Travis builds
|
||||
|
||||
# v1.6.23
|
||||
## 03/19/2020
|
||||
|
||||
1. [](#new)
|
||||
* Moved `Parsedown` 1.6 and `ParsedownExtra` 0.7 into `Grav\Framework\Parsedown` to allow fixes
|
||||
* Added `aliases.php` with references to direct `\Parsedown` and `\ParsedownExtra` references
|
||||
1. [](#improved)
|
||||
* Upgraded `jQuery` to latest 3.4.1 version [#2859](https://github.com/getgrav/grav/issues/2859)
|
||||
1. [](#bugfix)
|
||||
* Fixed PHP 7.4 issue in ParsedownExtra [#2832](https://github.com/getgrav/grav/issues/2832)
|
||||
* Fix for [user reported](https://twitter.com/OriginalSicksec) CVE path-based open redirect
|
||||
* Fix for `stream_set_option` error with PHP 7.4 via Toolbox#28 [#2850](https://github.com/getgrav/grav/issues/2850)
|
||||
|
||||
# v1.6.22
|
||||
## 03/05/2020
|
||||
|
||||
1. [](#new)
|
||||
* Added `Pages::reset()` method
|
||||
1. [](#improved)
|
||||
* Updated Negotiation library to address issues [#2513](https://github.com/getgrav/grav/issues/2513)
|
||||
1. [](#bugfix)
|
||||
* Fixed issue with search plugins not being able to switch between page translations
|
||||
* Fixed issues with `Pages::baseRoute()` not picking up active language reliably
|
||||
* Reverted `validation: strict` fix as it breaks sites, see [#1273](https://github.com/getgrav/grav/issues/1273)
|
||||
|
||||
# v1.6.21
|
||||
## 02/11/2020
|
||||
|
||||
1. [](#new)
|
||||
* Added `ConsoleCommand::setLanguage()` method to set language to be used from CLI
|
||||
* Added `ConsoleCommand::initializeGrav()` method to properly set up Grav instance to be used from CLI
|
||||
* Added `ConsoleCommand::initializePlugins()`method to properly set up all plugins to be used from CLI
|
||||
* Added `ConsoleCommand::initializeThemes()`method to properly set up current theme to be used from CLI
|
||||
* Added `ConsoleCommand::initializePages()` method to properly set up pages to be used from CLI
|
||||
1. [](#improved)
|
||||
* Vendor updates
|
||||
1. [](#bugfix)
|
||||
* Fixed `bin/plugin` CLI calling `$themes->init()` way too early (removed it, use above methods instead)
|
||||
* Fixed call to `$grav['page']` crashing CLI
|
||||
* Fixed encoding problems when PHP INI setting `default_charset` is not `utf-8` [#2154](https://github.com/getgrav/grav/issues/2154)
|
||||
|
||||
# v1.6.20
|
||||
## 02/03/2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed incorrect routing caused by `str_replace()` in `Uri::init()` [#2754](https://github.com/getgrav/grav/issues/2754)
|
||||
* Fixed session cookie is being set twice in the HTTP header [#2745](https://github.com/getgrav/grav/issues/2745)
|
||||
* Fixed session not restarting if user was invalid (downgrading from Grav 1.7)
|
||||
* Fixed filesystem iterator calls with non-existing folders
|
||||
* Fixed `checkbox` field not being saved, requires also Form v4.0.2 [#1225](https://github.com/getgrav/grav/issues/1225)
|
||||
* Fixed `validation: strict` not working in blueprints [#1273](https://github.com/getgrav/grav/issues/1273)
|
||||
* Fixed `Data::filter()` removing empty fields (such as empty list) by default [#2805](https://github.com/getgrav/grav/issues/2805)
|
||||
* Fixed fatal error with non-integer page param value [#2803](https://github.com/getgrav/grav/issues/2803)
|
||||
* Fixed `Assets::addInlineJs()` parameter type mismatch between v1.5 and v1.6 [#2659](https://github.com/getgrav/grav/issues/2659)
|
||||
* Fixed `site.metadata` saving issues [#2615](https://github.com/getgrav/grav/issues/2615)
|
||||
|
||||
# v1.6.19
|
||||
## 12/04/2019
|
||||
|
||||
1. [](#new)
|
||||
* Catch PHP 7.4 deprecation messages and report them in debugbar instead of throwing fatal error
|
||||
1. [](#bugfix)
|
||||
* Fixed fatal error when calling `{{ grav.undefined }}`
|
||||
* Fixed multiple issues when there are no pages in the site
|
||||
* PHP 7.4 fix for [#2750](https://github.com/getgrav/grav/issues/2750)
|
||||
|
||||
# v1.6.18
|
||||
## 12/02/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* PHP 7.4 fix in `Pages::buildSort()`
|
||||
* Updated vendor libraries for PHP 7.4 fixes in Twig and other libraries
|
||||
* Fixed fatal error when `$page->id()` is null [#2731](https://github.com/getgrav/grav/pull/2731)
|
||||
* Fixed cache conflicts on pages with no set id
|
||||
* Fix rewrite rule for for `lighttpd` default config [#721](https://github.com/getgrav/grav/pull/2721)
|
||||
|
||||
# v1.6.17
|
||||
## 11/06/2019
|
||||
|
||||
1. [](#new)
|
||||
* Added working ETag (304 Not Modified) support based on the final rendered HTML
|
||||
1. [](#improved)
|
||||
* Safer file handling + customizable null char replacement in `CsvFormatter::decode()`
|
||||
* Change of Behavior: `Inflector::hyphenize` will now automatically trim dashes at beginning and end of a string.
|
||||
* Change in Behavior for `Folder::all()` so no longer fails if trying to copy non-existent dot file [#2581](https://github.com/getgrav/grav/pull/2581)
|
||||
* renamed composer `test-plugins` script to `phpstan-plugins` to be more explicit [#2637](https://github.com/getgrav/grav/pull/2637)
|
||||
1. [](#bugfix)
|
||||
* Fixed PHP 7.1 bug in FlexMedia
|
||||
* Fix cache image generation when using cropResize [#2639](https://github.com/getgrav/grav/pull/2639)
|
||||
* Fix `array_merge()` exception with non-array page header metadata [#2701](https://github.com/getgrav/grav/pull/2701)
|
||||
|
||||
# v1.6.16
|
||||
## 09/19/2019
|
||||
|
||||
@@ -35,7 +159,7 @@
|
||||
* Support new GRAV_BASEDIR environment variable [#2541](https://github.com/getgrav/grav/pull/2541)
|
||||
* Allow users to override plugin handler priorities [#2165](https://github.com/getgrav/grav/pull/2165)
|
||||
1. [](#improved)
|
||||
* Use new `Utils::getSupportedPageTypes()` to enforce `html,htm` at the front of the list [#2531](https://github.com/getgrav/grav/issues/2531)
|
||||
* Use new `Utils::getSupportedPageTypes()` to enforce `html,htm` at the front of the list [#2531](https://github.com/getgrav/grav/issues/2531)
|
||||
* Updated vendor libraries
|
||||
* Markdown filter is now page-aware so that it works with modular references [admin#1731](https://github.com/getgrav/grav-plugin-admin/issues/1731)
|
||||
* Check of `GRAV_USER_INSTANCE` constant is already defined [#2621](https://github.com/getgrav/grav/pull/2621)
|
||||
@@ -54,7 +178,7 @@
|
||||
* Fixed `FlexObject::exists()` failing sometimes just after the object has been saved
|
||||
* Fixed CSV formatter not encoding strings with `"` and `,` properly
|
||||
* Fixed var order in `Validation.php` [#2610](https://github.com/getgrav/grav/issues/2610)
|
||||
|
||||
|
||||
# v1.6.11
|
||||
## 06/21/2019
|
||||
|
||||
@@ -85,7 +209,7 @@
|
||||
* Fixed regression with `bin/plugin` not listing the plugins available (1c725c0)
|
||||
* Fixed bitwise operator in `TwigExtension::exifFunc()` [#2518](https://github.com/getgrav/grav/issues/2518)
|
||||
* Fixed issue with lang prefix incorrectly identifying as admin [#2511](https://github.com/getgrav/grav/issues/2511)
|
||||
* Fixed issue with `U0ils::pathPrefixedBYLanguageCode()` and trailing slash [#2510](https://github.com/getgrav/grav/issues/2511)
|
||||
* Fixed issue with `U0ils::pathPrefixedBYLanguageCode()` and trailing slash [#2510](https://github.com/getgrav/grav/issues/2511)
|
||||
* Fixed regresssion issue of `Utils::Url()` not returning `false` on failure. Added new optional `fail_gracefully` 3rd attribute to return string that caused failure [#2524](https://github.com/getgrav/grav/issues/2524)
|
||||
|
||||
# v1.6.9
|
||||
|
||||
@@ -28,6 +28,13 @@ if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
if (!file_exists(GRAV_ROOT . '/index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
@@ -55,7 +62,7 @@ $grav->setup($environment);
|
||||
|
||||
$grav['config']->init();
|
||||
$grav['uri']->init();
|
||||
$grav['users'];
|
||||
$grav['accounts'];
|
||||
|
||||
$app = new Application('Grav Package Manager', GRAV_VERSION);
|
||||
$app->addCommands(array(
|
||||
|
||||
@@ -25,6 +25,17 @@ if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
|
||||
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
|
||||
}
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
$climate = new League\CLImate\CLImate;
|
||||
$climate->arguments->add([
|
||||
'environment' => [
|
||||
@@ -42,10 +53,6 @@ $environment = $climate->arguments->get('environment');
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav->setup($environment);
|
||||
|
||||
if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
if (!file_exists(GRAV_ROOT . '/index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
|
||||
+8
-6
@@ -32,6 +32,13 @@ if (!ini_get('date.timezone')) {
|
||||
date_default_timezone_set('UTC');
|
||||
}
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
if (!file_exists(GRAV_ROOT . '/index.php')) {
|
||||
exit('FATAL: Must be run from ROOT directory of Grav!');
|
||||
}
|
||||
@@ -51,12 +58,7 @@ $environment = $climate->arguments->get('environment');
|
||||
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav->setup($environment);
|
||||
|
||||
$grav['config']->init();
|
||||
$grav['uri']->init();
|
||||
$grav['users'];
|
||||
$grav['plugins']->init();
|
||||
$grav['themes']->init();
|
||||
$grav->initializeCli();
|
||||
|
||||
$app = new Application('Grav Plugins Commands', GRAV_VERSION);
|
||||
$pattern = '([A-Z]\w+Command\.php)';
|
||||
|
||||
+18
-13
@@ -2,7 +2,13 @@
|
||||
"name": "getgrav/grav",
|
||||
"type": "project",
|
||||
"description": "Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS",
|
||||
"keywords": ["cms","flat-file cms","flat cms","flatfile cms","php"],
|
||||
"keywords": [
|
||||
"cms",
|
||||
"flat-file cms",
|
||||
"flat cms",
|
||||
"flatfile cms",
|
||||
"php"
|
||||
],
|
||||
"homepage": "https://getgrav.org",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
@@ -16,17 +22,12 @@
|
||||
"symfony/polyfill-iconv": "^1.9",
|
||||
"symfony/polyfill-php72": "^1.9",
|
||||
"symfony/polyfill-php73": "^1.9",
|
||||
|
||||
"psr/simple-cache": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"psr/http-server-middleware": "^1.0",
|
||||
|
||||
"kodus/psr7-server": "*",
|
||||
"nyholm/psr7": "^1.0",
|
||||
|
||||
"twig/twig": "~1.40",
|
||||
"erusev/parsedown": "1.6.4",
|
||||
"erusev/parsedown-extra": "~0.7",
|
||||
"symfony/yaml": "~4.2.0",
|
||||
"symfony/console": "~4.2.0",
|
||||
"symfony/event-dispatcher": "~4.2.0",
|
||||
@@ -36,13 +37,12 @@
|
||||
"doctrine/collections": "^1.5",
|
||||
"guzzlehttp/psr7": "^1.4",
|
||||
"filp/whoops": "~2.2",
|
||||
|
||||
"matthiasmullie/minify": "^1.3",
|
||||
"monolog/monolog": "~1.0",
|
||||
"gregwar/image": "2.*",
|
||||
"donatj/phpuseragentparser": "~0.10",
|
||||
"donatj/phpuseragentparser": "~1.0",
|
||||
"pimple/pimple": "~3.2",
|
||||
"rockettheme/toolbox": "~1.4",
|
||||
"rockettheme/toolbox": "~1.4.0",
|
||||
"maximebf/debugbar": "~1.15",
|
||||
"league/climate": "^3.4",
|
||||
"antoligy/dom-string-iterators": "^1.0",
|
||||
@@ -50,7 +50,7 @@
|
||||
"composer/ca-bundle": "^1.0",
|
||||
"dragonmantank/cron-expression": "^1.2",
|
||||
"phive/twig-extensions-deferred": "^1.0",
|
||||
"willdurand/negotiation": "^2.3"
|
||||
"willdurand/negotiation": "2.x-dev"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.4",
|
||||
@@ -83,10 +83,15 @@
|
||||
"psr-4": {
|
||||
"Grav\\": "system/src/Grav"
|
||||
},
|
||||
"files": ["system/defines.php"]
|
||||
"files": [
|
||||
"system/defines.php",
|
||||
"system/aliases.php"
|
||||
]
|
||||
},
|
||||
"archive": {
|
||||
"exclude": ["VERSION"]
|
||||
"exclude": [
|
||||
"VERSION"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"api-16": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.16.md",
|
||||
@@ -94,7 +99,7 @@
|
||||
"post-create-project-cmd": "bin/grav install",
|
||||
"phpstan": "vendor/bin/phpstan analyse -l 2 -c ./tests/phpstan/phpstan.neon system/src --memory-limit=256M",
|
||||
"phpstan-framework": "vendor/bin/phpstan analyse -l 5 -c ./tests/phpstan/phpstan.neon system/src/Grav/Framework --memory-limit=256M",
|
||||
"test-plugins": "vendor/bin/phpstan analyse -l 0 -c ./tests/phpstan/plugins.neon user/plugins --memory-limit=256M",
|
||||
"phpstan-plugins": "vendor/bin/phpstan analyse -l 0 -c ./tests/phpstan/plugins.neon user/plugins --memory-limit=256M",
|
||||
"test": "vendor/bin/codecept run unit",
|
||||
"test-windows": "vendor\\bin\\codecept run unit"
|
||||
},
|
||||
|
||||
Generated
+500
-529
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
chown -R 1000:www-data .
|
||||
chown -R 1000:http .
|
||||
find . -type f -exec chmod 664 {} \;
|
||||
find ./bin -type f -exec chmod 775 {} \;
|
||||
find . -type d -exec chmod 775 {} \;
|
||||
|
||||
@@ -20,6 +20,16 @@ if (PHP_SAPI === 'cli-server' && !isset($_SERVER['PHP_CLI_ROUTER'])) {
|
||||
die("PHP webserver requires a router to run Grav, please use: <pre>php -S {$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']} system/router.php</pre>");
|
||||
}
|
||||
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding.
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
@ini_set('default_charset', 'UTF-8');
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
$autoload = __DIR__ . '/vendor/autoload.php';
|
||||
if (!is_file($autoload)) {
|
||||
@@ -32,15 +42,6 @@ $loader = require $autoload;
|
||||
use Grav\Common\Grav;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
// Set timezone to default, falls back to system if php.ini not set
|
||||
date_default_timezone_set(@date_default_timezone_get());
|
||||
|
||||
// Set internal encoding if mbstring loaded
|
||||
if (!\extension_loaded('mbstring')) {
|
||||
die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
|
||||
}
|
||||
mb_internal_encoding('UTF-8');
|
||||
|
||||
// Get the Grav instance
|
||||
$grav = Grav::instance(
|
||||
array(
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
/** Moved from non-namespaced classes to Grav Framework */
|
||||
class_alias(Grav\Framework\Parsedown\Parsedown::class, '\Parsedown');
|
||||
class_alias(Grav\Framework\Parsedown\ParsedownExtra::class, '\ParsedownExtra');
|
||||
+2
-2
File diff suppressed because one or more lines are too long
@@ -241,13 +241,15 @@ form:
|
||||
type: commalist
|
||||
|
||||
pages.hide_empty_folders:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.HIDE_EMPTY_FOLDERS
|
||||
help: PLUGIN_ADMIN.HIDE_EMPTY_FOLDERS_HELP
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.HIDE_EMPTY_FOLDERS
|
||||
help: PLUGIN_ADMIN.HIDE_EMPTY_FOLDERS_HELP
|
||||
highlight: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
pages.url_taxonomy_filters:
|
||||
type: toggle
|
||||
@@ -513,6 +515,16 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
pages.markdown.valid_link_attributes:
|
||||
type: selectize
|
||||
size: large
|
||||
label: PLUGIN_ADMIN.VALID_LINK_ATTRIBUTES
|
||||
help: PLUGIN_ADMIN.VALID_LINK_ATTRIBUTES_HELP
|
||||
placeholder: "rel, target, id, class, classes"
|
||||
classes: fancy
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
caching:
|
||||
type: tab
|
||||
title: PLUGIN_ADMIN.CACHING
|
||||
@@ -1379,6 +1391,51 @@ form:
|
||||
label: PLUGIN_ADMIN.CUSTOM_BASE_URL
|
||||
help: PLUGIN_ADMIN.CUSTOM_BASE_URL_HELP
|
||||
|
||||
http_x_forwarded.protocol:
|
||||
type: toggle
|
||||
label: HTTP_X_FORWARDED_PROTO Enabled
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
http_x_forwarded.host:
|
||||
type: toggle
|
||||
label: HTTP_X_FORWARDED_HOST Enabled
|
||||
highlight: 0
|
||||
default: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
http_x_forwarded.port:
|
||||
type: toggle
|
||||
label: HTTP_X_FORWARDED_PORT Enabled
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
http_x_forwarded.ip:
|
||||
type: toggle
|
||||
label: HTTP_X_FORWARDED IP Enabled
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
|
||||
accounts.type:
|
||||
type: hidden
|
||||
|
||||
|
||||
@@ -10,6 +10,11 @@ custom_base_url: '' # Set the base_url manually, e.
|
||||
username_regex: '^[a-z0-9_-]{3,16}$' # Only lowercase chars, digits, dashes, underscores. 3 - 16 chars
|
||||
pwd_regex: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' # At least one number, one uppercase and lowercase letter, and be at least 8+ chars
|
||||
intl_enabled: true # Special logic for PHP International Extension (mod_intl)
|
||||
http_x_forwarded: # Configuration options for the various HTTP_X_FORWARD headers
|
||||
protocol: true
|
||||
host: false
|
||||
port: true
|
||||
ip: true
|
||||
|
||||
languages:
|
||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
||||
@@ -54,6 +59,12 @@ pages:
|
||||
special_chars: # List of special characters to automatically convert to entities
|
||||
'>': 'gt'
|
||||
'<': 'lt'
|
||||
valid_link_attributes: # Valid attributes to pass through via markdown links
|
||||
- rel
|
||||
- target
|
||||
- id
|
||||
- class
|
||||
- classes
|
||||
types: [html,htm,xml,txt,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)
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.6.16');
|
||||
define('GRAV_VERSION', '1.6.27');
|
||||
define('GRAV_TESTING', false);
|
||||
define('DS', '/');
|
||||
|
||||
|
||||
@@ -51,7 +51,11 @@ trait LegacyAssetsTrait
|
||||
// special case to handle old attributes being passed in
|
||||
if (isset($arguments['attributes'])) {
|
||||
$old_attributes = $arguments['attributes'];
|
||||
$arguments = array_merge($arguments, $old_attributes);
|
||||
if (is_array($old_attributes)) {
|
||||
$arguments = array_merge($arguments, $old_attributes);
|
||||
} else {
|
||||
$arguments['type'] = $old_attributes;
|
||||
}
|
||||
}
|
||||
unset($arguments['attributes']);
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use function donatj\UserAgent\parse_user_agent;
|
||||
|
||||
/**
|
||||
* Internally uses the PhpUserAgent package https://github.com/donatj/PhpUserAgent
|
||||
*/
|
||||
|
||||
@@ -136,7 +136,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
{
|
||||
$messages = $this->checkRequired($data, $rules);
|
||||
|
||||
foreach ($data as $key => $field) {
|
||||
foreach ($data as $key => $child) {
|
||||
$val = $rules[$key] ?? $rules['*'] ?? null;
|
||||
$rule = \is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
@@ -147,10 +147,10 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages += Validation::validate($field, $rule);
|
||||
} elseif (\is_array($field) && \is_array($val)) {
|
||||
$messages += Validation::validate($child, $rule);
|
||||
} elseif (\is_array($child) && \is_array($val)) {
|
||||
// Array has been defined in blueprints.
|
||||
$messages += $this->validateArray($field, $val);
|
||||
$messages += $this->validateArray($child, $val);
|
||||
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
|
||||
// Undefined/extra item.
|
||||
throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key));
|
||||
|
||||
@@ -32,6 +32,12 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
/** @var File */
|
||||
protected $storage;
|
||||
|
||||
/** @var bool */
|
||||
private $missingValuesAsNull = false;
|
||||
|
||||
/** @var bool */
|
||||
private $keepEmptyValues = true;
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param Blueprint|callable $blueprints
|
||||
@@ -42,6 +48,28 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
$this->blueprints = $blueprints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setKeepEmptyValues(bool $value)
|
||||
{
|
||||
$this->keepEmptyValues = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setMissingValuesAsNull(bool $value)
|
||||
{
|
||||
$this->missingValuesAsNull = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
@@ -202,8 +230,8 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
public function filter()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$missingValuesAsNull = (bool)(array_shift($args) ?: false);
|
||||
$keepEmptyValues = (bool)(array_shift($args) ?: false);
|
||||
$missingValuesAsNull = (bool)(array_shift($args) ?? $this->missingValuesAsNull);
|
||||
$keepEmptyValues = (bool)(array_shift($args) ?? $this->keepEmptyValues);
|
||||
|
||||
$this->items = $this->blueprints()->filter($this->items, $missingValuesAsNull, $keepEmptyValues);
|
||||
|
||||
|
||||
@@ -166,9 +166,18 @@ class Validation
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param array $params
|
||||
* @param array $field
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function filterCheckbox($value, array $params, array $field)
|
||||
{
|
||||
return (bool) $value;
|
||||
$value = (string)$value;
|
||||
$field_value = (string)($field['value'] ?? '1');
|
||||
|
||||
return $value === $field_value ? $value : null;
|
||||
}
|
||||
|
||||
protected static function filterCommaList($value, array $params, array $field)
|
||||
|
||||
@@ -347,7 +347,7 @@ class Debugger
|
||||
*/
|
||||
public function deprecatedErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if ($errno !== E_USER_DEPRECATED) {
|
||||
if ($errno !== E_USER_DEPRECATED && $errno !== E_DEPRECATED) {
|
||||
if ($this->errorHandler) {
|
||||
return \call_user_func($this->errorHandler, $errno, $errstr, $errfile, $errline);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ abstract class Folder
|
||||
*/
|
||||
public static function lastModifiedFolder($path)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$last_modified = 0;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
@@ -56,6 +60,10 @@ abstract class Folder
|
||||
*/
|
||||
public static function lastModifiedFile($path, $extensions = 'md|yaml')
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$last_modified = 0;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
@@ -92,21 +100,24 @@ abstract class Folder
|
||||
*/
|
||||
public static function hashAllFiles($path)
|
||||
{
|
||||
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;
|
||||
$files = [];
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$directory = $locator->getRecursiveIterator($path, $flags);
|
||||
} else {
|
||||
$directory = new \RecursiveDirectoryIterator($path, $flags);
|
||||
}
|
||||
if (file_exists($path)) {
|
||||
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$directory = $locator->getRecursiveIterator($path, $flags);
|
||||
} else {
|
||||
$directory = new \RecursiveDirectoryIterator($path, $flags);
|
||||
}
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = $file->getPathname() . '?'. $file->getMTime();
|
||||
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = $file->getPathname() . '?'. $file->getMTime();
|
||||
}
|
||||
}
|
||||
|
||||
return md5(serialize($files));
|
||||
@@ -199,6 +210,9 @@ abstract class Folder
|
||||
if ($path === false) {
|
||||
throw new \RuntimeException("Path doesn't exist.");
|
||||
}
|
||||
if (!file_exists($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$compare = isset($params['compare']) ? 'get' . $params['compare'] : null;
|
||||
$pattern = $params['pattern'] ?? null;
|
||||
@@ -235,7 +249,7 @@ abstract class Folder
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
// Ignore hidden files.
|
||||
if (strpos($file->getFilename(), '.') === 0) {
|
||||
if (strpos($file->getFilename(), '.') === 0 && $file->isFile()) {
|
||||
continue;
|
||||
}
|
||||
if (!$folders && $file->isDir()) {
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Common\GPM\Local;
|
||||
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\GPM\Common\Package as BasePackage;
|
||||
use Grav\Framework\Parsedown\Parsedown;
|
||||
|
||||
class Package extends BasePackage
|
||||
{
|
||||
@@ -23,7 +24,7 @@ class Package extends BasePackage
|
||||
|
||||
$this->settings = $package->toArray();
|
||||
|
||||
$html_description = \Parsedown::instance()->line($this->__get('description'));
|
||||
$html_description = Parsedown::instance()->line($this->__get('description'));
|
||||
$this->data->set('slug', $package->__get('slug'));
|
||||
$this->data->set('description_html', $html_description);
|
||||
$this->data->set('description_plain', strip_tags($html_description));
|
||||
|
||||
@@ -409,7 +409,7 @@ class Response
|
||||
} else {
|
||||
$code = (int)curl_getinfo($rch, CURLINFO_HTTP_CODE);
|
||||
if ($code === 301 || $code === 302 || $code === 303) {
|
||||
preg_match('/Location:(.*?)\n/', $header, $matches);
|
||||
preg_match('/(?:^|\n)Location:(.*?)\n/i', $header, $matches);
|
||||
$uri = trim(array_pop($matches));
|
||||
} else {
|
||||
$code = 0;
|
||||
|
||||
@@ -170,6 +170,29 @@ class Grav extends Container
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize CLI environment.
|
||||
*
|
||||
* Call after `$grav->setup($environment)`
|
||||
*
|
||||
* - Load configuration
|
||||
* - Disable debugger
|
||||
* - Set timezone, locale
|
||||
* - Load plugins
|
||||
* - Set Users type to be used in the site
|
||||
*
|
||||
* This method WILL NOT initialize assets, twig or pages.
|
||||
*
|
||||
* @param string|null $environment
|
||||
* @return $this
|
||||
*/
|
||||
public function initializeCli()
|
||||
{
|
||||
InitializeProcessor::initializeCli($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a request
|
||||
*/
|
||||
@@ -247,9 +270,21 @@ class Grav extends Container
|
||||
$collection = new RequestHandler($this->middleware, $default, $container);
|
||||
|
||||
$response = $collection->handle($this['request']);
|
||||
$body = $response->getBody();
|
||||
|
||||
// Handle ETag and If-None-Match headers.
|
||||
if ($response->getHeaderLine('ETag') === '1') {
|
||||
$etag = md5($body);
|
||||
$response = $response->withHeader('ETag', $etag);
|
||||
|
||||
if ($this['request']->getHeaderLine('If-None-Match') === $etag) {
|
||||
$response = $response->withStatus(304);
|
||||
$body = '';
|
||||
}
|
||||
}
|
||||
|
||||
$this->header($response);
|
||||
echo $response->getBody();
|
||||
echo $body;
|
||||
|
||||
$debugger->render();
|
||||
|
||||
@@ -281,7 +316,10 @@ class Grav extends Container
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
|
||||
//Check for code in route
|
||||
// Clean route for redirect
|
||||
$route = preg_replace("#^\/[\\\/]+\/#", '/', $route);
|
||||
|
||||
// Check for code in route
|
||||
$regex = '/.*(\[(30[1-7])\])$/';
|
||||
preg_match($regex, $route, $matches);
|
||||
if ($matches) {
|
||||
@@ -427,11 +465,16 @@ class Grav extends Container
|
||||
* Used to call closures.
|
||||
*
|
||||
* Source: http://stackoverflow.com/questions/419804/closures-as-class-members
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$closure = $this->{$method};
|
||||
\call_user_func_array($closure, $args);
|
||||
$closure = $this->{$method} ?? null;
|
||||
|
||||
return is_callable($closure) ? $closure(...$args) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -193,6 +193,8 @@ class Inflector
|
||||
$regex3 = preg_replace('/([0-9])([A-Z])/', '\1-\2', $regex2);
|
||||
$regex4 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex3);
|
||||
|
||||
$regex4 = trim($regex4, '-');
|
||||
|
||||
return strtolower($regex4);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Markdown\Excerpts;
|
||||
use Grav\Framework\Parsedown\Parsedown as ParsedownLib;
|
||||
|
||||
class Parsedown extends \Parsedown
|
||||
class Parsedown extends ParsedownLib
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Markdown\Excerpts;
|
||||
use Grav\Framework\Parsedown\ParsedownExtra as ParsedownExtraLib;
|
||||
|
||||
class ParsedownExtra extends \ParsedownExtra
|
||||
class ParsedownExtra extends ParsedownExtraLib
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
|
||||
@@ -125,5 +125,5 @@ trait MediaTrait
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getCacheKey();
|
||||
abstract protected function getCacheKey(): string;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class Excerpts
|
||||
);
|
||||
|
||||
// Valid attributes supported.
|
||||
$valid_attributes = ['rel', 'target', 'id', 'class', 'classes'];
|
||||
$valid_attributes = Grav::instance()['config']->get('system.pages.markdown.valid_link_attributes');
|
||||
|
||||
// Unless told to not process, go through actions.
|
||||
if (array_key_exists('noprocess', $actions)) {
|
||||
@@ -232,6 +232,7 @@ class Excerpts
|
||||
$url_parts = is_string($url) ? $this->parseUrl($url) : $url;
|
||||
$actions = [];
|
||||
|
||||
|
||||
// if there is a query, then parse it and build action calls
|
||||
if (isset($url_parts['query'])) {
|
||||
$actions = array_reduce(
|
||||
|
||||
@@ -516,6 +516,15 @@ class ImageMedium extends Medium
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle this commonly used variant
|
||||
*/
|
||||
public function cropZoom()
|
||||
{
|
||||
$this->__call('zoomCrop', func_get_args());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward the call to the image processing method.
|
||||
*
|
||||
@@ -525,10 +534,6 @@ class ImageMedium extends Medium
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if ($method === 'cropZoom') {
|
||||
$method = 'zoomCrop';
|
||||
}
|
||||
|
||||
if (!\in_array($method, self::$magic_actions, true)) {
|
||||
return parent::__call($method, $args);
|
||||
}
|
||||
|
||||
@@ -529,9 +529,9 @@ class Page implements PageInterface
|
||||
$headers['Last-Modified'] = $last_modified_date;
|
||||
}
|
||||
|
||||
// Calculate ETag based on the raw file
|
||||
// Ask Grav to calculate ETag from the final content.
|
||||
if ($this->eTag()) {
|
||||
$headers['ETag'] = '"' . md5($this->raw() . $this->modified()).'"';
|
||||
$headers['ETag'] = '1';
|
||||
}
|
||||
|
||||
// Set Vary: Accept-Encoding header
|
||||
@@ -608,12 +608,12 @@ class Page implements PageInterface
|
||||
return $content;
|
||||
}
|
||||
|
||||
return mb_strimwidth($content, 0, $size, '...', 'utf-8');
|
||||
return mb_strimwidth($content, 0, $size, '…', 'UTF-8');
|
||||
}
|
||||
|
||||
$summary = Utils::truncateHtml($content, $size);
|
||||
|
||||
return html_entity_decode($summary);
|
||||
return html_entity_decode($summary, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -659,7 +659,7 @@ class Page implements PageInterface
|
||||
// Load cached content
|
||||
/** @var Cache $cache */
|
||||
$cache = Grav::instance()['cache'];
|
||||
$cache_id = md5('page' . $this->id());
|
||||
$cache_id = md5('page' . $this->getCacheKey());
|
||||
$content_obj = $cache->fetch($cache_id);
|
||||
|
||||
if (is_array($content_obj)) {
|
||||
@@ -865,7 +865,7 @@ class Page implements PageInterface
|
||||
public function cachePageContent()
|
||||
{
|
||||
$cache = Grav::instance()['cache'];
|
||||
$cache_id = md5('page' . $this->id());
|
||||
$cache_id = md5('page' . $this->getCacheKey());
|
||||
$cache->save($cache_id, ['content' => $this->content, 'content_meta' => $this->content_meta]);
|
||||
}
|
||||
|
||||
@@ -1200,7 +1200,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey()
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
return $this->id();
|
||||
}
|
||||
@@ -1694,9 +1694,9 @@ class Page implements PageInterface
|
||||
$metadata['generator'] = 'GravCMS';
|
||||
|
||||
// Get initial metadata for the page
|
||||
$metadata = array_merge($metadata, Grav::instance()['config']->get('site.metadata'));
|
||||
$metadata = array_merge($metadata, Grav::instance()['config']->get('site.metadata', []));
|
||||
|
||||
if (isset($this->header->metadata)) {
|
||||
if (isset($this->header->metadata) && is_array($this->header->metadata)) {
|
||||
// Merge any site.metadata settings in with page metadata
|
||||
$metadata = array_merge($metadata, $this->header->metadata);
|
||||
}
|
||||
@@ -2009,6 +2009,10 @@ class Page implements PageInterface
|
||||
*/
|
||||
public function id($var = null)
|
||||
{
|
||||
if (null === $this->id) {
|
||||
// We need to set unique id to avoid potential cache conflicts between pages.
|
||||
$var = time() . md5($this->filePath());
|
||||
}
|
||||
if ($var !== null) {
|
||||
// store unique per language
|
||||
$active_lang = Grav::instance()['language']->getLanguage() ?: '';
|
||||
@@ -2824,7 +2828,7 @@ class Page implements PageInterface
|
||||
if ($pagination) {
|
||||
$params = $collection->params();
|
||||
|
||||
$limit = $params['limit'] ?? 0;
|
||||
$limit = (int)($params['limit'] ?? 0);
|
||||
$start = !empty($params['pagination']) ? ($uri->currentPage() - 1) * $limit : 0;
|
||||
|
||||
if ($limit && $collection->count() > $limit) {
|
||||
|
||||
@@ -95,6 +95,8 @@ class Pages
|
||||
|
||||
protected $initialized = false;
|
||||
|
||||
protected $active_lang;
|
||||
|
||||
/**
|
||||
* @var Types
|
||||
*/
|
||||
@@ -143,7 +145,7 @@ class Pages
|
||||
*/
|
||||
public function baseRoute($lang = null)
|
||||
{
|
||||
$key = $lang ?: 'default';
|
||||
$key = $lang ?: $this->active_lang ?: 'default';
|
||||
|
||||
if (!isset($this->baseRoute[$key])) {
|
||||
/** @var Language $language */
|
||||
@@ -236,6 +238,16 @@ class Pages
|
||||
$this->check_method = strtolower($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset pages (used in search indexing etc).
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->initialized = false;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class initialization. Must be called before using this class.
|
||||
*/
|
||||
@@ -958,6 +970,9 @@ class Pages
|
||||
|
||||
$pages_dir = $locator->findResource('page://');
|
||||
|
||||
// Set active language
|
||||
$this->active_lang = $language->getActive();
|
||||
|
||||
if ($config->get('system.cache.enabled')) {
|
||||
/** @var Cache $cache */
|
||||
$cache = $this->grav['cache'];
|
||||
@@ -982,17 +997,19 @@ class Pages
|
||||
|
||||
$this->pages_cache_id = md5($pages_dir . $hash . $language->getActive() . $config->checksum());
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($this->pages_cache_id);
|
||||
if (!$this->instances) {
|
||||
$cached = $cache->fetch($this->pages_cache_id);
|
||||
if ($cached) {
|
||||
$this->grav['debugger']->addMessage('Page cache hit.');
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cached;
|
||||
|
||||
// If pages was found in cache, set the taxonomy
|
||||
$taxonomy->taxonomy($taxonomy_map);
|
||||
} else {
|
||||
$this->grav['debugger']->addMessage('Page cache missed, rebuilding pages..');
|
||||
|
||||
// recurse pages and cache result
|
||||
$this->resetPages($pages_dir);
|
||||
|
||||
} else {
|
||||
// If pages was found in cache, set the taxonomy
|
||||
$this->grav['debugger']->addMessage('Page cache hit.');
|
||||
$taxonomy->taxonomy($taxonomy_map);
|
||||
}
|
||||
} else {
|
||||
$this->recurse($pages_dir);
|
||||
@@ -1261,14 +1278,13 @@ class Pages
|
||||
{
|
||||
$list = [];
|
||||
$header_default = null;
|
||||
$header_query = null;
|
||||
$header_query = [];
|
||||
|
||||
// do this header query work only once
|
||||
if (strpos($order_by, 'header.') === 0) {
|
||||
$header_query = explode('|', str_replace('header.', '', $order_by));
|
||||
if (isset($header_query[1])) {
|
||||
$header_default = $header_query[1];
|
||||
}
|
||||
$query = explode('|', str_replace('header.', '', $order_by), 2);
|
||||
$header_query = array_shift($query) ?? '';
|
||||
$header_default = array_shift($query);
|
||||
}
|
||||
|
||||
foreach ($pages as $key => $info) {
|
||||
@@ -1306,11 +1322,17 @@ class Pages
|
||||
case 'folder':
|
||||
$list[$key] = $child->folder();
|
||||
break;
|
||||
case (is_string($header_query[0])):
|
||||
$child_header = new Header((array)$child->header());
|
||||
$header_value = $child_header->get($header_query[0]);
|
||||
case 'manual':
|
||||
case 'default':
|
||||
default:
|
||||
if (is_string($header_query)) {
|
||||
$child_header = $child->header();
|
||||
if (!$child_header instanceof Header) {
|
||||
$child_header = new Header((array)$child_header);
|
||||
}
|
||||
$header_value = $child_header->get($header_query);
|
||||
if (is_array($header_value)) {
|
||||
$list[$key] = implode(',',$header_value);
|
||||
$list[$key] = implode(',', $header_value);
|
||||
} elseif ($header_value) {
|
||||
$list[$key] = $header_value;
|
||||
} else {
|
||||
@@ -1318,11 +1340,9 @@ class Pages
|
||||
}
|
||||
$sort_flags = $sort_flags ?: SORT_REGULAR;
|
||||
break;
|
||||
case 'manual':
|
||||
case 'default':
|
||||
default:
|
||||
$list[$key] = $key;
|
||||
$sort_flags = $sort_flags ?: SORT_REGULAR;
|
||||
}
|
||||
$list[$key] = $key;
|
||||
$sort_flags = $sort_flags ?: SORT_REGULAR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
|
||||
// Create new config object and set it on the page object so it's cached for next time
|
||||
$page->modifyHeader($class_name_merged, new Data($header));
|
||||
} else if (isset($page_header->{$class_name_merged})) {
|
||||
} elseif (isset($page_header->{$class_name_merged})) {
|
||||
$merged = $page_header->{$class_name_merged};
|
||||
$header = $merged->toArray();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
namespace Grav\Common\Processors;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Session\Exceptions\SessionException;
|
||||
@@ -22,6 +23,22 @@ class InitializeProcessor extends ProcessorBase
|
||||
public $id = 'init';
|
||||
public $title = 'Initialize';
|
||||
|
||||
/** @var bool */
|
||||
private static $cli_initialized = false;
|
||||
|
||||
/**
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public static function initializeCli(Grav $grav)
|
||||
{
|
||||
if (!static::$cli_initialized) {
|
||||
static::$cli_initialized = true;
|
||||
|
||||
$instance = new static($grav);
|
||||
$instance->processCli();
|
||||
}
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
|
||||
{
|
||||
$this->startTimer();
|
||||
@@ -77,4 +94,35 @@ class InitializeProcessor extends ProcessorBase
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
public function processCli(): void
|
||||
{
|
||||
// Load configuration.
|
||||
$this->container['config']->init();
|
||||
$this->container['plugins']->setup();
|
||||
|
||||
// Disable debugger.
|
||||
$this->container['debugger']->enabled(false);
|
||||
|
||||
// Set timezone, locale.
|
||||
/** @var Config $config */
|
||||
$config = $this->container['config'];
|
||||
$timezone = $config->get('system.timezone');
|
||||
if ($timezone) {
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
$this->container->setLocale();
|
||||
|
||||
// Load plugins.
|
||||
$this->container['plugins']->init();
|
||||
|
||||
// Initialize URI.
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->container['uri'];
|
||||
$uri->init();
|
||||
|
||||
// Load accounts.
|
||||
// TODO: remove in 2.0.
|
||||
$this->container['accounts'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class Cron
|
||||
'name_year' => 'année',
|
||||
'text_period' => 'Chaque %s',
|
||||
'text_mins' => 'à %s minutes',
|
||||
'text_time' => 'à %s:%s',
|
||||
'text_time' => 'à %02s:%02s',
|
||||
'text_dow' => 'le %s',
|
||||
'text_month' => 'de %s',
|
||||
'text_dom' => 'le %s',
|
||||
@@ -86,7 +86,7 @@ class Cron
|
||||
'name_year' => 'year',
|
||||
'text_period' => 'Every %s',
|
||||
'text_mins' => 'at %s minutes past the hour',
|
||||
'text_time' => 'at %s:%s',
|
||||
'text_time' => 'at %02s:%02s',
|
||||
'text_dow' => 'on %s',
|
||||
'text_month' => 'of %s',
|
||||
'text_dom' => 'on the %s',
|
||||
|
||||
@@ -26,6 +26,19 @@ class PagesServiceProvider implements ServiceProviderInterface
|
||||
return new Pages($c);
|
||||
};
|
||||
|
||||
if (\defined('GRAV_CLI')) {
|
||||
$container['page'] = static function ($c) {
|
||||
$path = $c['locator']->findResource('system://pages/notfound.md');
|
||||
$page = new Page();
|
||||
$page->init(new \SplFileInfo($path));
|
||||
$page->routable(false);
|
||||
|
||||
return $page;
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$container['page'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
|
||||
|
||||
@@ -1055,7 +1055,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
*/
|
||||
public function jsonDecodeFilter($str, $assoc = false, $depth = 512, $options = 0)
|
||||
{
|
||||
return json_decode(html_entity_decode($str), $assoc, $depth, $options);
|
||||
return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML401, 'UTF-8'), $assoc, $depth, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,7 +151,7 @@ class Uri
|
||||
|
||||
$this->url = $this->base . $this->uri;
|
||||
|
||||
$uri = str_replace(static::filterPath($this->root), '', $this->url);
|
||||
$uri = Utils::replaceFirstOccurrence(static::filterPath($this->root), '', $this->url);
|
||||
|
||||
// remove the setup.php based base if set:
|
||||
$setup_base = $grav['pages']->base();
|
||||
@@ -195,7 +195,7 @@ class Uri
|
||||
// set the new url
|
||||
$this->url = $this->root . $path;
|
||||
$this->path = static::cleanPath($path);
|
||||
$this->content_path = trim(str_replace($this->base, '', $this->path), '/');
|
||||
$this->content_path = trim(Utils::replaceFirstOccurrence($this->base, '', $this->path), '/');
|
||||
if ($this->content_path !== '') {
|
||||
$this->paths = explode('/', $this->content_path);
|
||||
}
|
||||
@@ -306,7 +306,7 @@ class Uri
|
||||
public function param($id)
|
||||
{
|
||||
if (isset($this->params[$id])) {
|
||||
return html_entity_decode(rawurldecode($this->params[$id]));
|
||||
return html_entity_decode(rawurldecode($this->params[$id]), ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -340,7 +340,7 @@ class Uri
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
$url = str_replace($this->base, '', rtrim($this->url, '/'));
|
||||
$url = Utils::replaceFirstOccurrence($this->base, '', rtrim($this->url, '/'));
|
||||
|
||||
return $url ?: '/';
|
||||
}
|
||||
@@ -489,7 +489,7 @@ class Uri
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
return str_replace($this->root_path, '', $this->uri);
|
||||
return Utils::replaceFirstOccurrence($this->root_path, '', $this->uri);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -531,7 +531,7 @@ class Uri
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
return str_replace($this->base, '', $this->root);
|
||||
return Utils::replaceFirstOccurrence($this->base, '', $this->root);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,7 +541,9 @@ class Uri
|
||||
*/
|
||||
public function currentPage()
|
||||
{
|
||||
return $this->params['page'] ?? 1;
|
||||
$page = (int)($this->params['page'] ?? 1);
|
||||
|
||||
return max(1, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -629,9 +631,9 @@ class Uri
|
||||
{
|
||||
if (getenv('HTTP_CLIENT_IP')) {
|
||||
$ip = getenv('HTTP_CLIENT_IP');
|
||||
} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
|
||||
} elseif (getenv('HTTP_X_FORWARDED_FOR') && Grav::instance()['config']->get('system.http_x_forwarded.ip')) {
|
||||
$ip = getenv('HTTP_X_FORWARDED_FOR');
|
||||
} elseif (getenv('HTTP_X_FORWARDED')) {
|
||||
} elseif (getenv('HTTP_X_FORWARDED') && Grav::instance()['config']->get('system.http_x_forwarded.ip')) {
|
||||
$ip = getenv('HTTP_X_FORWARDED');
|
||||
} elseif (getenv('HTTP_FORWARDED_FOR')) {
|
||||
$ip = getenv('HTTP_FORWARDED_FOR');
|
||||
@@ -783,7 +785,7 @@ class Uri
|
||||
}
|
||||
|
||||
// special check to see if path checking is required.
|
||||
$just_path = str_replace($normalized_url, '', $normalized_path);
|
||||
$just_path = Utils::replaceFirstOccurrence($normalized_url, '', $normalized_path);
|
||||
if ($normalized_url === '/' || $just_path === $page->path()) {
|
||||
$url_path = $normalized_url;
|
||||
} else {
|
||||
@@ -852,7 +854,7 @@ class Uri
|
||||
}
|
||||
|
||||
// strip base from this path
|
||||
$target_path = str_replace($uri->rootUrl(), '', $target_path);
|
||||
$target_path = Utils::replaceFirstOccurrence($uri->rootUrl(), '', $target_path);
|
||||
|
||||
// set to / if root
|
||||
if (empty($target_path)) {
|
||||
@@ -877,7 +879,7 @@ class Uri
|
||||
|
||||
// Handle route only
|
||||
if ($route_only) {
|
||||
$url_path = str_replace(static::filterPath($base_url), '', $url_path);
|
||||
$url_path = Utils::replaceFirstOccurrence(static::filterPath($base_url), '', $url_path);
|
||||
}
|
||||
|
||||
// transform back to string/array as needed
|
||||
@@ -998,7 +1000,7 @@ class Uri
|
||||
}
|
||||
|
||||
// special check to see if path checking is required.
|
||||
$just_path = str_replace($normalized_url, '', $normalized_path);
|
||||
$just_path = Utils::replaceFirstOccurrence($normalized_url, '', $normalized_path);
|
||||
if ($just_path === $page->path()) {
|
||||
return $normalized_url;
|
||||
}
|
||||
@@ -1148,7 +1150,7 @@ class Uri
|
||||
protected function createFromEnvironment(array $env)
|
||||
{
|
||||
// Build scheme.
|
||||
if (isset($env['HTTP_X_FORWARDED_PROTO'])) {
|
||||
if (isset($env['HTTP_X_FORWARDED_PROTO']) && Grav::instance()['config']->get('system.http_x_forwarded.protocol')) {
|
||||
$this->scheme = $env['HTTP_X_FORWARDED_PROTO'];
|
||||
} elseif (isset($env['X-FORWARDED-PROTO'])) {
|
||||
$this->scheme = $env['X-FORWARDED-PROTO'];
|
||||
@@ -1166,11 +1168,14 @@ class Uri
|
||||
$this->password = $env['PHP_AUTH_PW'] ?? null;
|
||||
|
||||
// Build host.
|
||||
$hostname = 'localhost';
|
||||
if (isset($env['HTTP_HOST'])) {
|
||||
if (isset($env['HTTP_X_FORWARDED_HOST']) && Grav::instance()['config']->get('system.http_x_forwarded.host')) {
|
||||
$hostname = $env['HTTP_X_FORWARDED_HOST'];
|
||||
} else if (isset($env['HTTP_HOST'])) {
|
||||
$hostname = $env['HTTP_HOST'];
|
||||
} elseif (isset($env['SERVER_NAME'])) {
|
||||
$hostname = $env['SERVER_NAME'];
|
||||
} else {
|
||||
$hostname = 'localhost';
|
||||
}
|
||||
// Remove port from HTTP_HOST generated $hostname
|
||||
$hostname = Utils::substrToString($hostname, ':');
|
||||
@@ -1178,7 +1183,7 @@ class Uri
|
||||
$this->host = $this->validateHostname($hostname) ? $hostname : 'unknown';
|
||||
|
||||
// Build port.
|
||||
if (isset($env['HTTP_X_FORWARDED_PORT'])) {
|
||||
if (isset($env['HTTP_X_FORWARDED_PORT']) && Grav::instance()['config']->get('system.http_x_forwarded.port')) {
|
||||
$this->port = (int)$env['HTTP_X_FORWARDED_PORT'];
|
||||
} elseif (isset($env['X-FORWARDED-PORT'])) {
|
||||
$this->port = (int)$env['X-FORWARDED-PORT'];
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
namespace Grav\Console;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Processors\InitializeProcessor;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
@@ -18,6 +22,13 @@ class ConsoleCommand extends Command
|
||||
{
|
||||
use ConsoleTrait;
|
||||
|
||||
/** @var bool */
|
||||
private $plugins_initialized = false;
|
||||
/** @var bool */
|
||||
private $themes_initialized = false;
|
||||
/** @var bool */
|
||||
private $pages_initialized = false;
|
||||
|
||||
/**
|
||||
* @param InputInterface $input
|
||||
* @param OutputInterface $output
|
||||
@@ -31,12 +42,140 @@ class ConsoleCommand extends Command
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Override with your implementation.
|
||||
*/
|
||||
protected function serve()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Grav.
|
||||
*
|
||||
* - Load configuration
|
||||
* - Disable debugger
|
||||
* - Set timezone, locale
|
||||
* - Load plugins
|
||||
* - Set Users type to be used in the site
|
||||
*
|
||||
* Safe to be called multiple times.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function initializeGrav()
|
||||
{
|
||||
InitializeProcessor::initializeCli(Grav::instance());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set language to be used in CLI.
|
||||
*
|
||||
* @param string|null $code
|
||||
*/
|
||||
final protected function setLanguage(string $code = null)
|
||||
{
|
||||
$this->initializeGrav();
|
||||
|
||||
$grav = Grav::instance();
|
||||
/** @var Language $language */
|
||||
$language = $grav['language'];
|
||||
if ($language->enabled()) {
|
||||
if ($code && $language->validate($code)) {
|
||||
$language->setActive($code);
|
||||
} else {
|
||||
$language->setActive($language->getDefault());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Properly initialize plugins.
|
||||
*
|
||||
* - call $this->initializeGrav()
|
||||
* - call onPluginsInitialized event
|
||||
*
|
||||
* Safe to be called multiple times.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function initializePlugins()
|
||||
{
|
||||
if (!$this->plugins_initialized) {
|
||||
$this->plugins_initialized = true;
|
||||
|
||||
$this->initializeGrav();
|
||||
|
||||
// Initialize plugins.
|
||||
$grav = Grav::instance();
|
||||
$grav->fireEvent('onPluginsInitialized');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Properly initialize themes.
|
||||
*
|
||||
* - call $this->initializePlugins()
|
||||
* - initialize theme (call onThemeInitialized event)
|
||||
*
|
||||
* Safe to be called multiple times.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function initializeThemes()
|
||||
{
|
||||
if (!$this->themes_initialized) {
|
||||
$this->themes_initialized = true;
|
||||
|
||||
$this->initializePlugins();
|
||||
|
||||
// Initialize themes.
|
||||
$grav = Grav::instance();
|
||||
$grav['themes']->init();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Properly initialize pages.
|
||||
*
|
||||
* - call $this->initializeThemes()
|
||||
* - initialize assets (call onAssetsInitialized event)
|
||||
* - initialize twig (calls the twig events)
|
||||
* - initialize pages (calls onPagesInitialized event)
|
||||
*
|
||||
* Safe to be called multiple times.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function initializePages()
|
||||
{
|
||||
if (!$this->pages_initialized) {
|
||||
$this->pages_initialized = true;
|
||||
|
||||
$this->initializeThemes();
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
// Initialize assets.
|
||||
$grav['assets']->init();
|
||||
$grav->fireEvent('onAssetsInitialized');
|
||||
|
||||
// Initialize twig.
|
||||
$grav['twig']->init();
|
||||
|
||||
// Initialize pages.
|
||||
$pages = $grav['pages'];
|
||||
$pages->init();
|
||||
$grav->fireEvent('onPagesInitialized', new Event(['pages' => $pages]));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function displayGPMRelease()
|
||||
{
|
||||
$this->output->writeln('');
|
||||
|
||||
@@ -177,7 +177,7 @@ class SelfupgradeCommand extends ConsoleCommand
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Package $package
|
||||
* @param array $package
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -79,10 +79,28 @@ class CsvFormatter extends AbstractFormatter
|
||||
// Get the field names
|
||||
$header = str_getcsv(array_shift($lines), $delimiter);
|
||||
|
||||
// Allow for replacing a null string with null/empty value
|
||||
$null_replace = $this->getConfig('null');
|
||||
|
||||
// Get the data
|
||||
$list = [];
|
||||
foreach ($lines as $line) {
|
||||
$list[] = array_combine($header, str_getcsv($line, $delimiter));
|
||||
$line = null;
|
||||
try {
|
||||
foreach ($lines as $line) {
|
||||
if (!empty($line)) {
|
||||
$csv_line = str_getcsv($line, $delimiter);
|
||||
|
||||
if ($null_replace) {
|
||||
array_walk($csv_line, function(&$el) use ($null_replace) {
|
||||
$el = str_replace($null_replace, "\0", $el);
|
||||
});
|
||||
}
|
||||
|
||||
$list[] = array_combine($header, $csv_line);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception('Badly formatted CSV line: ' . $line);
|
||||
}
|
||||
|
||||
return $list;
|
||||
|
||||
@@ -342,5 +342,5 @@ trait FlexMediaTrait
|
||||
|
||||
abstract public function getFlexDirectory(): FlexDirectory;
|
||||
|
||||
abstract public function getStorageKey();
|
||||
abstract public function getStorageKey(): string;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,532 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Framework\Parsedown
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Framework\Parsedown;
|
||||
|
||||
/*
|
||||
* Parsedown Extra
|
||||
* http://parsedown.org
|
||||
*
|
||||
* (c) Emanuil Rusev
|
||||
* http://erusev.com
|
||||
*
|
||||
* This file ported from officiall ParsedownExtra repo and kept for compatibility.
|
||||
*/
|
||||
|
||||
class ParsedownExtra extends Parsedown
|
||||
{
|
||||
# ~
|
||||
|
||||
const version = '0.7.0';
|
||||
|
||||
# ~
|
||||
|
||||
function __construct()
|
||||
{
|
||||
if (parent::version < '1.5.0')
|
||||
{
|
||||
throw new Exception('ParsedownExtra requires a later version of Parsedown');
|
||||
}
|
||||
|
||||
$this->BlockTypes[':'] []= 'DefinitionList';
|
||||
$this->BlockTypes['*'] []= 'Abbreviation';
|
||||
|
||||
# identify footnote definitions before reference definitions
|
||||
array_unshift($this->BlockTypes['['], 'Footnote');
|
||||
|
||||
# identify footnote markers before before links
|
||||
array_unshift($this->InlineTypes['['], 'FootnoteMarker');
|
||||
}
|
||||
|
||||
#
|
||||
# ~
|
||||
|
||||
function text($text)
|
||||
{
|
||||
$markup = parent::text($text);
|
||||
|
||||
# merge consecutive dl elements
|
||||
|
||||
$markup = preg_replace('/<\/dl>\s+<dl>\s+/', '', $markup);
|
||||
|
||||
# add footnotes
|
||||
|
||||
if (isset($this->DefinitionData['Footnote']))
|
||||
{
|
||||
$Element = $this->buildFootnoteElement();
|
||||
|
||||
$markup .= "\n" . $this->element($Element);
|
||||
}
|
||||
|
||||
return $markup;
|
||||
}
|
||||
|
||||
#
|
||||
# Blocks
|
||||
#
|
||||
|
||||
#
|
||||
# Abbreviation
|
||||
|
||||
protected function blockAbbreviation($Line)
|
||||
{
|
||||
if (preg_match('/^\*\[(.+?)\]:[ ]*(.+?)[ ]*$/', $Line['text'], $matches))
|
||||
{
|
||||
$this->DefinitionData['Abbreviation'][$matches[1]] = $matches[2];
|
||||
|
||||
$Block = array(
|
||||
'hidden' => true,
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Footnote
|
||||
|
||||
protected function blockFootnote($Line)
|
||||
{
|
||||
if (preg_match('/^\[\^(.+?)\]:[ ]?(.*)$/', $Line['text'], $matches))
|
||||
{
|
||||
$Block = array(
|
||||
'label' => $matches[1],
|
||||
'text' => $matches[2],
|
||||
'hidden' => true,
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function blockFootnoteContinue($Line, $Block)
|
||||
{
|
||||
if ($Line['text'][0] === '[' and preg_match('/^\[\^(.+?)\]:/', $Line['text']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($Block['interrupted']))
|
||||
{
|
||||
if ($Line['indent'] >= 4)
|
||||
{
|
||||
$Block['text'] .= "\n\n" . $Line['text'];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$Block['text'] .= "\n" . $Line['text'];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function blockFootnoteComplete($Block)
|
||||
{
|
||||
$this->DefinitionData['Footnote'][$Block['label']] = array(
|
||||
'text' => $Block['text'],
|
||||
'count' => null,
|
||||
'number' => null,
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Definition List
|
||||
|
||||
protected function blockDefinitionList($Line, $Block)
|
||||
{
|
||||
if ( ! isset($Block) or isset($Block['type']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$Element = array(
|
||||
'name' => 'dl',
|
||||
'handler' => 'elements',
|
||||
'text' => array(),
|
||||
);
|
||||
|
||||
$terms = explode("\n", $Block['element']['text']);
|
||||
|
||||
foreach ($terms as $term)
|
||||
{
|
||||
$Element['text'] []= array(
|
||||
'name' => 'dt',
|
||||
'handler' => 'line',
|
||||
'text' => $term,
|
||||
);
|
||||
}
|
||||
|
||||
$Block['element'] = $Element;
|
||||
|
||||
$Block = $this->addDdElement($Line, $Block);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
protected function blockDefinitionListContinue($Line, array $Block)
|
||||
{
|
||||
if ($Line['text'][0] === ':')
|
||||
{
|
||||
$Block = $this->addDdElement($Line, $Block);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($Block['interrupted']) and $Line['indent'] === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($Block['interrupted']))
|
||||
{
|
||||
$Block['dd']['handler'] = 'text';
|
||||
$Block['dd']['text'] .= "\n\n";
|
||||
|
||||
unset($Block['interrupted']);
|
||||
}
|
||||
|
||||
$text = substr($Line['body'], min($Line['indent'], 4));
|
||||
|
||||
$Block['dd']['text'] .= "\n" . $text;
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Header
|
||||
|
||||
protected function blockHeader($Line)
|
||||
{
|
||||
$Block = parent::blockHeader($Line);
|
||||
|
||||
if ($Block !== null && preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$attributeString = $matches[1][0];
|
||||
|
||||
$Block['element']['attributes'] = $this->parseAttributeData($attributeString);
|
||||
|
||||
$Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
|
||||
}
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Markup
|
||||
|
||||
protected function blockMarkupComplete($Block)
|
||||
{
|
||||
if ( ! isset($Block['void']))
|
||||
{
|
||||
$Block['markup'] = $this->processTag($Block['markup']);
|
||||
}
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Setext
|
||||
|
||||
protected function blockSetextHeader($Line, array $Block = null)
|
||||
{
|
||||
$Block = parent::blockSetextHeader($Line, $Block);
|
||||
|
||||
if ($Block !== null && preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$attributeString = $matches[1][0];
|
||||
|
||||
$Block['element']['attributes'] = $this->parseAttributeData($attributeString);
|
||||
|
||||
$Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
|
||||
}
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Inline Elements
|
||||
#
|
||||
|
||||
#
|
||||
# Footnote Marker
|
||||
|
||||
protected function inlineFootnoteMarker($Excerpt)
|
||||
{
|
||||
if (preg_match('/^\[\^(.+?)\]/', $Excerpt['text'], $matches))
|
||||
{
|
||||
$name = $matches[1];
|
||||
|
||||
if ( ! isset($this->DefinitionData['Footnote'][$name]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->DefinitionData['Footnote'][$name]['count'] ++;
|
||||
|
||||
if ( ! isset($this->DefinitionData['Footnote'][$name]['number']))
|
||||
{
|
||||
$this->DefinitionData['Footnote'][$name]['number'] = ++ $this->footnoteCount; # » &
|
||||
}
|
||||
|
||||
$Element = array(
|
||||
'name' => 'sup',
|
||||
'attributes' => array('id' => 'fnref'.$this->DefinitionData['Footnote'][$name]['count'].':'.$name),
|
||||
'handler' => 'element',
|
||||
'text' => array(
|
||||
'name' => 'a',
|
||||
'attributes' => array('href' => '#fn:'.$name, 'class' => 'footnote-ref'),
|
||||
'text' => $this->DefinitionData['Footnote'][$name]['number'],
|
||||
),
|
||||
);
|
||||
|
||||
return array(
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => $Element,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private $footnoteCount = 0;
|
||||
|
||||
#
|
||||
# Link
|
||||
|
||||
protected function inlineLink($Excerpt)
|
||||
{
|
||||
$Link = parent::inlineLink($Excerpt);
|
||||
|
||||
$remainder = $Link !== null ? substr($Excerpt['text'], $Link['extent']) : '';
|
||||
|
||||
if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches))
|
||||
{
|
||||
$Link['element']['attributes'] += $this->parseAttributeData($matches[1]);
|
||||
|
||||
$Link['extent'] += strlen($matches[0]);
|
||||
}
|
||||
|
||||
return $Link;
|
||||
}
|
||||
|
||||
#
|
||||
# ~
|
||||
#
|
||||
|
||||
protected function unmarkedText($text)
|
||||
{
|
||||
$text = parent::unmarkedText($text);
|
||||
|
||||
if (isset($this->DefinitionData['Abbreviation']))
|
||||
{
|
||||
foreach ($this->DefinitionData['Abbreviation'] as $abbreviation => $meaning)
|
||||
{
|
||||
$pattern = '/\b'.preg_quote($abbreviation, '/').'\b/';
|
||||
|
||||
$text = preg_replace($pattern, '<abbr title="'.$meaning.'">'.$abbreviation.'</abbr>', $text);
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
#
|
||||
# Util Methods
|
||||
#
|
||||
|
||||
protected function addDdElement(array $Line, array $Block)
|
||||
{
|
||||
$text = substr($Line['text'], 1);
|
||||
$text = trim($text);
|
||||
|
||||
unset($Block['dd']);
|
||||
|
||||
$Block['dd'] = array(
|
||||
'name' => 'dd',
|
||||
'handler' => 'line',
|
||||
'text' => $text,
|
||||
);
|
||||
|
||||
if (isset($Block['interrupted']))
|
||||
{
|
||||
$Block['dd']['handler'] = 'text';
|
||||
|
||||
unset($Block['interrupted']);
|
||||
}
|
||||
|
||||
$Block['element']['text'] []= & $Block['dd'];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
protected function buildFootnoteElement()
|
||||
{
|
||||
$Element = array(
|
||||
'name' => 'div',
|
||||
'attributes' => array('class' => 'footnotes'),
|
||||
'handler' => 'elements',
|
||||
'text' => array(
|
||||
array(
|
||||
'name' => 'hr',
|
||||
),
|
||||
array(
|
||||
'name' => 'ol',
|
||||
'handler' => 'elements',
|
||||
'text' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
uasort($this->DefinitionData['Footnote'], 'self::sortFootnotes');
|
||||
|
||||
foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData)
|
||||
{
|
||||
if ( ! isset($DefinitionData['number']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$text = $DefinitionData['text'];
|
||||
|
||||
$text = parent::text($text);
|
||||
|
||||
$numbers = range(1, $DefinitionData['count']);
|
||||
|
||||
$backLinksMarkup = '';
|
||||
|
||||
foreach ($numbers as $number)
|
||||
{
|
||||
$backLinksMarkup .= ' <a href="#fnref'.$number.':'.$definitionId.'" rev="footnote" class="footnote-backref">↩</a>';
|
||||
}
|
||||
|
||||
$backLinksMarkup = substr($backLinksMarkup, 1);
|
||||
|
||||
if (substr($text, - 4) === '</p>')
|
||||
{
|
||||
$backLinksMarkup = ' '.$backLinksMarkup;
|
||||
|
||||
$text = substr_replace($text, $backLinksMarkup.'</p>', - 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= "\n".'<p>'.$backLinksMarkup.'</p>';
|
||||
}
|
||||
|
||||
$Element['text'][1]['text'] []= array(
|
||||
'name' => 'li',
|
||||
'attributes' => array('id' => 'fn:'.$definitionId),
|
||||
'text' => "\n".$text."\n",
|
||||
);
|
||||
}
|
||||
|
||||
return $Element;
|
||||
}
|
||||
|
||||
# ~
|
||||
|
||||
protected function parseAttributeData($attributeString)
|
||||
{
|
||||
$Data = array();
|
||||
|
||||
$attributes = preg_split('/[ ]+/', $attributeString, - 1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
foreach ($attributes as $attribute)
|
||||
{
|
||||
if ($attribute[0] === '#')
|
||||
{
|
||||
$Data['id'] = substr($attribute, 1);
|
||||
}
|
||||
else # "."
|
||||
{
|
||||
$classes []= substr($attribute, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($classes))
|
||||
{
|
||||
$Data['class'] = implode(' ', $classes);
|
||||
}
|
||||
|
||||
return $Data;
|
||||
}
|
||||
|
||||
# ~
|
||||
|
||||
protected function processTag($elementMarkup) # recursive
|
||||
{
|
||||
# http://stackoverflow.com/q/1148928/200145
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
$DOMDocument = new \DOMDocument;
|
||||
|
||||
# http://stackoverflow.com/q/11309194/200145
|
||||
$elementMarkup = mb_convert_encoding($elementMarkup, 'HTML-ENTITIES', 'UTF-8');
|
||||
|
||||
# http://stackoverflow.com/q/4879946/200145
|
||||
$DOMDocument->loadHTML($elementMarkup);
|
||||
$DOMDocument->removeChild($DOMDocument->doctype);
|
||||
$DOMDocument->replaceChild($DOMDocument->firstChild->firstChild->firstChild, $DOMDocument->firstChild);
|
||||
|
||||
$elementText = '';
|
||||
|
||||
if ($DOMDocument->documentElement->getAttribute('markdown') === '1')
|
||||
{
|
||||
foreach ($DOMDocument->documentElement->childNodes as $Node)
|
||||
{
|
||||
$elementText .= $DOMDocument->saveHTML($Node);
|
||||
}
|
||||
|
||||
$DOMDocument->documentElement->removeAttribute('markdown');
|
||||
|
||||
$elementText = "\n".$this->text($elementText)."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($DOMDocument->documentElement->childNodes as $Node)
|
||||
{
|
||||
$nodeMarkup = $DOMDocument->saveHTML($Node);
|
||||
|
||||
if ($Node instanceof \DOMElement and ! in_array($Node->nodeName, $this->textLevelElements))
|
||||
{
|
||||
$elementText .= $this->processTag($nodeMarkup);
|
||||
}
|
||||
else
|
||||
{
|
||||
$elementText .= $nodeMarkup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# because we don't want for markup to get encoded
|
||||
$DOMDocument->documentElement->nodeValue = 'placeholder\x1A';
|
||||
|
||||
$markup = $DOMDocument->saveHTML($DOMDocument->documentElement);
|
||||
$markup = str_replace('placeholder\x1A', $elementText, $markup);
|
||||
|
||||
return $markup;
|
||||
}
|
||||
|
||||
# ~
|
||||
|
||||
protected function sortFootnotes($A, $B) # callback
|
||||
{
|
||||
return $A['number'] - $B['number'];
|
||||
}
|
||||
|
||||
#
|
||||
# Fields
|
||||
#
|
||||
|
||||
protected $regexAttribute = '(?:[#.][-\w]+[ ]*)';
|
||||
}
|
||||
@@ -286,7 +286,7 @@ class Route
|
||||
$url .= '?' . $this->getUriQuery();
|
||||
}
|
||||
|
||||
return $url;
|
||||
return rtrim($url,'/');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,9 +344,8 @@ class Route
|
||||
$parts[] = $this->language;
|
||||
}
|
||||
|
||||
if ($this->route !== '') {
|
||||
$parts[] = $this->extension ? $this->route . '.' . $this->extension : $this->route;
|
||||
}
|
||||
$parts[] = $this->extension ? $this->route . '.' . $this->extension : $this->route;
|
||||
|
||||
|
||||
if ($this->gravParams) {
|
||||
$parts[] = RouteFactory::buildParams($this->gravParams);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Grav\Framework\Session;
|
||||
|
||||
use Grav\Common\User\Interfaces\UserInterface;
|
||||
use Grav\Framework\Session\Exceptions\SessionException;
|
||||
|
||||
/**
|
||||
@@ -17,16 +18,13 @@ use Grav\Framework\Session\Exceptions\SessionException;
|
||||
*/
|
||||
class Session implements SessionInterface
|
||||
{
|
||||
protected $options;
|
||||
/** @var array */
|
||||
protected $options = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
/** @var bool */
|
||||
protected $started = false;
|
||||
|
||||
/**
|
||||
* @var Session
|
||||
*/
|
||||
/** @var Session */
|
||||
protected static $instance;
|
||||
|
||||
/**
|
||||
@@ -178,9 +176,13 @@ class Session implements SessionInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
$sessionName = session_name();
|
||||
$sessionExists = isset($_COOKIE[$sessionName]);
|
||||
|
||||
// Protection against invalid session cookie names throwing exception: http://php.net/manual/en/function.session-id.php#116836
|
||||
if (isset($_COOKIE[session_name()]) && !preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[session_name()])) {
|
||||
unset($_COOKIE[session_name()]);
|
||||
if ($sessionExists && !preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[$sessionName])) {
|
||||
unset($_COOKIE[$sessionName]);
|
||||
$sessionExists = false;
|
||||
}
|
||||
|
||||
$options = $this->options;
|
||||
@@ -197,24 +199,28 @@ class Session implements SessionInterface
|
||||
throw new SessionException('Failed to start session: ' . $error, 500);
|
||||
}
|
||||
|
||||
if ($user && !$user->isValid()) {
|
||||
$this->clear();
|
||||
throw new SessionException('User Invalid', 500);
|
||||
$this->started = true;
|
||||
|
||||
if ($user && (!$user instanceof UserInterface || !$user->isValid())) {
|
||||
$this->invalidate();
|
||||
|
||||
throw new SessionException('Invalid User object, session destroyed.', 500);
|
||||
}
|
||||
|
||||
$params = session_get_cookie_params();
|
||||
// Extend the lifetime of the session.
|
||||
if ($sessionExists) {
|
||||
$params = session_get_cookie_params();
|
||||
|
||||
setcookie(
|
||||
session_name(),
|
||||
session_id(),
|
||||
time() + $params['lifetime'],
|
||||
$params['path'],
|
||||
$params['domain'],
|
||||
$params['secure'],
|
||||
$params['httponly']
|
||||
);
|
||||
|
||||
$this->started = true;
|
||||
setcookie(
|
||||
$sessionName,
|
||||
session_id(),
|
||||
time() + $params['lifetime'],
|
||||
$params['path'],
|
||||
$params['domain'],
|
||||
$params['secure'],
|
||||
$params['httponly']
|
||||
);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
themes/grav/.sass-cache
|
||||
.DS_Store
|
||||
crowdin.yaml
|
||||
|
||||
# Node Modules
|
||||
**/node_modules/**
|
||||
|
||||
@@ -1,3 +1,53 @@
|
||||
# v1.9.16
|
||||
## 09/01/2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed a glitch which allows user to delete entire pages directory [#1941](https://github.com/getgrav/grav-plugin-admin/issues/1941)
|
||||
* Fixed the hidden login plugin toggle
|
||||
|
||||
# v1.9.15
|
||||
## 06/08/2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Support markdown in `fieldset.text` [#2934](https://github.com/getgrav/grav/issues/2934)
|
||||
* Fix data URLs in avatar images [#1889](https://github.com/getgrav/grav/issues/1889)
|
||||
* Fix for deleting files in plugin configurations
|
||||
|
||||
# v1.9.14
|
||||
## 04/27/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Added `slug` and `type` to blueprints
|
||||
1. [](#bugfix)
|
||||
* Support markdown in `fieldset.text` [#2934](https://github.com/getgrav/grav/issues/2934)
|
||||
|
||||
# v1.9.13
|
||||
## 03/05/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Updated vendor libs
|
||||
1. [](#bugfix)
|
||||
* Fixed toggleable buttons no longer holding false state [form#406](ttps://github.com/getgrav/grav-plugin-form/issues/406)
|
||||
|
||||
# v1.9.12
|
||||
## 12/04/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed saving configuration in PHP 7.4
|
||||
|
||||
# v1.9.11
|
||||
## 11/06/2019
|
||||
|
||||
1. [](#improved)
|
||||
* Added new "secure delete" functionality [#1752](https://github.com/getgrav/grav-plugin-admin/issues/1752)
|
||||
* Center text logo [#1751](https://github.com/getgrav/grav-plugin-admin/issues/1751)
|
||||
* Added required span to editor field [#1748](https://github.com/getgrav/grav-plugin-admin/issues/1748)
|
||||
* Warn users if JS is disabled [#1722](https://github.com/getgrav/grav-plugin-admin/issues/1722)
|
||||
* Added target rule to quick links [#1518](https://github.com/getgrav/grav-plugin-admin/issues/1518)
|
||||
1. [](#bugfix)
|
||||
* Fixed `Badly encoded JSON data` warning when uploading files [grav#2663](https://github.com/getgrav/grav/issues/2663)
|
||||
* Fixed `accept` for SVG in `file` uploaders [#1732](https://github.com/getgrav/grav-plugin-admin/issues/1732)
|
||||
|
||||
# v1.9.10
|
||||
## 09/19/2019
|
||||
|
||||
@@ -24,13 +74,13 @@
|
||||
* Fixed issue with `array` field nested in `list` that were losing their index order when the list reordered
|
||||
* Fixed file form field failing resolution checks in certain circumstances
|
||||
* Fixed issue with deleting files in config based YAML files
|
||||
|
||||
|
||||
# v1.9.7
|
||||
## 06/21/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed issue with charts in dashboard where label would cut off [#1700](https://github.com/getgrav/grav-plugin-admin/issues/1700)
|
||||
* Resetting a user's password clears the user's site access [grav#2528](https://github.com/getgrav/grav/issues/2528)
|
||||
* Resetting a user's password clears the user's site access [grav#2528](https://github.com/getgrav/grav/issues/2528)
|
||||
* Fixed issue with permissions toggle [#1702](https://github.com/getgrav/grav-plugin-admin/issues/1702)
|
||||
|
||||
# v1.9.6
|
||||
@@ -72,7 +122,7 @@
|
||||
* Added a new **YAML Linter** report to the `Tools - Reports` section
|
||||
1. [](#improved)
|
||||
* Updated package.json scripts to properly use gulp compiler
|
||||
|
||||
|
||||
# v1.9.2
|
||||
## 04/15/2019
|
||||
|
||||
@@ -85,7 +135,7 @@
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fix for Page saving issues [#1648](https://github.com/getgrav/grav-plugin-admin/issues/1648)
|
||||
* Remove status message when picking folder for move [#1650](https://github.com/getgrav/grav-plugin-admin/issues/1650)
|
||||
* Remove status message when picking folder for move [#1650](https://github.com/getgrav/grav-plugin-admin/issues/1650)
|
||||
|
||||
# v1.9.0
|
||||
## 04/11/2019
|
||||
@@ -120,10 +170,10 @@
|
||||
* Homepage link should be `https://` [#1564](https://github.com/getgrav/grav-plugin-admin/issues/1564)
|
||||
* Improve lang string to describe XSS security settings [#1566](https://github.com/getgrav/grav-plugin-admin/issues/1566)
|
||||
* Take admin setting for 2FA into account when showing user 2FA badge [#1568](https://github.com/getgrav/grav-plugin-admin/issues/1568)
|
||||
* Moved `ignore` and `key` field into form plugin
|
||||
* Moved `ignore` and `key` field into form plugin
|
||||
* Improved usability of `System` configuration blueprint with side-tabs
|
||||
* Cleaned up UI in `Scheduler` tools page
|
||||
* Updated languages
|
||||
* Cleaned up UI in `Scheduler` tools page
|
||||
* Updated languages
|
||||
1. [](#bugfix)
|
||||
* Fixed user edit links if Flex Objects plugin is installed but user isn't Flex User
|
||||
* Fixed deprecated `sameas()` Twig test
|
||||
@@ -133,15 +183,15 @@
|
||||
* Fixed issue with Safari browser and blueprint fields with `toggleable: true` [#1643](https://github.com/getgrav/grav-plugin-admin/issues/1643)
|
||||
* Incorrect 2FA lang code [#1618](https://github.com/getgrav/grav-plugin-admin/issues/1618)
|
||||
* Fixed potential undefined property in `onPageNotFound` event handling
|
||||
* Proper fix for `vUndefined` when updating plugins/themes
|
||||
* Proper fix for `vUndefined` when updating plugins/themes
|
||||
* Text in Tab Tools/Direct install disappears [#1613](https://github.com/getgrav/grav-plugin-admin/issues/1613)
|
||||
* Fallback to page `slug` in Pages list if title is empty [grav#2267](https://github.com/getgrav/grav/issues/2267)
|
||||
* Fixes backup button issues with `;` param separator [#1602](https://github.com/getgrav/grav-plugin-admin/issues/1602) [#1502](https://github.com/getgrav/grav-plugin-admin/issues/1502)
|
||||
* Set default state for `show_modular` to `true` [#1599](https://github.com/getgrav/grav-plugin-admin/issues/1599)
|
||||
* Removed `tabs`, `tab`, and `toggle` fields as they are now in Form plugin
|
||||
* Fix issue with new page always showing modular page templates [#1573](https://github.com/getgrav/grav-plugin-admin/issues/1573)
|
||||
* Fixed issue deleting files in plugins/themes/config
|
||||
* Fixed array support in admin languages, e.g. `DAYS_OF_THE_WEEK`
|
||||
* Fixed issue deleting files in plugins/themes/config
|
||||
* Fixed array support in admin languages, e.g. `DAYS_OF_THE_WEEK`
|
||||
* Fixed user login / remember me triggering before admin gets initialized
|
||||
* Fixed a bug when deleting files via AJAX
|
||||
* Fixed error page not to be the frontend version
|
||||
@@ -154,24 +204,24 @@
|
||||
* Removed duplicate language strings
|
||||
* Fixed default `job_at` so it does not fail if missing
|
||||
* Minor JS group `bottom` fix
|
||||
|
||||
|
||||
# v1.8.20
|
||||
## 03/20/2019
|
||||
|
||||
1. [](#improved)
|
||||
* Added security field to column [#1622](https://github.com/getgrav/grav-plugin-admin/pull/1622)
|
||||
|
||||
|
||||
# v1.8.19
|
||||
## 02/13/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Moved `show_modular` to proper place - Doh! [grav#2362](https://github.com/getgrav/grav/issues/2362)
|
||||
* Moved `show_modular` to proper place - Doh! [grav#2362](https://github.com/getgrav/grav/issues/2362)
|
||||
|
||||
# v1.8.18
|
||||
## 02/12/2019
|
||||
|
||||
1. [](#bugfix)
|
||||
* Set default value for `show_modular` [grav#2362](https://github.com/getgrav/grav/issues/2362)
|
||||
* Set default value for `show_modular` [grav#2362](https://github.com/getgrav/grav/issues/2362)
|
||||
|
||||
# v1.8.17
|
||||
## 02/07/2019
|
||||
@@ -192,7 +242,7 @@
|
||||
1. [](#bugfix)
|
||||
* Fixed calendar js module not properly loading for datetime field [#1581](https://github.com/getgrav/grav-plugin-admin/issues/1581)
|
||||
* Fixed deleting file when using file field type [#1558](https://github.com/getgrav/grav-plugin-admin/issues/1558)
|
||||
* Unset state from user if not super or user admin
|
||||
* Unset state from user if not super or user admin
|
||||
|
||||
# v1.8.15
|
||||
## 12/14/2018
|
||||
|
||||
@@ -26,6 +26,7 @@ session:
|
||||
timeout: 1800
|
||||
warnings:
|
||||
delete_page: true
|
||||
secure_delete: false
|
||||
edit_mode: normal
|
||||
frontend_preview_target: inline
|
||||
show_github_msg: true
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
name: Admin Panel
|
||||
version: 1.9.10
|
||||
slug: admin
|
||||
type: plugin
|
||||
version: 1.9.16
|
||||
testing: false
|
||||
description: Adds an advanced administration panel to manage your site
|
||||
icon: empire
|
||||
@@ -14,7 +16,7 @@ docs: https://github.com/getgrav/grav-plugin-admin/blob/develop/README.md
|
||||
license: MIT
|
||||
|
||||
dependencies:
|
||||
- { name: grav, version: '>=1.6.8' }
|
||||
- { name: grav, version: '>=1.6.22' }
|
||||
- { name: form, version: '>=3.0.0' }
|
||||
- { name: login, version: '>=3.0.0' }
|
||||
- { name: email, version: '>=3.0.0' }
|
||||
@@ -243,6 +245,18 @@ form:
|
||||
type: bool
|
||||
help: Ask the user confirmation when deleting a page
|
||||
|
||||
warnings.secure_delete:
|
||||
type: toggle
|
||||
label: Secure Delete
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
1: PLUGIN_ADMIN.ENABLED
|
||||
0: PLUGIN_ADMIN.DISABLED
|
||||
validate:
|
||||
type: bool
|
||||
help: Shows the user a field to enter the word DELETE and enable the confirm delete button.
|
||||
|
||||
hide_page_types:
|
||||
type: array
|
||||
label: Hide page types in Admin
|
||||
|
||||
@@ -1671,8 +1671,11 @@ class Admin
|
||||
{
|
||||
$reports = new ArrayCollection();
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $this->grav['pages'];
|
||||
|
||||
// Default to XSS Security Report
|
||||
$result = Security::detectXssFromPages($this->grav['pages'], true);
|
||||
$result = Security::detectXssFromPages($pages, true);
|
||||
|
||||
$reports['Grav Security Check'] = $this->grav['twig']->processTemplate('reports/security.html.twig', [
|
||||
'result' => $result,
|
||||
|
||||
@@ -325,7 +325,7 @@ class AdminBaseController
|
||||
}
|
||||
|
||||
$isMime = strstr($type, '/');
|
||||
$find = str_replace(['.', '*'], ['\.', '.*'], $type);
|
||||
$find = str_replace(['.', '*', '+'], ['\.', '.*', '\+'], $type);
|
||||
|
||||
if ($isMime) {
|
||||
$match = preg_match('#' . $find . '$#', $mime);
|
||||
@@ -737,8 +737,8 @@ class AdminBaseController
|
||||
// Process previously uploaded files for the current URI
|
||||
// and finally store them. Everything else will get discarded
|
||||
$queue = $this->admin->session()->getFlashObject('files-upload');
|
||||
$queue = $queue[base64_encode($this->grav['uri']->url())];
|
||||
if (is_array($queue)) {
|
||||
$queue = $queue[base64_encode($this->grav['uri']->url())];
|
||||
foreach ($queue as $key => $files) {
|
||||
foreach ($files as $destination => $file) {
|
||||
if (!rename($file['tmp_name'], $destination)) {
|
||||
@@ -943,7 +943,7 @@ class AdminBaseController
|
||||
$settings = (object)$blueprints->schema()->getProperty($field);
|
||||
} else {
|
||||
$page = null;
|
||||
if ($type === 'themes') {
|
||||
if ($type === 'themes' || $type === 'plugins') {
|
||||
$obj = $this->grav[$type]->get(Utils::substrToString($blueprint, '/')); //here
|
||||
$settings = (object) $obj->blueprints()->schema()->getProperty($field);
|
||||
} else {
|
||||
|
||||
@@ -487,6 +487,11 @@ class AdminController extends AdminBaseController
|
||||
|
||||
$data = (array)$this->data;
|
||||
|
||||
$folder = $data['folder'] ?? '';
|
||||
if ($folder === '' || mb_strpos($folder, '/') !== false) {
|
||||
throw new \RuntimeException('Creating folder failed, bad folder name', 400);
|
||||
}
|
||||
|
||||
if ($data['route'] === '/') {
|
||||
$path = $this->grav['locator']->findResource('page://');
|
||||
} else {
|
||||
@@ -494,7 +499,7 @@ class AdminController extends AdminBaseController
|
||||
}
|
||||
|
||||
$orderOfNewFolder = static::getNextOrderInFolder($path);
|
||||
$new_path = $path . '/' . $orderOfNewFolder . '.' . $data['folder'];
|
||||
$new_path = $path . '/' . $orderOfNewFolder . '.' . $folder;
|
||||
|
||||
Folder::create($new_path);
|
||||
Cache::clearCache('invalidate');
|
||||
@@ -585,6 +590,11 @@ class AdminController extends AdminBaseController
|
||||
/** @var PageInterface $obj */
|
||||
$obj = $this->admin->page(true);
|
||||
|
||||
$folder = $data['folder'] ?? null;
|
||||
if ($folder === '' || mb_strpos($folder, '/') !== false) {
|
||||
throw new \RuntimeException('Saving page failed: bad folder name', 400);
|
||||
}
|
||||
|
||||
if (!isset($data['folder']) || !$data['folder']) {
|
||||
$data['folder'] = $obj->slug();
|
||||
$this->data['folder'] = $obj->slug();
|
||||
@@ -814,6 +824,10 @@ class AdminController extends AdminBaseController
|
||||
$folder = \Grav\Plugin\Admin\Utils::slug($data[substr($folder, 9)]);
|
||||
}
|
||||
$folder = ltrim($folder, '_');
|
||||
if ($folder === '' || mb_strpos($folder, '/') !== false) {
|
||||
throw new \RuntimeException('Creating page failed: bad folder name', 400);
|
||||
}
|
||||
|
||||
if (!empty($data['modular'])) {
|
||||
$folder = '_' . $folder;
|
||||
}
|
||||
|
||||
Generated
+517
-341
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
||||
PLUGIN_ADMIN:
|
||||
ADMIN_NOSCRIPT_MSG: "Please enable JavaScript in your browser."
|
||||
ADMIN_BETA_MSG: "This is a Beta release! Use this in production at your own risk..."
|
||||
ADMIN_REPORT_ISSUE: "Found an issue? Please report it on GitHub."
|
||||
EMAIL_FOOTER: "<a href=\"http://getgrav.org\">Powered by Grav</a> - The Modern Flat File CMS"
|
||||
@@ -43,10 +44,12 @@ PLUGIN_ADMIN:
|
||||
EXPERT: "Expert"
|
||||
EXPAND_ALL: "Expand All"
|
||||
COLLAPSE_ALL: "Collapse All"
|
||||
SECURE_DELETE_DESC: "Type DELETE and confirm"
|
||||
ERROR: "Error"
|
||||
CLOSE: "Close"
|
||||
CANCEL: "Cancel"
|
||||
CONTINUE: "Continue"
|
||||
CONFIRM: "Confirm"
|
||||
MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_TITLE: "Confirmation Required"
|
||||
MODAL_CHANGED_DETECTED_TITLE: "Changes Detected"
|
||||
MODAL_CHANGED_DETECTED_DESC: "You have unsaved changes. Are you sure you want to leave without saving?"
|
||||
@@ -825,3 +828,6 @@ PLUGIN_ADMIN:
|
||||
DEBUGGER_CLOCKWORK: "Clockwork Browser Extension"
|
||||
SHOW_SENSITIVE: "Show Sensitive Data"
|
||||
SHOW_SENSITIVE_HELP: "Clockwork Provider ONLY: Censor potentially sensitive information (POST parameters, cookies, files, configuration and most array/object data in log messages)"
|
||||
VALID_LINK_ATTRIBUTES: "Valid Link Attributes"
|
||||
VALID_LINK_ATTRIBUTES_HELP: "Attributes that will be automatically added to the media HTML element"
|
||||
|
||||
|
||||
@@ -43,10 +43,12 @@ PLUGIN_ADMIN:
|
||||
EXPERT: "Esperto"
|
||||
EXPAND_ALL: "Expandir Tudo"
|
||||
COLLAPSE_ALL: "Recolher Tudo"
|
||||
SECURE_DELETE_DESC: "Digite DELETE e confirme"
|
||||
ERROR: "Erro"
|
||||
CLOSE: "Fechar"
|
||||
CANCEL: "Cancelar"
|
||||
CONTINUE: "Continuar"
|
||||
CONFIRM: "Confirmar"
|
||||
MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_TITLE: "Confirmação Requerida"
|
||||
MODAL_CHANGED_DETECTED_TITLE: "Alterações Detectadas"
|
||||
MODAL_CHANGED_DETECTED_DESC: "Você tem alterações não salvas. Tem certeza que deseja sair sem salvar?"
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -3,7 +3,7 @@ $fonts-default: 'Roboto' !default;
|
||||
$fonts-mono: 'Inconsolata' !default;
|
||||
|
||||
$font-definitions: (
|
||||
Josefin+Slab: 400,
|
||||
'Josefin Slab': '400',
|
||||
Roboto: '300,400,500',
|
||||
Inconsolata: '400,700'
|
||||
);
|
||||
|
||||
@@ -244,7 +244,7 @@ $content-padding: 1.5rem;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
a:not(.front-end) {
|
||||
display: inherit;
|
||||
}
|
||||
@@ -798,6 +798,7 @@ body.sidebar-quickopen #admin-main {
|
||||
|
||||
.button {
|
||||
margin: 0;
|
||||
height: 37px;
|
||||
|
||||
&.dropdown-toggle {
|
||||
margin-left: -4px;
|
||||
|
||||
@@ -103,6 +103,7 @@
|
||||
justify-content: center;
|
||||
|
||||
&.text-logo {
|
||||
text-align: center;
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,10 @@
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
&:disabled {
|
||||
opacity: .6;
|
||||
cursor: no-drop;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
{% if not blueprints or (blueprints.schema.type(field.type)['input@'] ?? true) is same as(true) %}
|
||||
{% set originalValue = originalValue is defined ? originalValue : value %}
|
||||
{% set toggleableChecked = field.toggleable and (originalValue is not null and originalValue is not empty) %}
|
||||
{% set toggleableChecked = field.toggleable and originalValue is not null %}
|
||||
{% set isDisabledToggleable = field.toggleable and not toggleableChecked %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
{% set value = value ?? field.default %}
|
||||
|
||||
{% if (field.yaml or field.validate.type == 'yaml') and value is iterable%}
|
||||
{% set value = value|toYaml %}
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
{% if field.help %}
|
||||
{% set hint = 'data-hint="' ~ field.help|tu|raw ~ '"' %}
|
||||
{% endif %}
|
||||
<div class="form-label form-field hint--bottom" {{ hint|raw }}>{{ field.label|tu|raw }}</div>
|
||||
<div class="form-label form-field hint--bottom" {{ hint|raw }}>
|
||||
{{ field.label|tu|raw }}
|
||||
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
<div class="form-field {{ field.classes|default('') }}">
|
||||
|
||||
@@ -48,9 +48,12 @@
|
||||
>
|
||||
|
||||
{% block group %}
|
||||
{% if field.text %}
|
||||
<p>{% if grav.twig.twig.filters['tu'] is defined %}{{ field.text|tu }}{% else %}{{ field.text|t }}{% endif %}
|
||||
<p>
|
||||
{% if field.text %}
|
||||
{% if grav.twig.twig.filters['tu'] is defined %}
|
||||
{{ field.markdown ? field.text|tu|markdown : '<p>' ~ field.text|tu ~ '</p>' }}
|
||||
{% else %}
|
||||
{{ field.markdown ? field.text|t|markdown : '<p>' ~ field.t ~ '</p>' }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if field.fields %}
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
|
||||
{% set modular = context.modular ? 'modular_' : '' %}
|
||||
{% set warn = config.plugins.admin.warnings.delete_page %}
|
||||
{% set secure_delete = config.plugins.admin.warnings.secure_delete %}
|
||||
{% set admin_lang = admin.session.admin_lang ?: 'en' %}
|
||||
{% set page_lang = context.language %}
|
||||
{% set type = 'page' %}
|
||||
@@ -405,10 +406,19 @@
|
||||
<p class="bigger">
|
||||
{{ "PLUGIN_ADMIN.MODAL_DELETE_PAGE_CONFIRMATION_REQUIRED_DESC"|tu }}
|
||||
</p>
|
||||
{% if secure_delete %}
|
||||
<p class="form-secure-delete">
|
||||
<input id="secure-delete-field" autofocus type="text" placeholder="{{ "PLUGIN_ADMIN.SECURE_DELETE_DESC"|tu }}" />
|
||||
</p>
|
||||
{% endif %}
|
||||
<br>
|
||||
<div class="button-bar">
|
||||
<button data-remodal-action="cancel" class="button secondary remodal-cancel"><i class="fa fa-fw fa-close"></i> {{ "PLUGIN_ADMIN.CANCEL"|tu }}</button>
|
||||
<a class="button disable-after-click" data-delete-action href="#"><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONTINUE"|tu }}</a>
|
||||
{% if secure_delete %}
|
||||
<button id="secure-delete-btn" disabled="true" class="button danger disable-after-click" data-delete-action><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONFIRM"|tu }}</button>
|
||||
{% else %}
|
||||
<a class="button danger disable-after-click" data-delete-action href="#"><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONTINUE"|tu }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -421,5 +431,18 @@
|
||||
{{ parent() }}
|
||||
<script>
|
||||
$('.admin-pages .form-tabs .tabs-nav').css('margin-right', ($('#admin-topbar').width() + 20) + 'px');
|
||||
{% if secure_delete %}
|
||||
$('#secure-delete-field').keyup(function () {
|
||||
var inputValue = $(this).val();
|
||||
if (inputValue == 'DELETE') {
|
||||
$('#secure-delete-btn').attr('disabled', false);
|
||||
}else{
|
||||
$('#secure-delete-btn').attr('disabled', true);
|
||||
}
|
||||
});
|
||||
$(document).on('closing', '.remodal', function () {
|
||||
$('#secure-delete-field').val('');
|
||||
});
|
||||
{% endif %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
{% include 'partials/messages.html.twig' %}
|
||||
{% else %}
|
||||
|
||||
{% block noscript %}
|
||||
{% include 'partials/noscript.html.twig' %}
|
||||
{% endblock noscript %}
|
||||
|
||||
{% block page %}
|
||||
<div class="remodal-bg">
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
{% endif %}
|
||||
<li class="{{ item.class }} hint--bottom" data-hint="{{ item.hint }}" {{ data_tags|raw }}>
|
||||
{% if item.route %}
|
||||
<a href="{{ url(item.route) }}">
|
||||
<a href="{{ url(item.route) }}" {% if item.target %}target="{{ item.target }}"{% endif %}>
|
||||
<i class="fa fa-fw {{ item.icon }}"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
{% set user_avatar = admin.user.getAvatarUrl() %}
|
||||
<img src="{{ '?' not in user_avatar ? user_avatar ~ '?s=80' : user_avatar }}" />
|
||||
<img src="{{ ('?' not in user_avatar) and (not user_avatar starts with 'data:') ? user_avatar ~ '?s=80' : user_avatar }}" />
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<style>
|
||||
.error-message {
|
||||
background-color: #fce4e4;
|
||||
border: 1px solid #fcc2c3;
|
||||
width: 100%;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
.error-text {
|
||||
color: #cc0033;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
text-shadow: 1px 1px rgba(250,250,250,.3);
|
||||
}
|
||||
.full-height {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="noscript" class="full-height">
|
||||
<main id="admin-main" class="full-height">
|
||||
<div id="titlebar" class="titlebar">
|
||||
<h1><i class="fa fa-fw fa-exclamation-triangle"></i>{{ "PLUGIN_ADMIN.ERROR"|tu }}</h1>
|
||||
</div>
|
||||
<div class="full-height">
|
||||
<div class="error-message {% if config.plugins.admin.content_padding %}content-padding{% endif %}">
|
||||
<span class="error-text">{{ "PLUGIN_ADMIN.ADMIN_NOSCRIPT_MSG"|tu }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
function checkjs() {
|
||||
var element = document.getElementById("noscript");
|
||||
element.style.display = 'none';
|
||||
}
|
||||
checkjs();
|
||||
</script>
|
||||
@@ -42,7 +42,7 @@
|
||||
{% if isTestingRelease %}<span class="gpm-testing">test release</span>{% endif %}
|
||||
</td>
|
||||
<td class="gpm-actions">
|
||||
{% if (not installing and (plugin.form.fields.enabled.type != 'hidden' and plugin.form.fields.tabs.fields.login.fields.enabled.type != 'hidden')) %}
|
||||
{% if (not installing and (plugin.form.fields.enabled.type != 'hidden' and plugin.form.fields.tabs.fields.options.fields.enabled.type != 'hidden')) %}
|
||||
<a class="{{ data.get('enabled') ? 'enabled' : 'disabled' }}" href="{{ uri.addNonce(base_url_relative ~ '/plugins/' ~ slug ~ '/task' ~ config.system.param_sep ~ (data.get('enabled') ? 'disable' : 'enable'), 'admin-form', 'admin-nonce') }}">
|
||||
<i class="fa fa-fw fa-toggle-{{ data.get('enabled') ? 'on' : 'off' }}"></i>
|
||||
</a>
|
||||
|
||||
+2
-2
@@ -279,7 +279,7 @@ class ClassLoader
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,7 +377,7 @@ class ClassLoader
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath.'\\';
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
|
||||
+9
-9
@@ -1,27 +1,26 @@
|
||||
[
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "1.4.2",
|
||||
"version_normalized": "1.4.2.0",
|
||||
"version": "1.5.1",
|
||||
"version_normalized": "1.5.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "c7cb9a2095a074d131b65a8a0cd294479d785573"
|
||||
"reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573",
|
||||
"reference": "c7cb9a2095a074d131b65a8a0cd294479d785573",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
|
||||
"reference": "c6bea70230ef4dd483e6bbcab6005f682ed3a8de",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.5 || ^5.0.5",
|
||||
"phpunit/phpunit-mock-objects": "2.3.0 || ^3.0"
|
||||
"phpunit/phpunit": "^4.5 || ^5.0.5"
|
||||
},
|
||||
"time": "2016-08-30T16:08:34+00:00",
|
||||
"time": "2020-01-13T12:06:48+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@@ -164,6 +163,7 @@
|
||||
"security",
|
||||
"xml",
|
||||
"zf"
|
||||
]
|
||||
],
|
||||
"abandoned": "laminas/laminas-xml"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
### [1.5.1] 2020-01-13
|
||||
|
||||
* Fixed: Parsing of aliased version was not validating the alias to be a valid version
|
||||
|
||||
### [1.5.0] 2019-03-19
|
||||
|
||||
* Added: some support for date versions (e.g. 201903) in `~` operator
|
||||
* Fixed: support for stabilities in `~` operator was inconsistent
|
||||
|
||||
### [1.4.2] 2016-08-30
|
||||
|
||||
* Fixed: collapsing of complex constraints lead to buggy constraints
|
||||
@@ -57,6 +66,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Namespace: `Composer\Test\Package\LinkConstraint` -> `Composer\Test\Semver\Constraint`
|
||||
* Changed: code style using php-cs-fixer.
|
||||
|
||||
[1.5.1]: https://github.com/composer/semver/compare/1.5.0...1.5.1
|
||||
[1.5.0]: https://github.com/composer/semver/compare/1.4.2...1.5.0
|
||||
[1.4.2]: https://github.com/composer/semver/compare/1.4.1...1.4.2
|
||||
[1.4.1]: https://github.com/composer/semver/compare/1.4.0...1.4.1
|
||||
[1.4.0]: https://github.com/composer/semver/compare/1.3.0...1.4.0
|
||||
[1.3.0]: https://github.com/composer/semver/compare/1.2.0...1.3.0
|
||||
|
||||
+1
-2
@@ -34,8 +34,7 @@
|
||||
"php": "^5.3.2 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.5 || ^5.0.5",
|
||||
"phpunit/phpunit-mock-objects": "2.3.0 || ^3.0"
|
||||
"phpunit/phpunit": "^4.5 || ^5.0.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
|
||||
namespace Composer\Semver\Constraint;
|
||||
|
||||
trigger_error('The ' . __CLASS__ . ' abstract class is deprecated, there is no replacement for it, it will be removed in the next major version.', E_USER_DEPRECATED);
|
||||
trigger_error('The ' . __NAMESPACE__ . '\AbstractConstraint abstract class is deprecated, there is no replacement for it, it will be removed in the next major version.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Base constraint class.
|
||||
|
||||
@@ -184,7 +184,7 @@ class Constraint implements ConstraintInterface
|
||||
// '!=' operator is match when other operator is not '==' operator or version is not match
|
||||
// these kinds of comparisons always have a solution
|
||||
if ($isNonEqualOp || $isProviderNonEqualOp) {
|
||||
return !$isEqualOp && !$isProviderEqualOp
|
||||
return (!$isEqualOp && !$isProviderEqualOp)
|
||||
|| $this->versionCompare($provider->version, $this->version, '!=', $compareBranches);
|
||||
}
|
||||
|
||||
@@ -197,13 +197,9 @@ class Constraint implements ConstraintInterface
|
||||
if ($this->versionCompare($provider->version, $this->version, self::$transOpInt[$this->operator], $compareBranches)) {
|
||||
// special case, e.g. require >= 1.0 and provide < 1.0
|
||||
// 1.0 >= 1.0 but 1.0 is outside of the provided interval
|
||||
if ($provider->version === $this->version
|
||||
return !($provider->version === $this->version
|
||||
&& self::$transOpInt[$provider->operator] === $providerNoEqualOp
|
||||
&& self::$transOpInt[$this->operator] !== $noEqualOp) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
&& self::$transOpInt[$this->operator] !== $noEqualOp);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ class EmptyConstraint implements ConstraintInterface
|
||||
return $this->prettyString;
|
||||
}
|
||||
|
||||
return $this->__toString();
|
||||
return (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ class MultiConstraint implements ConstraintInterface
|
||||
return $this->prettyString;
|
||||
}
|
||||
|
||||
return $this->__toString();
|
||||
return (string) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,9 +37,9 @@ class Semver
|
||||
|
||||
$versionParser = self::$versionParser;
|
||||
$provider = new Constraint('==', $versionParser->normalize($version));
|
||||
$constraints = $versionParser->parseConstraints($constraints);
|
||||
$parsedConstraints = $versionParser->parseConstraints($constraints);
|
||||
|
||||
return $constraints->matches($provider);
|
||||
return $parsedConstraints->matches($provider);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+22
-25
@@ -52,11 +52,12 @@ class VersionParser
|
||||
{
|
||||
$version = preg_replace('{#.+$}i', '', $version);
|
||||
|
||||
if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
|
||||
if (strpos($version, 'dev-') === 0 || '-dev' === substr($version, -4)) {
|
||||
return 'dev';
|
||||
}
|
||||
|
||||
preg_match('{' . self::$modifierRegex . '(?:\+.*)?$}i', strtolower($version), $match);
|
||||
|
||||
if (!empty($match[3])) {
|
||||
return 'dev';
|
||||
}
|
||||
@@ -107,6 +108,9 @@ class VersionParser
|
||||
|
||||
// strip off aliasing
|
||||
if (preg_match('{^([^,\s]++) ++as ++([^,\s]++)$}', $version, $match)) {
|
||||
// verify that the alias is a version without constraint
|
||||
$this->normalize($match[2]);
|
||||
|
||||
$version = $match[1];
|
||||
}
|
||||
|
||||
@@ -116,7 +120,7 @@ class VersionParser
|
||||
}
|
||||
|
||||
// if requirement is branch-like, use full name
|
||||
if ('dev-' === strtolower(substr($version, 0, 4))) {
|
||||
if (stripos($version, 'dev-') === 0) {
|
||||
return 'dev-' . substr($version, 4);
|
||||
}
|
||||
|
||||
@@ -236,6 +240,7 @@ class VersionParser
|
||||
|
||||
$orConstraints = preg_split('{\s*\|\|?\s*}', trim($constraints));
|
||||
$orGroups = array();
|
||||
|
||||
foreach ($orConstraints as $constraints) {
|
||||
$andConstraints = preg_split('{(?<!^|as|[=>< ,]) *(?<!-)[, ](?!-) *(?!,|as|$)}', $constraints);
|
||||
if (count($andConstraints) > 1) {
|
||||
@@ -268,9 +273,9 @@ class VersionParser
|
||||
&& 2 === count($orGroups[0]->getConstraints())
|
||||
&& 2 === count($orGroups[1]->getConstraints())
|
||||
&& ($a = (string) $orGroups[0])
|
||||
&& substr($a, 0, 3) === '[>=' && (false !== ($posA = strpos($a, '<', 4)))
|
||||
&& strpos($a, '[>=') === 0 && (false !== ($posA = strpos($a, '<', 4)))
|
||||
&& ($b = (string) $orGroups[1])
|
||||
&& substr($b, 0, 3) === '[>=' && (false !== ($posB = strpos($b, '<', 4)))
|
||||
&& strpos($b, '[>=') === 0 && (false !== ($posB = strpos($b, '<', 4)))
|
||||
&& substr($a, $posA + 2, -1) === substr($b, 4, $posB - 5)
|
||||
) {
|
||||
$constraint = new MultiConstraint(array(
|
||||
@@ -314,7 +319,7 @@ class VersionParser
|
||||
// version, to ensure that unstable instances of the current version are allowed. However, if a stability
|
||||
// suffix is added to the constraint, then a >= match on the current version is used instead.
|
||||
if (preg_match('{^~>?' . $versionRegex . '$}i', $constraint, $matches)) {
|
||||
if (substr($constraint, 0, 2) === '~>') {
|
||||
if (strpos($constraint, '~>') === 0) {
|
||||
throw new \UnexpectedValueException(
|
||||
'Could not parse version constraint ' . $constraint . ': ' .
|
||||
'Invalid operator "~>", you probably meant to use the "~" operator'
|
||||
@@ -322,11 +327,11 @@ class VersionParser
|
||||
}
|
||||
|
||||
// Work out which position in the version we are operating at
|
||||
if (isset($matches[4]) && '' !== $matches[4]) {
|
||||
if (isset($matches[4]) && '' !== $matches[4] && null !== $matches[4]) {
|
||||
$position = 4;
|
||||
} elseif (isset($matches[3]) && '' !== $matches[3]) {
|
||||
} elseif (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
|
||||
$position = 3;
|
||||
} elseif (isset($matches[2]) && '' !== $matches[2]) {
|
||||
} elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
|
||||
$position = 2;
|
||||
} else {
|
||||
$position = 1;
|
||||
@@ -334,19 +339,11 @@ class VersionParser
|
||||
|
||||
// Calculate the stability suffix
|
||||
$stabilitySuffix = '';
|
||||
if (!empty($matches[5])) {
|
||||
$stabilitySuffix .= '-' . $this->expandStability($matches[5]) . (!empty($matches[6]) ? $matches[6] : '');
|
||||
}
|
||||
|
||||
if (!empty($matches[7])) {
|
||||
if (empty($matches[5]) && empty($matches[7])) {
|
||||
$stabilitySuffix .= '-dev';
|
||||
}
|
||||
|
||||
if (!$stabilitySuffix) {
|
||||
$stabilitySuffix = '-dev';
|
||||
}
|
||||
|
||||
$lowVersion = $this->manipulateVersionString($matches, $position, 0) . $stabilitySuffix;
|
||||
$lowVersion = $this->normalize(substr($constraint . $stabilitySuffix, 1));
|
||||
$lowerBound = new Constraint('>=', $lowVersion);
|
||||
|
||||
// For upper bound, we increment the position of one more significance,
|
||||
@@ -368,9 +365,9 @@ class VersionParser
|
||||
// versions 0.X >=0.1.0, and no updates for versions 0.0.X
|
||||
if (preg_match('{^\^' . $versionRegex . '($)}i', $constraint, $matches)) {
|
||||
// Work out which position in the version we are operating at
|
||||
if ('0' !== $matches[1] || '' === $matches[2]) {
|
||||
if ('0' !== $matches[1] || '' === $matches[2] || null === $matches[2]) {
|
||||
$position = 1;
|
||||
} elseif ('0' !== $matches[2] || '' === $matches[3]) {
|
||||
} elseif ('0' !== $matches[2] || '' === $matches[3] || null === $matches[3]) {
|
||||
$position = 2;
|
||||
} else {
|
||||
$position = 3;
|
||||
@@ -401,9 +398,9 @@ class VersionParser
|
||||
// Any of X, x, or * may be used to "stand in" for one of the numeric values in the [major, minor, patch] tuple.
|
||||
// A partial version range is treated as an X-Range, so the special character is in fact optional.
|
||||
if (preg_match('{^v?(\d++)(?:\.(\d++))?(?:\.(\d++))?(?:\.[xX*])++$}', $constraint, $matches)) {
|
||||
if (isset($matches[3]) && '' !== $matches[3]) {
|
||||
if (isset($matches[3]) && '' !== $matches[3] && null !== $matches[3]) {
|
||||
$position = 3;
|
||||
} elseif (isset($matches[2]) && '' !== $matches[2]) {
|
||||
} elseif (isset($matches[2]) && '' !== $matches[2] && null !== $matches[2]) {
|
||||
$position = 2;
|
||||
} else {
|
||||
$position = 1;
|
||||
@@ -462,11 +459,11 @@ class VersionParser
|
||||
try {
|
||||
$version = $this->normalize($matches[2]);
|
||||
|
||||
if (!empty($stabilityModifier) && $this->parseStability($version) === 'stable') {
|
||||
if (!empty($stabilityModifier) && self::parseStability($version) === 'stable') {
|
||||
$version .= '-' . $stabilityModifier;
|
||||
} elseif ('<' === $matches[1] || '>=' === $matches[1]) {
|
||||
if (!preg_match('/-' . self::$modifierRegex . '$/', strtolower($matches[2]))) {
|
||||
if (substr($matches[2], 0, 4) !== 'dev-') {
|
||||
if (strpos($matches[2], 'dev-') !== 0) {
|
||||
$version .= '-dev';
|
||||
}
|
||||
}
|
||||
@@ -511,7 +508,7 @@ class VersionParser
|
||||
|
||||
// Return null on a carry overflow
|
||||
if ($i === 1) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,44 @@
|
||||
# v3.0.9
|
||||
## 06/08/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Disable password autocomplete in password field
|
||||
* Don't save empty string in password field [#134](https://github.com/getgrav/grav-plugin-email/issues/134)
|
||||
|
||||
# v3.0.8
|
||||
## 04/27/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Updated vendor library files
|
||||
* Use Grav's Parsedown class
|
||||
|
||||
# v3.0.7
|
||||
## 03/05/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Updated email validator library
|
||||
1. [](#bugfix)
|
||||
* Fixed `Invalid resource theme://` on CLI command `test-email` on Grav 1.6.21 and later versions [#128](https://github.com/getgrav/grav-plugin-email/issues/128)
|
||||
|
||||
# v3.0.6
|
||||
## 02/11/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Updated email validator library
|
||||
|
||||
# v3.0.5
|
||||
## 02/03/2020
|
||||
|
||||
1. [](#bugfix)
|
||||
* Fixed a date in changelog (no other changes)
|
||||
|
||||
# v3.0.4
|
||||
## 01/17/2020
|
||||
|
||||
1. [](#improved)
|
||||
* Added ZOHO configuration example
|
||||
* Updated SwiftMailer library for PHP 7.4 support
|
||||
|
||||
# v3.0.3
|
||||
## 08/16/2019
|
||||
|
||||
|
||||
@@ -159,6 +159,25 @@ mailer:
|
||||
|
||||
It's that easy!
|
||||
|
||||
#### ZOHO
|
||||
|
||||
ZOHO is a popular solution for hosted email due to it's great 'FREE' tier. It's paid options are also very reasonable and combined with the latest UI updates and outstanding security features, it's a solid email option.
|
||||
|
||||
In order to get ZOHO working with Grav, you need to send email via a user account. You can either use your users' password or generate an **App Password** via your ZOHO account (clicking on your avatar once logged in), then navigating to `Two Factor Authentication -> App Passwords -> Generate`. Just enter a unique app name (i.e. `Grav Website`).
|
||||
|
||||
NOTE: The SMTP host required can be found in `Settings -> Mail - > Mail Accounts -> POP/IMAP -> SMTP`. This will provide the SMTP server for this account (it may not be `imap.zoho.com` depending on what region you are in)
|
||||
|
||||
```
|
||||
mailer:
|
||||
engine: smtp
|
||||
smtp:
|
||||
server: smtp.zoho.com
|
||||
port: 587
|
||||
encryption: tls
|
||||
user: 'ZOHO_EMAIL_ADDRESS'
|
||||
password: 'ZOHO_EMAIL_PASSWORD'
|
||||
```
|
||||
|
||||
#### Sendmail
|
||||
|
||||
Although not as reliable as SMTP not providing as much debug information, sendmail is a simple option as long as your hosting provider is not blocking the default SMTP port `25`:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
name: Email
|
||||
version: 3.0.3
|
||||
slug: email
|
||||
type: plugin
|
||||
version: 3.0.9
|
||||
testing: false
|
||||
description: Enables the emailing system for Grav
|
||||
icon: envelope
|
||||
@@ -18,6 +20,7 @@ dependencies:
|
||||
|
||||
form:
|
||||
validation: loose
|
||||
|
||||
fields:
|
||||
enabled:
|
||||
type: hidden
|
||||
@@ -168,13 +171,13 @@ form:
|
||||
mailer.smtp.user:
|
||||
type: text
|
||||
size: medium
|
||||
autocomplete: nope
|
||||
autocomplete: 'off'
|
||||
label: PLUGIN_EMAIL.SMTP_LOGIN_NAME
|
||||
|
||||
mailer.smtp.password:
|
||||
type: password
|
||||
size: medium
|
||||
autocomplete: nope
|
||||
autocomplete: 'new-password'
|
||||
label: PLUGIN_EMAIL.SMTP_PASSWORD
|
||||
|
||||
sendmail_config:
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Grav\Plugin\Email;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Markdown\Parsedown;
|
||||
use Grav\Common\Twig\Twig;
|
||||
use Grav\Framework\Form\Interfaces\FormInterface;
|
||||
use \Monolog\Logger;
|
||||
@@ -178,7 +179,7 @@ class Email
|
||||
$body = $twig->processString($value, $vars);
|
||||
|
||||
if ($params['process_markdown']) {
|
||||
$parsedown = new \Parsedown();
|
||||
$parsedown = new Parsedown();
|
||||
$body = $parsedown->text($body);
|
||||
}
|
||||
|
||||
@@ -202,7 +203,7 @@ class Email
|
||||
$body = !empty($body_part['body']) ? $twig->processString($body_part['body'], $vars) : null;
|
||||
|
||||
if ($params['process_markdown']) {
|
||||
$parsedown = new \Parsedown();
|
||||
$parsedown = new Parsedown();
|
||||
$body = $parsedown->text($body);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,11 @@ class ClearQueueFailuresCommand extends ConsoleCommand
|
||||
*/
|
||||
protected function serve()
|
||||
{
|
||||
// TODO: remove when requiring Grav 1.7+
|
||||
if (method_exists($this, 'initializeGrav')) {
|
||||
$this->initializeGrav();
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
$this->output->writeln('');
|
||||
|
||||
@@ -40,6 +40,11 @@ class FlushQueueCommand extends ConsoleCommand
|
||||
*/
|
||||
protected function serve()
|
||||
{
|
||||
// TODO: remove when requiring Grav 1.7+
|
||||
if (method_exists($this, 'initializeGrav')) {
|
||||
$this->initializeGrav();
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
$this->output->writeln('');
|
||||
|
||||
@@ -59,6 +59,11 @@ class TestEmailCommand extends ConsoleCommand
|
||||
*/
|
||||
protected function serve()
|
||||
{
|
||||
// TODO: remove when requiring Grav 1.7+
|
||||
if (method_exists($this, 'initializeGrav')) {
|
||||
$this->initializeThemes();
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
$this->output->writeln('');
|
||||
@@ -69,8 +74,6 @@ class TestEmailCommand extends ConsoleCommand
|
||||
|
||||
$this->output->writeln('');
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$grav['Email'] = new Email();
|
||||
|
||||
$to = $this->input->getOption('to') ?: $grav['config']->get('plugins.email.to');
|
||||
@@ -86,8 +89,6 @@ class TestEmailCommand extends ConsoleCommand
|
||||
$body = $grav['language']->translate(['PLUGIN_EMAIL.TEST_EMAIL_BODY', $configuration]);
|
||||
}
|
||||
|
||||
// This is the old way....
|
||||
// $sent = EmailUtils::sendEmail($subject, $body, $email_to);
|
||||
$sent = EmailUtils::sendEmail(['subject'=>$subject, 'body'=>$body, 'to'=>$to]);
|
||||
|
||||
if ($sent) {
|
||||
|
||||
Generated
+126
-60
@@ -8,30 +8,35 @@
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
"version": "v1.0.1",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/lexer.git",
|
||||
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
|
||||
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
|
||||
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
|
||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
|
||||
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
"php": "^7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpstan/phpstan": "^0.11.8",
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Lexer\\": "lib/"
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -39,48 +44,52 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
|
||||
"keywords": [
|
||||
"annotations",
|
||||
"docblock",
|
||||
"lexer",
|
||||
"parser"
|
||||
"parser",
|
||||
"php"
|
||||
],
|
||||
"time": "2014-09-09T13:34:57+00:00"
|
||||
"time": "2019-10-30T14:39:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "egulias/email-validator",
|
||||
"version": "2.1.7",
|
||||
"version": "2.1.17",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/egulias/EmailValidator.git",
|
||||
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e"
|
||||
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e",
|
||||
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a",
|
||||
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/lexer": "^1.0.1",
|
||||
"php": ">= 5.5"
|
||||
"php": ">=5.5",
|
||||
"symfony/polyfill-intl-idn": "^1.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"dominicsayers/isemail": "dev-master",
|
||||
"phpunit/phpunit": "^4.8.35||^5.7||^6.0",
|
||||
"dominicsayers/isemail": "^3.0.7",
|
||||
"phpunit/phpunit": "^4.8.36|^7.5.15",
|
||||
"satooshi/php-coveralls": "^1.0.1"
|
||||
},
|
||||
"suggest": {
|
||||
@@ -89,7 +98,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "2.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -115,20 +124,20 @@
|
||||
"validation",
|
||||
"validator"
|
||||
],
|
||||
"time": "2018-12-04T22:38:24+00:00"
|
||||
"time": "2020-02-13T22:36:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.2.0",
|
||||
"version": "v6.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707"
|
||||
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
|
||||
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
|
||||
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -177,20 +186,20 @@
|
||||
"mail",
|
||||
"mailer"
|
||||
],
|
||||
"time": "2019-03-10T07:52:41+00:00"
|
||||
"time": "2019-11-12T09:31:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-iconv",
|
||||
"version": "v1.10.0",
|
||||
"version": "v1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-iconv.git",
|
||||
"reference": "97001cfc283484c9691769f51cdf25259037eba2"
|
||||
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/97001cfc283484c9691769f51cdf25259037eba2",
|
||||
"reference": "97001cfc283484c9691769f51cdf25259037eba2",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
|
||||
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -202,7 +211,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -236,26 +245,40 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-09-21T06:26:08+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-03-09T19:04:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.10.0",
|
||||
"version": "v1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a"
|
||||
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
|
||||
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
|
||||
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php72": "^1.9"
|
||||
"symfony/polyfill-php72": "^1.10"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
@@ -263,7 +286,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -279,13 +302,13 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Laurent Bassin",
|
||||
"email": "laurent@bassin.info"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||
@@ -298,20 +321,34 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-09-30T16:36:12+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-03-09T19:04:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.10.0",
|
||||
"version": "v1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
|
||||
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
|
||||
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -323,7 +360,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -357,20 +394,34 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-03-09T19:04:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.10.0",
|
||||
"version": "v1.15.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631"
|
||||
"reference": "37b0976c78b94856543260ce09b460a7bc852747"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
|
||||
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747",
|
||||
"reference": "37b0976c78b94856543260ce09b460a7bc852747",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -379,7 +430,7 @@
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
@@ -412,7 +463,21 @@
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"time": "2018-09-21T13:07:52+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-02-27T09:26:54+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
@@ -424,5 +489,6 @@
|
||||
"platform": {
|
||||
"php": ">=7.1.3"
|
||||
},
|
||||
"platform-dev": []
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "1.1.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace Grav\Plugin;
|
||||
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\Plugin;
|
||||
use Grav\Plugin\Email\Email;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
@@ -22,6 +23,7 @@ class EmailPlugin extends Plugin
|
||||
'onFormProcessed' => ['onFormProcessed', 0],
|
||||
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
|
||||
'onSchedulerInitialized' => ['onSchedulerInitialized', 0],
|
||||
'onAdminSave' => ['onAdminSave', 0],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -48,6 +50,28 @@ class EmailPlugin extends Plugin
|
||||
$twig->twig_paths[] = __DIR__ . '/templates';
|
||||
}
|
||||
|
||||
/**
|
||||
* Force compile during save if admin plugin save
|
||||
*
|
||||
* @param Event $event
|
||||
*/
|
||||
public function onAdminSave(Event $event)
|
||||
{
|
||||
/** @var Data $obj */
|
||||
$obj = $event['object'];
|
||||
|
||||
|
||||
|
||||
if ($obj instanceof Data && $obj->blueprints()->getFilename() === 'email/blueprints') {
|
||||
$current_pw = $this->grav['config']->get('plugins.email.mailer.smtp.password');
|
||||
$new_pw = $obj->get('mailer.smtp.password');
|
||||
if (!empty($current_pw) && empty($new_pw)) {
|
||||
$obj->set('mailer.smtp.password', $current_pw);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send email when processing the form data.
|
||||
*
|
||||
|
||||
+2
-2
@@ -279,7 +279,7 @@ class ClassLoader
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -377,7 +377,7 @@ class ClassLoader
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath.'\\';
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ $baseDir = dirname($vendorDir);
|
||||
return array(
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||
);
|
||||
|
||||
@@ -6,5 +6,4 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib'),
|
||||
);
|
||||
|
||||
@@ -13,4 +13,5 @@ return array(
|
||||
'Grav\\Plugin\\Email\\' => array($baseDir . '/classes'),
|
||||
'Grav\\Plugin\\Console\\' => array($baseDir . '/cli'),
|
||||
'Egulias\\EmailValidator\\' => array($vendorDir . '/egulias/email-validator/EmailValidator'),
|
||||
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/lib/Doctrine/Common/Lexer'),
|
||||
);
|
||||
|
||||
@@ -13,6 +13,9 @@ class ComposerAutoloaderInitdec5d78def1384d1f20996ded9d7efbf
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
|
||||
+7
-10
@@ -9,8 +9,8 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
|
||||
public static $files = array (
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
||||
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||
);
|
||||
|
||||
@@ -31,6 +31,10 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
|
||||
array (
|
||||
'Egulias\\EmailValidator\\' => 23,
|
||||
),
|
||||
'D' =>
|
||||
array (
|
||||
'Doctrine\\Common\\Lexer\\' => 22,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
@@ -62,15 +66,9 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/egulias/email-validator/EmailValidator',
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixesPsr0 = array (
|
||||
'D' =>
|
||||
'Doctrine\\Common\\Lexer\\' =>
|
||||
array (
|
||||
'Doctrine\\Common\\Lexer\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/doctrine/lexer/lib',
|
||||
),
|
||||
0 => __DIR__ . '/..' . '/doctrine/lexer/lib/Doctrine/Common/Lexer',
|
||||
),
|
||||
);
|
||||
|
||||
@@ -83,7 +81,6 @@ class ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$prefixDirsPsr4;
|
||||
$loader->prefixesPsr0 = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$prefixesPsr0;
|
||||
$loader->classMap = ComposerStaticInitdec5d78def1384d1f20996ded9d7efbf::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
|
||||
+131
-66
@@ -1,33 +1,38 @@
|
||||
[
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
"version": "v1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"version": "1.2.0",
|
||||
"version_normalized": "1.2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/lexer.git",
|
||||
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
|
||||
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
|
||||
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
|
||||
"url": "https://api.github.com/repos/doctrine/lexer/zipball/5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
|
||||
"reference": "5242d66dbeb21a30dd8a3e66bf7a73b66e05e1f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
"php": "^7.2"
|
||||
},
|
||||
"time": "2014-09-09T13:34:57+00:00",
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpstan/phpstan": "^0.11.8",
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"time": "2019-10-30T14:39:59+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Common\\Lexer\\": "lib/"
|
||||
"psr-4": {
|
||||
"Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -35,58 +40,62 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Johannes Schmitt",
|
||||
"email": "schmittjoh@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
|
||||
"keywords": [
|
||||
"annotations",
|
||||
"docblock",
|
||||
"lexer",
|
||||
"parser"
|
||||
"parser",
|
||||
"php"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "egulias/email-validator",
|
||||
"version": "2.1.7",
|
||||
"version_normalized": "2.1.7.0",
|
||||
"version": "2.1.17",
|
||||
"version_normalized": "2.1.17.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/egulias/EmailValidator.git",
|
||||
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e"
|
||||
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e",
|
||||
"reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e",
|
||||
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a",
|
||||
"reference": "ade6887fd9bd74177769645ab5c474824f8a418a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/lexer": "^1.0.1",
|
||||
"php": ">= 5.5"
|
||||
"php": ">=5.5",
|
||||
"symfony/polyfill-intl-idn": "^1.10"
|
||||
},
|
||||
"require-dev": {
|
||||
"dominicsayers/isemail": "dev-master",
|
||||
"phpunit/phpunit": "^4.8.35||^5.7||^6.0",
|
||||
"dominicsayers/isemail": "^3.0.7",
|
||||
"phpunit/phpunit": "^4.8.36|^7.5.15",
|
||||
"satooshi/php-coveralls": "^1.0.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
|
||||
},
|
||||
"time": "2018-12-04T22:38:24+00:00",
|
||||
"time": "2020-02-13T22:36:52+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
"dev-master": "2.1.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -116,17 +125,17 @@
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.2.0",
|
||||
"version_normalized": "6.2.0.0",
|
||||
"version": "v6.2.3",
|
||||
"version_normalized": "6.2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swiftmailer/swiftmailer.git",
|
||||
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707"
|
||||
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
|
||||
"reference": "6fa3232ff9d3f8237c0fae4b7ff05e1baa4cd707",
|
||||
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
|
||||
"reference": "149cfdf118b169f7840bbe3ef0d4bc795d1780c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -144,7 +153,7 @@
|
||||
"ext-intl": "Needed to support internationalized email addresses",
|
||||
"true/punycode": "Needed to support internationalized email addresses, if ext-intl is not installed"
|
||||
},
|
||||
"time": "2019-03-10T07:52:41+00:00",
|
||||
"time": "2019-11-12T09:31:26+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
@@ -180,17 +189,17 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-iconv",
|
||||
"version": "v1.10.0",
|
||||
"version_normalized": "1.10.0.0",
|
||||
"version": "v1.15.0",
|
||||
"version_normalized": "1.15.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-iconv.git",
|
||||
"reference": "97001cfc283484c9691769f51cdf25259037eba2"
|
||||
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/97001cfc283484c9691769f51cdf25259037eba2",
|
||||
"reference": "97001cfc283484c9691769f51cdf25259037eba2",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
|
||||
"reference": "ad6d62792bfbcfc385dd34b424d4fcf9712a32c8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -199,11 +208,11 @@
|
||||
"suggest": {
|
||||
"ext-iconv": "For best performance"
|
||||
},
|
||||
"time": "2018-09-21T06:26:08+00:00",
|
||||
"time": "2020-03-09T19:04:49+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -237,36 +246,50 @@
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"version": "v1.10.0",
|
||||
"version_normalized": "1.10.0.0",
|
||||
"version": "v1.15.0",
|
||||
"version_normalized": "1.15.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-idn.git",
|
||||
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a"
|
||||
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
|
||||
"reference": "89de1d44f2c059b266f22c9cc9124ddc4cd0987a",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
|
||||
"reference": "47bd6aa45beb1cd7c6a16b7d1810133b728bdfcf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php72": "^1.9"
|
||||
"symfony/polyfill-php72": "^1.10"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
},
|
||||
"time": "2018-09-30T16:36:12+00:00",
|
||||
"time": "2020-03-09T19:04:49+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -283,13 +306,13 @@
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Laurent Bassin",
|
||||
"email": "laurent@bassin.info"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||
@@ -301,21 +324,35 @@
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.10.0",
|
||||
"version_normalized": "1.10.0.0",
|
||||
"version": "v1.15.0",
|
||||
"version_normalized": "1.15.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494"
|
||||
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"reference": "c79c051f5b3a46be09205c73b80b346e4153e494",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
|
||||
"reference": "81ffd3a9c6d707be22e3012b827de1c9775fc5ac",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -324,11 +361,11 @@
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"time": "2018-09-21T13:07:52+00:00",
|
||||
"time": "2020-03-09T19:04:49+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -362,31 +399,45 @@
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"version": "v1.10.0",
|
||||
"version_normalized": "1.10.0.0",
|
||||
"version": "v1.15.0",
|
||||
"version_normalized": "1.15.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php72.git",
|
||||
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631"
|
||||
"reference": "37b0976c78b94856543260ce09b460a7bc852747"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
|
||||
"reference": "9050816e2ca34a8e916c3a0ae8b9c2fccf68b631",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/37b0976c78b94856543260ce09b460a7bc852747",
|
||||
"reference": "37b0976c78b94856543260ce09b460a7bc852747",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"time": "2018-09-21T13:07:52+00:00",
|
||||
"time": "2020-02-27T09:26:54+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.9-dev"
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
@@ -419,6 +470,20 @@
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2006-2013 Doctrine Project
|
||||
Copyright (c) 2006-2018 Doctrine Project
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Doctrine Lexer
|
||||
|
||||
Build Status: [](https://travis-ci.org/doctrine/lexer)
|
||||
|
||||
Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
|
||||
|
||||
This lexer is used in Doctrine Annotations and in Doctrine ORM (DQL).
|
||||
|
||||
https://www.doctrine-project.org/projects/lexer.html
|
||||
|
||||
+23
-6
@@ -1,9 +1,15 @@
|
||||
{
|
||||
"name": "doctrine/lexer",
|
||||
"type": "library",
|
||||
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"keywords": ["lexer", "parser"],
|
||||
"homepage": "http://www.doctrine-project.org",
|
||||
"description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
|
||||
"keywords": [
|
||||
"php",
|
||||
"parser",
|
||||
"lexer",
|
||||
"annotations",
|
||||
"docblock"
|
||||
],
|
||||
"homepage": "https://www.doctrine-project.org/projects/lexer.html",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
|
||||
@@ -11,14 +17,25 @@
|
||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
"php": "^7.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpstan/phpstan": "^0.11.8",
|
||||
"phpunit/phpunit": "^8.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Doctrine\\Common\\Lexer\\": "lib/" }
|
||||
"psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" }
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "Doctrine\\Tests\\": "tests/Doctrine" }
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user