mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 15:29:57 +01:00
Merge branch 'release/1.0.9'
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -36,3 +36,8 @@ Thumbs.db
|
||||
# phpstorm
|
||||
.idea/*
|
||||
user/config/security.yaml
|
||||
|
||||
tests/_output/*
|
||||
tests/_support/_generated/*
|
||||
tests/cache/*
|
||||
tests/error.log
|
||||
|
||||
@@ -44,7 +44,7 @@ RewriteRule .* index.php [L]
|
||||
|
||||
## Begin - Security
|
||||
# Block all direct access for these folders
|
||||
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs)/(.*) error [F]
|
||||
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F]
|
||||
# Block access to specific file types for these system folders
|
||||
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
|
||||
# Block access to specific file types for these user folders
|
||||
@@ -52,7 +52,7 @@ RewriteRule ^(user)/(.*)\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
|
||||
# Block all direct access to .md files:
|
||||
RewriteRule \.md$ error [F]
|
||||
# Block all direct access to files and folders beginning with a dot
|
||||
RewriteRule (^\.|/\.) - [F]
|
||||
RewriteRule (^|/)\.(?!well-known) - [F]
|
||||
# Block access to specific files in the root folder
|
||||
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F]
|
||||
## End - Security
|
||||
|
||||
39
.travis.yml
39
.travis.yml
@@ -1,7 +1,12 @@
|
||||
language: php
|
||||
php: 5.6
|
||||
php:
|
||||
- '5.5'
|
||||
- '5.6'
|
||||
- '7.0'
|
||||
- hhvm
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- master
|
||||
- build_test
|
||||
notifications:
|
||||
@@ -13,8 +18,10 @@ notifications:
|
||||
rooms:
|
||||
- secure: "bqO0wM1B7bJnQw2fuhquSXEqI9gw6WmFytIh9sEWXzbYTzTUP5t0PcKOd3FT2BNMRaDxPJLVl+vG/oqmqDUBkEmOGcG504IQjeNzZqnMz0tXQMIcCc22Las9tFfc4Jf6RVi/qGomFtHGE9Wgii+TAN4zqZaufbNjwd8SyjO0+W8="
|
||||
template:
|
||||
- '%{repository}#%{build_number} (%{branch}): Grav Core and Skeletons packages have been uploaded. (<a href="%{build_url}">Details</a>)'
|
||||
- '%{repository}#%{build_number} (%{branch}): Travis Job Finished [%{duration}] (<a href="%{build_url}">Details</a>)'
|
||||
format: html
|
||||
slack:
|
||||
secure: dowksPsxxCxGKT6nis5hUgkp6+ZDAhoqzQHF9rJnx4hx0iEygPhVBs7pKl9yL2jubYJoLs+EXwE7z1dYgDAEJh4BnfrCokCMLpFGcxVxQC/HeAUdSQ2/RtdBYR5PRT75ScaFpqM/SfXXZVtnwVXAw9Z+JC6BjQ9vmn23m51Jw4k=
|
||||
env:
|
||||
global:
|
||||
# Colors!
|
||||
@@ -36,21 +43,31 @@ env:
|
||||
- secure: "einUtSEkUWy2IrqLXyVjwUU+mwaaoiOXRRVdLBpA3Zye6bZx8cm5h/5AplkPWhM/NmCJoW/MwNZHHkFhlr3mDRov5iOxVmTTYfnXB+I5lxYTSgduOLLErS7mU8hfADpVDU8bHNU44fNGD3UEiG1PD4qQBX4DMlqIFmR20mjs81k="
|
||||
# GH_API_USER [for curl]
|
||||
- secure: "Xbk/V9aIys0NxccJGR3Zrm2GRxDnA0RuazBs1puIboTYDhbi0Z7JTL+mOx3xp5Kfoniad/xAuijQESTM9MMrKqq/qCzhAMaC1+vcL4pCHZH4NSG6DBxB9BPkKVFq+1llu5FTEf8bkxHzwGR0l1ARW6TVRcgTHr5B58bCEIwEOrI="
|
||||
# Latest Release version
|
||||
- TRAVIS_TAG=$(curl --fail --user ${GH_API_USER} -s https://api.github.com/repos/getgrav/grav/releases/latest | grep tag_name | head -n 1 | cut -d '"' -f 4)
|
||||
|
||||
before_install:
|
||||
- export TZ=Pacific/Honolulu
|
||||
- composer self-update
|
||||
- go get github.com/aktau/github-release
|
||||
- echo "Travis Date - `date`"
|
||||
- git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
|
||||
- if [ ! -z "$TRAVIS_TAG" ]; then
|
||||
cd "${RT_DEVTOOLS}";
|
||||
./build-grav.sh skeletons.txt;
|
||||
- if [ $TRAVIS_BRANCH == 'develop' ] || [ $TRAVIS_PULL_REQUEST != 'false' ]; then
|
||||
composer install --dev --prefer-dist;
|
||||
fi
|
||||
- if [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == '5.6' ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then
|
||||
TRAVIS_TAG=$(curl --fail --user ${GH_API_USER} -s https://api.github.com/repos/getgrav/grav/releases/latest | grep tag_name | head -n 1 | cut -d '"' -f 4);
|
||||
go get github.com/aktau/github-release;
|
||||
git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
|
||||
if [ ! -z "$TRAVIS_TAG" ]; then
|
||||
cd ${RT_DEVTOOLS};
|
||||
./build-grav.sh skeletons.txt;
|
||||
fi;
|
||||
fi
|
||||
before_script:
|
||||
- if [ $TRAVIS_PHP_VERSION != 'hhvm' ]; then phpenv config-rm xdebug.ini; fi
|
||||
script:
|
||||
- if [ ! -z "$TRAVIS_TAG" ]; then
|
||||
- if [ $TRAVIS_BRANCH == 'develop' ] || [ $TRAVIS_PULL_REQUEST != 'false' ]; then
|
||||
vendor/bin/codecept run;
|
||||
else
|
||||
TRAVIS_TAG=$(curl --fail --user ${GH_API_USER} -s https://api.github.com/repos/getgrav/grav/releases/latest | grep tag_name | head -n 1 | cut -d '"' -f 4);
|
||||
fi
|
||||
- if [ ! -z "$TRAVIS_TAG" ] && [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == '5.6' ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then
|
||||
FILES="$RT_DEVTOOLS/grav-dist/*.zip";
|
||||
for file in ${FILES[@]}; do
|
||||
NAME=${file##*/};
|
||||
|
||||
52
CHANGELOG.md
52
CHANGELOG.md
@@ -1,10 +1,54 @@
|
||||
# v1.0.9
|
||||
## 02/05/2016
|
||||
|
||||
1. [](#new)
|
||||
* New **Unit Testing** via Codeception http://codeception.com/
|
||||
* New **page-level SSL** functionality when using `absolute_urls`
|
||||
* Added `reverse_proxy` config option for issues with non-standard ports
|
||||
* Added `proxy_url` config option to support GPM behind proxy servers #639
|
||||
* New `Pages::parentsRawRoutes()` method
|
||||
* Enhanced `bin/gpm info` CLI command with Changelog support #559
|
||||
* Ability to add empty *Folder* via admin plugin
|
||||
* Added latest `jQuery 2.2.0` library to core
|
||||
* Added translations from Crowdin
|
||||
1. [](#improved)
|
||||
* [BC] Metadata now supports only flat arrays. To use open graph metas and the likes (ie, 'og:title'), simply specify it in the key.
|
||||
* Refactored `Uri::convertUrl()` method to be more reliable + tests created
|
||||
* Date for last update of a modular sub-page sets modified date of modular page itself
|
||||
* Split configuration up into two steps
|
||||
* Moved Grav-based `base_uri` variables into `Uri::init()`
|
||||
* Refactored init in `URI` to better support testing
|
||||
* Allow `twig_vars` to be exposed earlier and merged later
|
||||
* Avoid setting empty metadata
|
||||
* Accept single group access as a string rather than requiring an array
|
||||
* Return `$this` in Page constructor and init to allow chaining
|
||||
* Added `ext-*` PHP requirements to `composer.json`
|
||||
* Use Whoops 2.0 library while supporting old style
|
||||
* Removed redundant old default-hash fallback mechanisms
|
||||
* Commented out default redirects and routes in `site.yaml`
|
||||
* Added `/tests` folder to deny's of all `webserver-configs/*` files
|
||||
* Various PS and code style fixes
|
||||
1. [](#bugfix)
|
||||
* Fix default generator metadata
|
||||
* Fix for broken image processing caused by `Uri::convertUrl()` bugs
|
||||
* Fix loading JS and CSS from collections #623
|
||||
* Fix stream overriding
|
||||
* Remove the URL extension for home link
|
||||
* Fix permissions when the user has no access level set at all
|
||||
* Fix issue with user with multiple groups getting denied on first group
|
||||
* Fixed an issue with `Pages()` internal cache lookup not being unique enough
|
||||
* Fix for bug with `site.redirects` and `site.routes` being an empty list
|
||||
* [Markdown] Don't process links for **special protocols**
|
||||
* [Whoops] serve JSON errors when request is JSON
|
||||
|
||||
|
||||
# v1.0.8
|
||||
## 01/08/2016
|
||||
|
||||
1. [](#new)
|
||||
* Added `rotate`, `flip` and `fixOrientation` image medium methods
|
||||
1. [](#bugfix)
|
||||
* Removed IP from Nonce generation. Should be more reliably in a variety of scenarios
|
||||
* Removed IP from Nonce generation. Should be more reliable in a variety of scenarios
|
||||
|
||||
# v1.0.7
|
||||
## 01/07/2016
|
||||
@@ -18,13 +62,13 @@
|
||||
* Added support for APCu and PHP7.0 via new Doctrine Cache release
|
||||
* Added global setting for `twig_first` processing (false by default)
|
||||
* New configuration options for Session settings #553
|
||||
1. [](#improved)
|
||||
1. [](#improved)
|
||||
* Switched to SSL for GPM calls
|
||||
* Use `URI->host()` for session domain
|
||||
* Add support for `open_basedir` when installing packages via GPM
|
||||
* Improved `Utils::generateNonceString()` method to handle reverse proxies
|
||||
* Optimized core thumbnails saving 38% in file size
|
||||
* Added new `bin/gpm index --installed-only` option
|
||||
* Added new `bin/gpm index --installed-only` option
|
||||
* Improved GPM errors to provider more helpful diagnostic of issues
|
||||
* Removed old hardcoded PHP version references
|
||||
* Moved `onPageContentProcessed()` event so it's fired more reliably
|
||||
@@ -34,7 +78,7 @@
|
||||
* Fixed an issue with cache/config checksum not being set on cache load
|
||||
* Fix for page blueprint and theme inheritance issue #534
|
||||
* Set `ZipBackup` timeout to 10 minutes if possible
|
||||
* Fix case where we only have inline data for CSS or JS #565
|
||||
* Fix case where we only have inline data for CSS or JS #565
|
||||
* Fix `bin/grav sandbox` command to work with new `webserver-config` folder
|
||||
* Fix for markdown attributes on external URLs
|
||||
* Fixed issue where `data:` page header was acting as `publish_date:`
|
||||
|
||||
15
README.md
15
README.md
@@ -1,4 +1,4 @@
|
||||
#  Grav
|
||||
#  Grav [](https://travis-ci.org/getgrav/grav)
|
||||
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [](https://gitter.im/getgrav/grav?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
@@ -100,11 +100,11 @@ What you mainly want to know is that:
|
||||
* [What is Grav?](http://learn.getgrav.org/basics/what-is-grav)
|
||||
* [Install](http://learn.getgrav.org/basics/installation) Grav in few seconds
|
||||
* Understand the [Configuration](http://learn.getgrav.org/basics/grav-configuration)
|
||||
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons#extras)
|
||||
* If you have questions, check out `#grav` on irc.freenode.net
|
||||
* Take a peek at our available free [Skeletons](http://getgrav.org/downloads/skeletons)
|
||||
* If you have questions, jump on our [Gitter Room](https://gitter.im/getgrav/grav)!
|
||||
* Have fun!
|
||||
|
||||
# Exploring more
|
||||
# Exploring More
|
||||
|
||||
* Have a look at our [Basic Tutorial](http://learn.getgrav.org/basics/basic-tutorial)
|
||||
* Dive into more [advanced](http://learn.getgrav.org/advanced) functions
|
||||
@@ -116,3 +116,10 @@ See [LICENSE](LICENSE.txt)
|
||||
|
||||
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
|
||||
[gitflow-extensions]: https://github.com/nvie/gitflow
|
||||
|
||||
# Running Tests
|
||||
|
||||
First install the dev dependencies by running `composer update` from the Grav root.
|
||||
Then `composer test` will run the Unit Tests, which should be always executed successfully on any site.
|
||||
|
||||
You can also run a single unit test file, e.g. `composer test tests/unit/Grav/Common/AssetsTest.php`
|
||||
|
||||
3
bin/gpm
3
bin/gpm
@@ -39,6 +39,7 @@ if (!function_exists('curl_version')) {
|
||||
|
||||
$grav = Grav::instance(array('loader' => $autoload));
|
||||
$grav['config']->init();
|
||||
$grav['uri']->init();
|
||||
$grav['streams'];
|
||||
|
||||
$app = new Application('Grav Package Manager', GRAV_VERSION);
|
||||
@@ -51,4 +52,6 @@ $app->addCommands(array(
|
||||
new \Grav\Console\Gpm\UpdateCommand(),
|
||||
new \Grav\Console\Gpm\SelfupgradeCommand(),
|
||||
));
|
||||
|
||||
$app->setDefaultCommand('index');
|
||||
$app->run();
|
||||
|
||||
10
bin/plugin
10
bin/plugin
@@ -107,10 +107,12 @@ try {
|
||||
exit;
|
||||
}
|
||||
|
||||
foreach ($commands as $command) {
|
||||
require_once "plugins://{$name}/cli/{$command}";
|
||||
$command = 'Grav\Plugin\Console\\' . preg_replace('/.php$/', '', $command);
|
||||
$app->add(new $command());
|
||||
foreach ($commands as $command_path) {
|
||||
require_once "plugins://{$name}/cli/{$command_path}";
|
||||
|
||||
$command_class = 'Grav\Plugin\Console\\' . preg_replace('/.php$/', '', $command_path);
|
||||
$command = new $command_class();
|
||||
$app->add($command);
|
||||
}
|
||||
|
||||
$app->run($input);
|
||||
|
||||
16
codeception.yml
Normal file
16
codeception.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
actor: Tester
|
||||
paths:
|
||||
tests: tests
|
||||
log: tests/_output
|
||||
data: tests/_data
|
||||
support: tests/_support
|
||||
envs: tests/_envs
|
||||
settings:
|
||||
bootstrap: _bootstrap.php
|
||||
colors: true
|
||||
memory_limit: 1024M
|
||||
extensions:
|
||||
enabled:
|
||||
- Codeception\Extension\RunFailed
|
||||
modules:
|
||||
config:
|
||||
@@ -7,7 +7,8 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=5.5.9",
|
||||
"twig/twig": "~1.23",
|
||||
"twig/twig": "~1.24",
|
||||
"erusev/parsedown": "dev-master as 1.6.0",
|
||||
"erusev/parsedown-extra": "~0.7",
|
||||
"symfony/yaml": "~2.8",
|
||||
"symfony/console": "~2.8",
|
||||
@@ -15,22 +16,22 @@
|
||||
"symfony/var-dumper": "~2.8",
|
||||
"symfony/polyfill-iconv": "~1.0",
|
||||
"doctrine/cache": "~1.5",
|
||||
"filp/whoops": "2.0.0-alpha2",
|
||||
"filp/whoops": "~2.0",
|
||||
"monolog/monolog": "~1.0",
|
||||
"gregwar/image": "~2.0",
|
||||
"ircmaxell/password-compat": "1.0.*",
|
||||
"mrclay/minify": "~2.2",
|
||||
"donatj/phpuseragentparser": "~0.3",
|
||||
"pimple/pimple": "~3.0",
|
||||
"rockettheme/toolbox": "~1.2",
|
||||
"maximebf/debugbar": "~1.10"
|
||||
"maximebf/debugbar": "~1.10",
|
||||
"ext-mbstring": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-curl": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.1",
|
||||
"fzaninotto/faker": "^1.5"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/getgrav/parsedown"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Grav\\": "system/src/Grav"
|
||||
@@ -41,7 +42,9 @@
|
||||
"exclude": ["VERSION"]
|
||||
},
|
||||
"scripts": {
|
||||
"post-create-project-cmd": "bin/grav install"
|
||||
"post-create-project-cmd": "bin/grav install",
|
||||
"test": "vendor/bin/codecept run unit",
|
||||
"test-windows": "vendor\\bin\\codecept run unit"
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
||||
1645
composer.lock
generated
1645
composer.lock
generated
File diff suppressed because it is too large
Load Diff
4
system/assets/jquery/jquery-2.x.min.js
vendored
Normal file
4
system/assets/jquery/jquery-2.x.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -848,6 +848,24 @@ form:
|
||||
underline: true
|
||||
|
||||
fields:
|
||||
proxy_url:
|
||||
type: text
|
||||
size: medium
|
||||
placeholder: "e.g. 127.0.0.1:3128"
|
||||
label: PLUGIN_ADMIN.PROXY_URL
|
||||
help: PLUGIN_ADMIN.PROXY_URL_HELP
|
||||
|
||||
reverse_proxy_setup:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.REVERSE_PROXY
|
||||
highlight: 0
|
||||
help: PLUGIN_ADMIN.REVERSE_PROXY_HELP
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
wrapped_site:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.WRAPPED_SITE
|
||||
|
||||
@@ -139,7 +139,7 @@ form:
|
||||
type: select
|
||||
label: PLUGIN_ADMIN.PARENT
|
||||
classes: fancy
|
||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
||||
'@data-options': '\Grav\Common\Page\Pages::parentsRawRoutes'
|
||||
'@data-default': '\Grav\Plugin\admin::route'
|
||||
options:
|
||||
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
|
||||
|
||||
35
system/blueprints/pages/new_folder.yaml
Normal file
35
system/blueprints/pages/new_folder.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
rules:
|
||||
slug:
|
||||
pattern: "[a-z][a-z0-9_\-]+"
|
||||
min: 2
|
||||
max: 80
|
||||
|
||||
form:
|
||||
validation: loose
|
||||
fields:
|
||||
|
||||
section:
|
||||
type: section
|
||||
title: PLUGIN_ADMIN.ADD_PAGE
|
||||
|
||||
folder:
|
||||
type: text
|
||||
label: PLUGIN_ADMIN.FOLDER_NAME
|
||||
help: PLUGIN_ADMIN.FOLDER_NAME_HELP
|
||||
validate:
|
||||
type: slug
|
||||
required: true
|
||||
|
||||
route:
|
||||
type: select
|
||||
label: PLUGIN_ADMIN.PARENT_PAGE
|
||||
classes: fancy
|
||||
'@data-options': '\Grav\Common\Page\Pages::parents'
|
||||
'@data-default': '\Grav\Plugin\admin::getLastPageRoute'
|
||||
options:
|
||||
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
|
||||
validate:
|
||||
required: true
|
||||
|
||||
blueprint:
|
||||
type: blueprint
|
||||
@@ -41,4 +41,4 @@ form:
|
||||
label: PLUGIN_ADMIN.SITE_ACCESS
|
||||
multiple: false
|
||||
validate:
|
||||
type: array
|
||||
type: array
|
||||
|
||||
@@ -16,12 +16,12 @@ summary:
|
||||
delimiter: === # The summary delimiter
|
||||
|
||||
redirects:
|
||||
/redirect-test: / # Redirect test goes to home page
|
||||
/old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
|
||||
# /redirect-test: / # Redirect test goes to home page
|
||||
# /old/(.*): /new/$1 # Would redirect /old/my-page to /new/my-page
|
||||
|
||||
routes:
|
||||
/something/else: '/blog/sample-3' # Alias for /blog/sample-3
|
||||
/new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
|
||||
# /something/else: '/blog/sample-3' # Alias for /blog/sample-3
|
||||
# /new/(.*): '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
|
||||
|
||||
blog:
|
||||
route: '/blog' # Custom value added (accessible via system.blog.route)
|
||||
|
||||
@@ -3,6 +3,8 @@ timezone: '' # Valid values: http://php.net/manua
|
||||
default_locale: # Default locale (defaults to system)
|
||||
param_sep: ':' # Parameter separator, use ';' for Apache on windows
|
||||
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
|
||||
reverse_proxy_setup: false # Running in a reverse proxy scenario with different webserver ports than proxy
|
||||
proxy_url: # Configure a manual proxy URL for GPM (eg 127.0.0.1:3128)
|
||||
|
||||
languages:
|
||||
supported: [] # List of languages supported. eg: [en, fr, de]
|
||||
@@ -85,7 +87,7 @@ assets: # Configuration for Assets Manager (
|
||||
js_minify: true # Minify the JS during pipelining
|
||||
enable_asset_timestamp: false # Enable asset timestamps
|
||||
collections:
|
||||
jquery: system://assets/jquery/jquery-2.1.4.min.js
|
||||
jquery: system://assets/jquery/jquery-2.x.min.js
|
||||
|
||||
errors:
|
||||
display: false # Display full backtrace-style error page
|
||||
@@ -113,4 +115,4 @@ session:
|
||||
timeout: 1800 # Timeout in seconds
|
||||
name: grav-site # Name prefix of the session cookie. Use alphanumeric, dashes or underscores only. Do not use dots in the session name
|
||||
secure: false # Set session secure. If true, indicates that communication for this cookie must be over an encrypted transmission. Enable this only on sites that run exclusively on HTTPS
|
||||
httponly: true # Set session HTTP only. If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed.
|
||||
httponly: true # Set session HTTP only. If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.0.8');
|
||||
define('GRAV_VERSION', '1.0.9');
|
||||
define('DS', '/');
|
||||
define('GRAV_PHP_MIN', '5.5.9');
|
||||
|
||||
|
||||
@@ -1,39 +1,80 @@
|
||||
---
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- vybavení
|
||||
- informace
|
||||
- rýže
|
||||
- peníze
|
||||
- druhy
|
||||
- série
|
||||
- ryba
|
||||
- ovce
|
||||
INFLECTOR_IRREGULAR:
|
||||
person: lidé
|
||||
man: muži
|
||||
child: děti
|
||||
sex: pohlaví
|
||||
move: pohyby
|
||||
INFLECTOR_ORDINALS:
|
||||
default: '.'
|
||||
first: '.'
|
||||
second: '.'
|
||||
third: '.'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Datum nebylo vloženo
|
||||
BAD_DATE: Chybné datum
|
||||
AGO: zpět
|
||||
FROM_NOW: od teď
|
||||
SECOND: sekunda
|
||||
MINUTE: minuta
|
||||
HOUR: hodina
|
||||
DAY: den
|
||||
WEEK: týden
|
||||
MONTH: měsíc
|
||||
YEAR: rok
|
||||
DECADE: dekáda
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: hod
|
||||
DAY: den
|
||||
WK: t
|
||||
MO: m
|
||||
YR: r
|
||||
DEC: dek
|
||||
SECOND_PLURAL: sekundy
|
||||
MINUTE_PLURAL: minuty
|
||||
HOUR_PLURAL: hodiny
|
||||
DAY_PLURAL: dny
|
||||
WEEK_PLURAL: týdny
|
||||
MONTH_PLURAL: měsíce
|
||||
YEAR_PLURAL: roky
|
||||
DECADE_PLURAL: dekády
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: hod
|
||||
DAY_PLURAL: dny
|
||||
WK_PLURAL: t
|
||||
MO_PLURAL: m
|
||||
YR_PLURAL: r
|
||||
DEC_PLURAL: dek
|
||||
MONTHS_OF_THE_YEAR: ['Leden', 'Únor', 'Březen', 'Duben', 'Květen', 'Červen', 'Červenec', 'Srpen', 'Září', 'Říjen', 'Listopad', 'Prosinec']
|
||||
DAYS_OF_THE_WEEK: ['Pondělí', 'Úterý', 'Středa', 'Čtvrtek', 'Pátek', 'Sobota', 'Neděle']
|
||||
NO_DATE_PROVIDED: Datum nebylo vloženo
|
||||
BAD_DATE: Chybné datum
|
||||
AGO: zpět
|
||||
FROM_NOW: od teď
|
||||
SECOND: sekunda
|
||||
MINUTE: minuta
|
||||
HOUR: hodina
|
||||
DAY: den
|
||||
WEEK: týden
|
||||
MONTH: měsíc
|
||||
YEAR: rok
|
||||
DECADE: dekáda
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: hod
|
||||
WK: t
|
||||
MO: m
|
||||
YR: r
|
||||
DEC: dek
|
||||
SECOND_PLURAL: sekundy
|
||||
MINUTE_PLURAL: minuty
|
||||
HOUR_PLURAL: hodiny
|
||||
DAY_PLURAL: dny
|
||||
WEEK_PLURAL: týdny
|
||||
MONTH_PLURAL: měsíce
|
||||
YEAR_PLURAL: roky
|
||||
DECADE_PLURAL: dekády
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: hod
|
||||
WK_PLURAL: t
|
||||
MO_PLURAL: m
|
||||
YR_PLURAL: r
|
||||
DEC_PLURAL: dek
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Ověření se nezdařilo:</b>'
|
||||
MISSING_REQUIRED_FIELD: 'Chybí požadované pole:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- ledna
|
||||
- února
|
||||
- března
|
||||
- dubna
|
||||
- května
|
||||
- června
|
||||
- července
|
||||
- srpna
|
||||
- září
|
||||
- října
|
||||
- listopadu
|
||||
- prosince
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Pondělí
|
||||
- Úterý
|
||||
- Středa
|
||||
- Čtvrtek
|
||||
- Pátek
|
||||
- Sobota
|
||||
- Neděle
|
||||
|
||||
@@ -1,45 +1,83 @@
|
||||
---
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
title: %1$s
|
||||
---
|
||||
# Fehler: Frontmatter enthält Fehler
|
||||
|
||||
Pfad: `%2$s`
|
||||
|
||||
**%3$s **
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
1: Informationen
|
||||
2: Reis
|
||||
3: Geld
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'Personen'
|
||||
'man': 'Menschen'
|
||||
'child': 'Kinder'
|
||||
'sex': 'Geschlecht'
|
||||
'move': 'Züge'
|
||||
person: Personen
|
||||
man: Menschen
|
||||
child: Kinder
|
||||
sex: Geschlecht
|
||||
move: Züge
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Keine Daten vorhanden
|
||||
BAD_DATE: Falsches Datum
|
||||
AGO: her
|
||||
FROM_NOW: ab jetzt
|
||||
SECOND: Sekunde
|
||||
MINUTE: Minute
|
||||
HOUR: Stunde
|
||||
DAY: Tag
|
||||
WEEK: Woche
|
||||
MONTH: Monat
|
||||
YEAR: Jahr
|
||||
DECADE: Dekade
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: std
|
||||
DAY: Tag
|
||||
WK: wo
|
||||
MO: mo
|
||||
YR: yh
|
||||
DEC: dec
|
||||
SECOND_PLURAL: Sekunden
|
||||
MINUTE_PLURAL: Minuten
|
||||
HOUR_PLURAL: Stunden
|
||||
DAY_PLURAL: Tage
|
||||
WEEK_PLURAL: Wochen
|
||||
MONTH_PLURAL: Monate
|
||||
YEAR_PLURAL: Jahre
|
||||
DECADE_PLURAL: Dekaden
|
||||
SEC_PLURAL: Sekunden
|
||||
MIN_PLURAL: Minuten
|
||||
HR_PLURAL: Stunden
|
||||
DAY_PLURAL: Tage
|
||||
WK_PLURAL: Wochen
|
||||
MO_PLURAL: Monate
|
||||
YR_PLURAL: Jahre
|
||||
DEC_PLURAL: Dekaden
|
||||
MONTHS_OF_THE_YEAR: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember']
|
||||
DAYS_OF_THE_WEEK: ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag']
|
||||
NO_DATE_PROVIDED: Keine Daten vorhanden
|
||||
BAD_DATE: Falsches Datum
|
||||
AGO: her
|
||||
FROM_NOW: ab jetzt
|
||||
SECOND: Sekunde
|
||||
MINUTE: Minute
|
||||
HOUR: Stunde
|
||||
DAY: Tag
|
||||
WEEK: Woche
|
||||
MONTH: Monat
|
||||
YEAR: Jahr
|
||||
DECADE: Dekade
|
||||
SEC: sek
|
||||
MIN: Min
|
||||
HR: std
|
||||
WK: wo
|
||||
YR: yh
|
||||
DEC: Jz
|
||||
SECOND_PLURAL: Sekunden
|
||||
MINUTE_PLURAL: Minuten
|
||||
HOUR_PLURAL: Stunden
|
||||
DAY_PLURAL: Tage
|
||||
WEEK_PLURAL: Wochen
|
||||
MONTH_PLURAL: Monate
|
||||
YEAR_PLURAL: Jahre
|
||||
DECADE_PLURAL: Dekaden
|
||||
SEC_PLURAL: Sekunden
|
||||
MIN_PLURAL: Minuten
|
||||
HR_PLURAL: Stunden
|
||||
WK_PLURAL: Wochen
|
||||
MO_PLURAL: Monate
|
||||
YR_PLURAL: Jahre
|
||||
DEC_PLURAL: Dekaden
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Überprüfung fehlgeschlagen:</b>'
|
||||
INVALID_INPUT: Ungültige Eingabe in
|
||||
MISSING_REQUIRED_FIELD: 'Erforderliches Feld fehlt:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Januar
|
||||
- Februar
|
||||
- März
|
||||
- April
|
||||
- Mai
|
||||
- Juni
|
||||
- Juli
|
||||
- August
|
||||
- Semptember
|
||||
- Oktober
|
||||
- November
|
||||
- Dezember
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Montag
|
||||
- Dienstag
|
||||
- Mittwoch
|
||||
- Donnerstag
|
||||
- Freitag
|
||||
- Samstag
|
||||
- Sonntag
|
||||
|
||||
@@ -1,2 +1,22 @@
|
||||
MONTHS_OF_THE_YEAR: ['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος']
|
||||
DAYS_OF_THE_WEEK: ['Δευτέρα', 'Τρλιτη', 'Τετάρτη', 'Πέμπτη', 'Παρασκευή', 'Σαββάτο', 'Κυριακή']
|
||||
---
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Ιανουάριος
|
||||
- Φεβρουάριος
|
||||
- Μάρτιος
|
||||
- Απρίλιος
|
||||
- Μάιος
|
||||
- Ιούνιος
|
||||
- Ιούλιος
|
||||
- Αύγουστος
|
||||
- Σεπτέμβριος
|
||||
- Οκτώβριος
|
||||
- Νοέμβριος
|
||||
- Δεκέμβριος
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Δευτέρα
|
||||
- Τρλιτη
|
||||
- Τετάρτη
|
||||
- Πέμπτη
|
||||
- Παρασκευή
|
||||
- Σαββάτο
|
||||
- Κυριακή
|
||||
|
||||
@@ -1,44 +1,76 @@
|
||||
---
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
0: equipo
|
||||
1: información
|
||||
3: dinero
|
||||
5: series
|
||||
6: pescado
|
||||
7: oveja
|
||||
INFLECTOR_IRREGULAR:
|
||||
man: hombres
|
||||
child: niños
|
||||
sex: sexos
|
||||
INFLECTOR_ORDINALS:
|
||||
first: ro
|
||||
second: do
|
||||
third: ro
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: No se proporcionó fecha
|
||||
BAD_DATE: Fecha erronea
|
||||
AGO: antes
|
||||
FROM_NOW: desde ahora
|
||||
SECOND: segundo
|
||||
MINUTE: minuto
|
||||
HOUR: hora
|
||||
DAY: dia
|
||||
WEEK: semana
|
||||
MONTH: mes
|
||||
YEAR: año
|
||||
DECADE: decada
|
||||
SEC: seg
|
||||
MIN: min
|
||||
HR: hr
|
||||
DAY: dia
|
||||
WK: sem
|
||||
MO: mes
|
||||
YR: yr
|
||||
DEC: dec
|
||||
SECOND_PLURAL: segundos
|
||||
MINUTE_PLURAL: minutos
|
||||
HOUR_PLURAL: horas
|
||||
DAY_PLURAL: días
|
||||
WEEK_PLURAL: semanas
|
||||
MONTH_PLURAL: meses
|
||||
YEAR_PLURAL: años
|
||||
DECADE_PLURAL: decadas
|
||||
SEC_PLURAL: segs
|
||||
MIN_PLURAL: mins
|
||||
HR_PLURAL: hrs
|
||||
DAY_PLURAL: dias
|
||||
WK_PLURAL: sem
|
||||
MO_PLURAL: mes
|
||||
YR_PLURAL: años
|
||||
DEC_PLURAL: decs
|
||||
NO_DATE_PROVIDED: No se proporcionó fecha
|
||||
BAD_DATE: Fecha erronea
|
||||
AGO: antes
|
||||
FROM_NOW: desde ahora
|
||||
SECOND: segundo
|
||||
MINUTE: minuto
|
||||
HOUR: hora
|
||||
DAY: día
|
||||
WEEK: semana
|
||||
MONTH: mes
|
||||
YEAR: año
|
||||
DECADE: década
|
||||
SEC: seg
|
||||
MIN: min
|
||||
HR: h
|
||||
WK: sem
|
||||
MO: mes
|
||||
YR: año
|
||||
DEC: dec
|
||||
SECOND_PLURAL: segundos
|
||||
MINUTE_PLURAL: minutos
|
||||
HOUR_PLURAL: horas
|
||||
DAY_PLURAL: días
|
||||
WEEK_PLURAL: semanas
|
||||
MONTH_PLURAL: meses
|
||||
YEAR_PLURAL: años
|
||||
DECADE_PLURAL: décadas
|
||||
SEC_PLURAL: segs
|
||||
MIN_PLURAL: mins
|
||||
HR_PLURAL: hs
|
||||
WK_PLURAL: sem
|
||||
MO_PLURAL: mes
|
||||
YR_PLURAL: años
|
||||
DEC_PLURAL: décadas
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>Falló la validación. </b>
|
||||
INVALID_INPUT: "Dato inválido en: "
|
||||
MISSING_REQUIRED_FIELD: "Falta el campo requerido: "
|
||||
MONTHS_OF_THE_YEAR: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Augosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']
|
||||
DAYS_OF_THE_WEEK: ['Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo']
|
||||
|
||||
VALIDATION_FAIL: '<b>Falló la validación. </b>'
|
||||
INVALID_INPUT: 'Dato inválido en: '
|
||||
MISSING_REQUIRED_FIELD: 'Falta el campo requerido: '
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Enero
|
||||
- Febrero
|
||||
- Marzo
|
||||
- Abril
|
||||
- Mayo
|
||||
- Junio
|
||||
- Julio
|
||||
- Agosto
|
||||
- Septiembre
|
||||
- Octubre
|
||||
- Noviembre
|
||||
- Diciembre
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Lunes
|
||||
- Martes
|
||||
- Miércoles
|
||||
- Jueves
|
||||
- Viernes
|
||||
- Sábado
|
||||
- Domingo
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
MONTHSOFTHE_YEAR: ['Tammikuu', 'Helmikuu', 'Maaliskuu', 'Huhtikuu', 'Toukokuu', 'Kesäkuu', 'Heinäkuu', 'Elokuu', 'Syyskuu', 'Lokakuu', 'Marraskuu', 'Joulukuu']
|
||||
DAYSOFTHE_WEEK: ['Maanantai', 'Tiistai', 'Keskiviikko', 'Torstai', 'Perjantai', 'Lauantai', 'Sunnuntai']
|
||||
---
|
||||
|
||||
@@ -1,100 +1,138 @@
|
||||
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Erreur : Frontmatter invalide\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
---
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
title: %1$s
|
||||
---
|
||||
|
||||
# Erreur : Frontmatter invalide
|
||||
|
||||
Path: `%2$s`
|
||||
|
||||
**%3$s**
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
INFLECTOR_PLURALS:
|
||||
'/(quiz)$/i': '\1zes'
|
||||
'/^(ox)$/i': '\1en'
|
||||
'/([m|l])ouse$/i': '\1ice'
|
||||
'/(matr|vert|ind)ix|ex$/i': '\1ices'
|
||||
'/(x|ch|ss|sh)$/i': '\1es'
|
||||
'/([^aeiouy]|qu)ies$/i': '\1y'
|
||||
'/([^aeiouy]|qu)y$/i': '\1ies'
|
||||
'/(hive)$/i': '\1s'
|
||||
'/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
|
||||
'/sis$/i': 'ses'
|
||||
'/([ti])um$/i': '\1a'
|
||||
'/(buffal|tomat)o$/i': '\1oes'
|
||||
'/(bu)s$/i': '\1ses'
|
||||
'/(alias|status)/i': '\1es'
|
||||
'/(octop|vir)us$/i': '\1i'
|
||||
'/(ax|test)is$/i': '\1es'
|
||||
'/s$/i': 's'
|
||||
'/$/': 's'
|
||||
/(quiz)$/i: '\1zes'
|
||||
/^(ox)$/i: '\1en'
|
||||
"/([m|l])ouse$/i": '\1ice'
|
||||
/(matr|vert|ind)ix|ex$/i: '\1ices'
|
||||
/(x|ch|ss|sh)$/i: '\1es'
|
||||
"/([^aeiouy]|qu)ies$/i": '\1y'
|
||||
"/([^aeiouy]|qu)y$/i": '\1ies'
|
||||
/(hive)$/i: '\1s'
|
||||
"/(?:([^f])fe|([lr])f)$/i": '\1\2ves'
|
||||
/sis$/i: ses
|
||||
"/([ti])um$/i": '\1a'
|
||||
/(buffal|tomat)o$/i: '\1oes'
|
||||
/(bu)s$/i: '\1ses'
|
||||
/(alias|status)/i: '\1es'
|
||||
/(octop|vir)us$/i: '\1i'
|
||||
/(ax|test)is$/i: '\1es'
|
||||
/s$/i: s
|
||||
/$/: s
|
||||
INFLECTOR_SINGULAR:
|
||||
'/(quiz)zes$/i': '\1'
|
||||
'/(matr)ices$/i': '\1ix'
|
||||
'/(vert|ind)ices$/i': '\1ex'
|
||||
'/^(ox)en/i': '\1'
|
||||
'/(alias|status)es$/i': '\1'
|
||||
'/([octop|vir])i$/i': '\1us'
|
||||
'/(cris|ax|test)es$/i': '\1is'
|
||||
'/(shoe)s$/i': '\1'
|
||||
'/(o)es$/i': '\1'
|
||||
'/(bus)es$/i': '\1'
|
||||
'/([m|l])ice$/i': '\1ouse'
|
||||
'/(x|ch|ss|sh)es$/i': '\1'
|
||||
'/(m)ovies$/i': '\1ovie'
|
||||
'/(s)eries$/i': '\1eries'
|
||||
'/([^aeiouy]|qu)ies$/i': '\1y'
|
||||
'/([lr])ves$/i': '\1f'
|
||||
'/(tive)s$/i': '\1'
|
||||
'/(hive)s$/i': '\1'
|
||||
'/([^f])ves$/i': '\1fe'
|
||||
'/(^analy)ses$/i': '\1sis'
|
||||
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
|
||||
'/([ti])a$/i': '\1um'
|
||||
'/(n)ews$/i': '\1ews'
|
||||
'/s$/i': ''
|
||||
INFLECTOR_UNCOUNTABLE: ['équipement', 'information', 'riz', 'argent', 'espèces', 'séries', 'poisson', 'mouton']
|
||||
/(quiz)zes$/i: '\1'
|
||||
/(matr)ices$/i: '\1ix'
|
||||
/(vert|ind)ices$/i: '\1ex'
|
||||
/^(ox)en/i: '\1'
|
||||
/(alias|status)es$/i: '\1'
|
||||
"/([octop|vir])i$/i": '\1us'
|
||||
/(cris|ax|test)es$/i: '\1is'
|
||||
/(shoe)s$/i: '\1'
|
||||
/(o)es$/i: '\1'
|
||||
/(bus)es$/i: '\1'
|
||||
"/([m|l])ice$/i": '\1ouse'
|
||||
/(x|ch|ss|sh)es$/i: '\1'
|
||||
/(m)ovies$/i: '\1ovie'
|
||||
/(s)eries$/i: '\1eries'
|
||||
"/([^aeiouy]|qu)ies$/i": '\1y'
|
||||
"/([lr])ves$/i": '\1f'
|
||||
/(tive)s$/i: '\1'
|
||||
/(hive)s$/i: '\1'
|
||||
"/([^f])ves$/i": '\1fe'
|
||||
/(^analy)ses$/i: '\1sis'
|
||||
/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i: '\1\2sis'
|
||||
"/([ti])a$/i": '\1um'
|
||||
/(n)ews$/i: '\1ews'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- équipement
|
||||
- informations
|
||||
- riz
|
||||
- argent
|
||||
- espèces
|
||||
- séries
|
||||
- poisson
|
||||
- mouton
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'personnes'
|
||||
'man': 'hommes'
|
||||
'child': 'enfants'
|
||||
'sex': 'sexes'
|
||||
'move': 'déplacements'
|
||||
person: personnes
|
||||
man: hommes
|
||||
child: enfants
|
||||
sex: sexes
|
||||
move: déplacements
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': 'ème'
|
||||
'first': 'er'
|
||||
'second': 'nd'
|
||||
'third': 'ème'
|
||||
default: ème
|
||||
first: er
|
||||
second: ème
|
||||
third: ème
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Aucune date
|
||||
BAD_DATE: Date erronée
|
||||
AGO: plus tôt
|
||||
FROM_NOW: à partir de maintenant
|
||||
SECOND: seconde
|
||||
MINUTE: minute
|
||||
HOUR: heure
|
||||
DAY: jour
|
||||
WEEK: semaine
|
||||
MONTH: mois
|
||||
YEAR: an
|
||||
DECADE: décennie
|
||||
SEC: s
|
||||
MIN: m
|
||||
HR: h
|
||||
DAY: j
|
||||
WK: s
|
||||
MO: m
|
||||
YR: a
|
||||
DEC: d
|
||||
SECOND_PLURAL: secondes
|
||||
MINUTE_PLURAL: minutes
|
||||
HOUR_PLURAL: heures
|
||||
DAY_PLURAL: jours
|
||||
WEEK_PLURAL: semaines
|
||||
MONTH_PLURAL: mois
|
||||
YEAR_PLURAL: années
|
||||
DECADE_PLURAL: décennies
|
||||
SEC_PLURAL: s
|
||||
MIN_PLURAL: m
|
||||
HR_PLURAL: h
|
||||
DAY_PLURAL: j
|
||||
WK_PLURAL: s
|
||||
MO_PLURAL: m
|
||||
YR_PLURAL: a
|
||||
DEC_PLURAL: d
|
||||
NO_DATE_PROVIDED: Aucune date fournie
|
||||
BAD_DATE: Date erronée
|
||||
AGO: plus tôt
|
||||
FROM_NOW: à partir de maintenant
|
||||
SECOND: seconde
|
||||
MINUTE: minute
|
||||
HOUR: heure
|
||||
DAY: jour
|
||||
WEEK: semaine
|
||||
MONTH: mois
|
||||
YEAR: année
|
||||
DECADE: décennie
|
||||
SEC: s
|
||||
MIN: m
|
||||
HR: h
|
||||
WK: sem
|
||||
MO: m
|
||||
YR: an
|
||||
DEC: déc
|
||||
SECOND_PLURAL: secondes
|
||||
MINUTE_PLURAL: minutes
|
||||
HOUR_PLURAL: heures
|
||||
DAY_PLURAL: jours
|
||||
WEEK_PLURAL: semaines
|
||||
MONTH_PLURAL: mois
|
||||
YEAR_PLURAL: années
|
||||
DECADE_PLURAL: décennies
|
||||
SEC_PLURAL: s
|
||||
MIN_PLURAL: m
|
||||
HR_PLURAL: h
|
||||
WK_PLURAL: sem
|
||||
MO_PLURAL: mois
|
||||
YR_PLURAL: a
|
||||
DEC_PLURAL: décs
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>La validation a échoué :</b>
|
||||
INVALID_INPUT: Saisie non valide
|
||||
MISSING_REQUIRED_FIELD: Champ obligatoire manquant :
|
||||
MONTHS_OF_THE_YEAR: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre']
|
||||
DAYS_OF_THE_WEEK: ['Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi', 'Dimanche']
|
||||
VALIDATION_FAIL: '<b>La validation a échoué :</b>'
|
||||
INVALID_INPUT: Saisie non valide
|
||||
MISSING_REQUIRED_FIELD: 'Champ obligatoire manquant :'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Janvier
|
||||
- Février
|
||||
- Mars
|
||||
- Avril
|
||||
- Mai
|
||||
- Juin
|
||||
- Juillet
|
||||
- Août
|
||||
- Septembre
|
||||
- Octobre
|
||||
- Novembre
|
||||
- Décembre
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Lundi
|
||||
- Mardi
|
||||
- Mercredi
|
||||
- Jeudi
|
||||
- Vendredi
|
||||
- Samedi
|
||||
- Dimanche
|
||||
|
||||
@@ -1,52 +1,75 @@
|
||||
---
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- oprema
|
||||
- informacije
|
||||
- riža
|
||||
- novac
|
||||
- vrsta
|
||||
- serija
|
||||
- riba
|
||||
- ovca
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'Osoba'
|
||||
'man': 'Čovjek'
|
||||
'child': 'Dijete'
|
||||
'sex': 'Spol'
|
||||
'move': 'Pomakni'
|
||||
person: osobe
|
||||
man: ljudi
|
||||
child: djeca
|
||||
sex: spolovi
|
||||
move: Pomakni
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Datum nije upisan
|
||||
BAD_DATE: Pogrešan datum
|
||||
AGO: prije
|
||||
FROM_NOW: od sad
|
||||
SECOND: sekundi
|
||||
MINUTE: minuta
|
||||
HOUR: godina
|
||||
DAY: dan
|
||||
WEEK: tjedan
|
||||
MONTH: mjesec
|
||||
YEAR: godina
|
||||
DECADE: desetljeće
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: sat
|
||||
DAY: dan
|
||||
WK: t
|
||||
MO: m
|
||||
YR: g
|
||||
DEC: des
|
||||
SECOND_PLURAL: sekundi
|
||||
SECOND_PLURAL_MORE_THAN_TWO: sekunde
|
||||
MINUTE_PLURAL: minuta
|
||||
MINUTE_PLURAL_MORE_THAN_TWO: minute
|
||||
HOUR_PLURAL: sati
|
||||
HOUR_PLURAL_MORE_THAN_TWO: sata
|
||||
DAY_PLURAL: dana
|
||||
WEEK_PLURAL: tjedana
|
||||
WEEK_PLURAL_MORE_THAN_TWO: tjedna
|
||||
MONTH_PLURAL: mjeseci
|
||||
MONTH_PLURAL_MORE_THAN_TWO: mjeseca
|
||||
YEAR_PLURAL: godina
|
||||
YEAR_PLURAL_MORE_THAN_TWO: godine
|
||||
DECADE_PLURAL: desetljeća
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: sat
|
||||
DAY_PLURAL: dan
|
||||
WK_PLURAL: t
|
||||
MO_PLURAL: m
|
||||
YR_PLURAL: g
|
||||
DEC_PLURAL: des
|
||||
NO_DATE_PROVIDED: Datum nije upisan
|
||||
BAD_DATE: Pogrešan datum
|
||||
AGO: prije
|
||||
FROM_NOW: od sada
|
||||
SECOND: sekunda
|
||||
MINUTE: minuta
|
||||
HOUR: sat
|
||||
DAY: dan
|
||||
WEEK: tjedan
|
||||
MONTH: mjesec
|
||||
YEAR: godina
|
||||
DECADE: desetljeće
|
||||
SEC: sek
|
||||
HR: sat
|
||||
WK: t
|
||||
MO: m
|
||||
YR: g
|
||||
DEC: des
|
||||
SECOND_PLURAL: sekundi
|
||||
MINUTE_PLURAL: minuta
|
||||
HOUR_PLURAL: sati
|
||||
DAY_PLURAL: dan
|
||||
WEEK_PLURAL: tjedana
|
||||
MONTH_PLURAL: mjeseci
|
||||
YEAR_PLURAL: godina
|
||||
DECADE_PLURAL: desetljeća
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: sat
|
||||
WK_PLURAL: t
|
||||
MO_PLURAL: m
|
||||
YR_PLURAL: g
|
||||
DEC_PLURAL: des
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>Validacija nije uspjela:</b>
|
||||
INVALID_INPUT: Unos nije valjan
|
||||
VALIDATION_FAIL: '<b>Validacija nije uspjela:</b>'
|
||||
INVALID_INPUT: Pogrešan unos u
|
||||
MISSING_REQUIRED_FIELD: 'Nedostaje obavezno polje:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Siječanj
|
||||
- Veljača
|
||||
- Ožujak
|
||||
- Travanj
|
||||
- Svibanj
|
||||
- Lipanj
|
||||
- Srpanj
|
||||
- Kolovoz
|
||||
- Rujan
|
||||
- Listopad
|
||||
- Studeni
|
||||
- Prosinac
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Ponedjeljak
|
||||
- Utorak
|
||||
- Srijeda
|
||||
- Četvrtak
|
||||
- Petak
|
||||
- Subota
|
||||
- Nedjelja
|
||||
|
||||
@@ -1,53 +1,65 @@
|
||||
FRONTMATTER_ERROR_PAGE: "---\ncím: %1$s\n---\n\n# Hiba: Érvénytelen Frontmatter\n\nElérési út: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
|
||||
---
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
cím: %1$s
|
||||
---
|
||||
|
||||
# Hiba: Érvénytelen Frontmatter
|
||||
|
||||
Elérési út: `%2$s`
|
||||
|
||||
**%3$s**
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'személyek'
|
||||
'man': 'férfiak'
|
||||
'child': 'gyerekek'
|
||||
'sex': 'nemek'
|
||||
'move': 'lépések'
|
||||
person: személyek
|
||||
man: férfiak
|
||||
child: gyerekek
|
||||
sex: nemek
|
||||
move: lépések
|
||||
INFLECTOR_ORDINALS:
|
||||
'default': '.'
|
||||
'first': '.'
|
||||
'second': '.'
|
||||
'third': '.'
|
||||
default: '.'
|
||||
first: '.'
|
||||
second: '.'
|
||||
third: '.'
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Nincs dátum megadva
|
||||
BAD_DATE: Hibás dátum
|
||||
AGO: elteltével
|
||||
FROM_NOW: mostantól
|
||||
SECOND: másodperc
|
||||
MINUTE: perc
|
||||
HOUR: óra
|
||||
DAY: nap
|
||||
WEEK: hét
|
||||
MONTH: hónap
|
||||
YEAR: év
|
||||
DECADE: évtized
|
||||
SEC: mp
|
||||
MIN: p
|
||||
HR: ó
|
||||
DAY: nap
|
||||
WK: hét
|
||||
MO: hó
|
||||
YR: év
|
||||
DEC: évt
|
||||
SECOND_PLURAL: másodperc
|
||||
MINUTE_PLURAL: perc
|
||||
HOUR_PLURAL: óra
|
||||
DAY_PLURAL: nap
|
||||
WEEK_PLURAL: hét
|
||||
MONTH_PLURAL: hónap
|
||||
YEAR_PLURAL: év
|
||||
DECADE_PLURAL: évtized
|
||||
SEC_PLURAL: mp
|
||||
MIN_PLURAL: perc
|
||||
HR_PLURAL: ó
|
||||
DAY_PLURAL: nap
|
||||
WK_PLURAL: hét
|
||||
MO_PLURAL: hó
|
||||
YR_PLURAL: év
|
||||
DEC_PLURAL: évt
|
||||
NO_DATE_PROVIDED: Nincs dátum megadva
|
||||
BAD_DATE: Hibás dátum
|
||||
AGO: elteltével
|
||||
FROM_NOW: mostantól
|
||||
SECOND: másodperc
|
||||
MINUTE: perc
|
||||
HOUR: óra
|
||||
DAY: nap
|
||||
WEEK: hét
|
||||
MONTH: hónap
|
||||
YEAR: év
|
||||
DECADE: évtized
|
||||
SEC: mp
|
||||
MIN: p
|
||||
HR: ó
|
||||
WK: hét
|
||||
MO: hó
|
||||
YR: év
|
||||
DEC: évt
|
||||
SECOND_PLURAL: másodperc
|
||||
MINUTE_PLURAL: perc
|
||||
HOUR_PLURAL: óra
|
||||
DAY_PLURAL: nap
|
||||
WEEK_PLURAL: hét
|
||||
MONTH_PLURAL: hónap
|
||||
YEAR_PLURAL: év
|
||||
DECADE_PLURAL: évtized
|
||||
SEC_PLURAL: mp
|
||||
MIN_PLURAL: perc
|
||||
HR_PLURAL: ó
|
||||
WK_PLURAL: hét
|
||||
MO_PLURAL: hó
|
||||
YR_PLURAL: év
|
||||
DEC_PLURAL: évt
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>A validáció hibát talált:</b>
|
||||
INVALID_INPUT: Az itt megadott érték érvénytelen:
|
||||
MISSING_REQUIRED_FIELD: Ez a kötelező mező nincs kitöltve:
|
||||
VALIDATION_FAIL: '<b>A validáció hibát talált:</b>'
|
||||
INVALID_INPUT: 'Az itt megadott érték érvénytelen:'
|
||||
MISSING_REQUIRED_FIELD: 'Ez a kötelező mező nincs kitöltve:'
|
||||
|
||||
@@ -1,27 +1,46 @@
|
||||
---
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Nessuna data fornita
|
||||
BAD_DATE: Data errata
|
||||
AGO: fa
|
||||
FROM_NOW: da adesso
|
||||
SECOND: secondo
|
||||
MINUTE: minuto
|
||||
HOUR: ora
|
||||
DAY: giorno
|
||||
WEEK: settimana
|
||||
MONTH: mese
|
||||
YEAR: anno
|
||||
DECADE: decade
|
||||
SECOND_PLURAL: secondi
|
||||
MINUTE_PLURAL: minuti
|
||||
HOUR_PLURAL: ore
|
||||
DAY_PLURAL: giorni
|
||||
WEEK_PLURAL: settimane
|
||||
MONTH_PLURAL: mesi
|
||||
YEAR_PLURAL: anni
|
||||
DECADE_PLURAL: decadi
|
||||
NO_DATE_PROVIDED: Nessuna data fornita
|
||||
BAD_DATE: Data errata
|
||||
AGO: fa
|
||||
FROM_NOW: da adesso
|
||||
SECOND: secondo
|
||||
MINUTE: minuto
|
||||
HOUR: ora
|
||||
DAY: giorno
|
||||
WEEK: settimana
|
||||
MONTH: mese
|
||||
YEAR: anno
|
||||
SECOND_PLURAL: secondi
|
||||
MINUTE_PLURAL: minuti
|
||||
HOUR_PLURAL: ore
|
||||
DAY_PLURAL: giorni
|
||||
WEEK_PLURAL: settimane
|
||||
MONTH_PLURAL: mesi
|
||||
YEAR_PLURAL: anni
|
||||
DECADE_PLURAL: decadi
|
||||
FORM:
|
||||
VALIDATION_FAIL: <b>Validazione fallita:</b>
|
||||
INVALID_INPUT: Input invalido in
|
||||
MISSING_REQUIRED_FIELD: Campo richiesto mancante:
|
||||
MONTHS_OF_THE_YEAR: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre']
|
||||
DAYS_OF_THE_WEEK: ['Lunedi', 'Martedi', 'Mercoledi', 'Giovedi', 'Venerdi', 'Sabato', 'Domenica']
|
||||
VALIDATION_FAIL: '<b>Validazione fallita:</b>'
|
||||
INVALID_INPUT: Input invalido in
|
||||
MISSING_REQUIRED_FIELD: 'Campo richiesto mancante:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Gennaio
|
||||
- Febbraio
|
||||
- Marzo
|
||||
- Aprile
|
||||
- Maggio
|
||||
- Giugno
|
||||
- Luglio
|
||||
- Agosto
|
||||
- Settembre
|
||||
- Ottobre
|
||||
- Novembre
|
||||
- Dicembre
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Lunedi
|
||||
- Martedi
|
||||
- Mercoledi
|
||||
- Giovedi
|
||||
- Venerdi
|
||||
- Sabato
|
||||
- Domenica
|
||||
|
||||
69
system/languages/lt.yaml
Normal file
69
system/languages/lt.yaml
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
2: ryžiai
|
||||
3: pinigai
|
||||
4: prieskoniai
|
||||
5: serijos
|
||||
6: žuvis
|
||||
7: avis
|
||||
INFLECTOR_IRREGULAR:
|
||||
person: žmonės
|
||||
man: žmogus
|
||||
child: vaikai
|
||||
sex: lytys
|
||||
move: juda
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Nenurodyta data
|
||||
BAD_DATE: Neteisinga data
|
||||
AGO: prieš
|
||||
FROM_NOW: nuo dabar
|
||||
SECOND: sekundė
|
||||
MINUTE: minutė
|
||||
HOUR: valanda
|
||||
DAY: diena
|
||||
WEEK: savaitė
|
||||
MONTH: mėnuo
|
||||
YEAR: metai
|
||||
DECADE: dešimtmetis
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: val
|
||||
WK: sav
|
||||
MO: mėn
|
||||
YR: m
|
||||
MINUTE_PLURAL: minutės
|
||||
HOUR_PLURAL: valandos
|
||||
DAY_PLURAL: dienos
|
||||
WEEK_PLURAL: savaitės
|
||||
MONTH_PLURAL: mėnesiai
|
||||
YEAR_PLURAL: metai
|
||||
DECADE_PLURAL: dešimtmečiai
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: val
|
||||
WK_PLURAL: sav
|
||||
MO_PLURAL: mėn
|
||||
YR_PLURAL: m
|
||||
FORM:
|
||||
MISSING_REQUIRED_FIELD: 'Būtina užpildyti laukelį:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Sausis
|
||||
- Vasaris
|
||||
- Kovas
|
||||
- Balandis
|
||||
- Gegužė
|
||||
- Birželis
|
||||
- Liepa
|
||||
- Rugpjūtis
|
||||
- Rugsėjis
|
||||
- Spalis
|
||||
- Lakpritis
|
||||
- Gruodis
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Pirmadienis
|
||||
- Antradienis
|
||||
- Trečiadienis
|
||||
- Ketvirtadienis
|
||||
- Penktadienis
|
||||
- Šeštadienis
|
||||
- Sekmadienis
|
||||
@@ -1,45 +1,51 @@
|
||||
---
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'personen'
|
||||
'man': 'mensen'
|
||||
'child': 'kinderen'
|
||||
'sex': 'geslacht'
|
||||
'move': 'verplaatsen'
|
||||
person: personen
|
||||
man: mensen
|
||||
child: kinderen
|
||||
sex: geslacht
|
||||
move: verplaatsen
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: geen datum opgegeven
|
||||
BAD_DATE: Datumformaat onjuist
|
||||
AGO: geleden
|
||||
FROM_NOW: vanaf nu
|
||||
SECOND: seconde
|
||||
MINUTE: minuut
|
||||
HOUR: uur
|
||||
DAY: dag
|
||||
WEEK: week
|
||||
MONTH: maand
|
||||
YEAR: jaar
|
||||
DECADE: decenium
|
||||
SEC: sec
|
||||
MIN: min
|
||||
HR: hr
|
||||
DAY: dag
|
||||
WK: wk
|
||||
MO: ma
|
||||
YR: yr
|
||||
DEC: dec
|
||||
SECOND_PLURAL: seconden
|
||||
MINUTE_PLURAL: minuten
|
||||
HOUR_PLURAL: uren
|
||||
DAY_PLURAL: dagen
|
||||
WEEK_PLURAL: weken
|
||||
MONTH_PLURAL: maanden
|
||||
YEAR_PLURAL: jaren
|
||||
DECADE_PLURAL: decennia
|
||||
SEC_PLURAL: seconden
|
||||
MIN_PLURAL: minuten
|
||||
HR_PLURAL: uren
|
||||
DAY_PLURAL: dagen
|
||||
WK_PLURAL: weken
|
||||
MO_PLURAL: maanden
|
||||
YR_PLURAL: jaren
|
||||
DEC_PLURAL: decs
|
||||
MONTHS_OF_THE_YEAR: ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December']
|
||||
DAYS_OF_THE_WEEK: ['Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag', 'Zondag']
|
||||
NO_DATE_PROVIDED: geen datum opgegeven
|
||||
BAD_DATE: Datumformaat onjuist
|
||||
AGO: geleden
|
||||
FROM_NOW: vanaf nu
|
||||
SECOND: seconde
|
||||
MINUTE: minuut
|
||||
HOUR: uur
|
||||
DAY: dag
|
||||
MONTH: maand
|
||||
YEAR: jaar
|
||||
DECADE: decenium
|
||||
MO: ma
|
||||
SECOND_PLURAL: seconden
|
||||
MINUTE_PLURAL: minuten
|
||||
HOUR_PLURAL: uren
|
||||
DAY_PLURAL: dagen
|
||||
WEEK_PLURAL: weken
|
||||
MONTH_PLURAL: maanden
|
||||
YEAR_PLURAL: jaren
|
||||
DECADE_PLURAL: decennia
|
||||
SEC_PLURAL: seconden
|
||||
MIN_PLURAL: minuten
|
||||
HR_PLURAL: uren
|
||||
WK_PLURAL: weken
|
||||
MO_PLURAL: maanden
|
||||
YR_PLURAL: jaren
|
||||
MONTHS_OF_THE_YEAR:
|
||||
0: Januari
|
||||
1: Februari
|
||||
2: Maart
|
||||
4: Mei
|
||||
5: Juni
|
||||
6: Juli
|
||||
7: Augustus
|
||||
9: Oktober
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Maandag
|
||||
- Dinsdag
|
||||
- Woensdag
|
||||
- Donderdag
|
||||
- Vrijdag
|
||||
- Zaterdag
|
||||
- Zondag
|
||||
|
||||
91
system/languages/no.yaml
Normal file
91
system/languages/no.yaml
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
Tittel: %1$s
|
||||
---
|
||||
|
||||
# Feilmelding: Ugyldig Frontmatter
|
||||
|
||||
Pane: '%2$s'
|
||||
|
||||
**%3$s **
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
INFLECTOR_PLURALS:
|
||||
/(quiz)$/i: '\1zes'
|
||||
/^(ox)$/i: '\1en'
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
- utstyr
|
||||
- informasjon
|
||||
- ris
|
||||
- penger
|
||||
- arter
|
||||
- serier
|
||||
- fisk
|
||||
- sau
|
||||
INFLECTOR_IRREGULAR:
|
||||
person: folk
|
||||
man: menn
|
||||
child: barn
|
||||
sex: kjønn
|
||||
move: trekk
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Ingen dato gitt
|
||||
BAD_DATE: Dårlig dato
|
||||
AGO: siden
|
||||
FROM_NOW: fra nå
|
||||
SECOND: sekund
|
||||
MINUTE: minutt
|
||||
HOUR: time
|
||||
DAY: dag
|
||||
WEEK: uke
|
||||
MONTH: måned
|
||||
YEAR: år
|
||||
DECADE: tiår
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: t
|
||||
WK: uke
|
||||
MO: må
|
||||
YR: år
|
||||
DEC: des
|
||||
SECOND_PLURAL: sekunder
|
||||
MINUTE_PLURAL: minutter
|
||||
HOUR_PLURAL: timer
|
||||
DAY_PLURAL: dager
|
||||
WEEK_PLURAL: uker
|
||||
MONTH_PLURAL: måneder
|
||||
YEAR_PLURAL: år
|
||||
DECADE_PLURAL: tiår
|
||||
SEC_PLURAL: sek
|
||||
MIN_PLURAL: min
|
||||
HR_PLURAL: timer
|
||||
WK_PLURAL: uker
|
||||
YR_PLURAL: år
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Validering mislyktes:</b>'
|
||||
INVALID_INPUT: Ugyldig innhold i
|
||||
MISSING_REQUIRED_FIELD: 'Mangler påkrevd felt:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- januar
|
||||
- februar
|
||||
- mars
|
||||
- april
|
||||
- mai
|
||||
- juni
|
||||
- juli
|
||||
- august
|
||||
- september
|
||||
- oktober
|
||||
- november
|
||||
- desember
|
||||
DAYS_OF_THE_WEEK:
|
||||
- mandag
|
||||
- tirsdag
|
||||
- onsdag
|
||||
- torsdag
|
||||
- fredag
|
||||
- lørdag
|
||||
- søndag
|
||||
@@ -1,2 +1,75 @@
|
||||
MONTHS_OF_THE_YEAR: ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień']
|
||||
DAYS_OF_THE_WEEK: ['Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota', 'Niedziela']
|
||||
---
|
||||
FRONTMATTER_ERROR_PAGE: |
|
||||
---
|
||||
title: %1$s
|
||||
---
|
||||
|
||||
# Error: Nieprawidłowy Frontmatter
|
||||
|
||||
Path: `%2$s`
|
||||
|
||||
**%3$s**
|
||||
|
||||
```
|
||||
%4$s
|
||||
```
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Nie podano daty
|
||||
BAD_DATE: Zła data
|
||||
AGO: temu
|
||||
FROM_NOW: od teraz
|
||||
SECOND: sekunda
|
||||
MINUTE: minuta
|
||||
HOUR: godzina
|
||||
DAY: dzień
|
||||
WEEK: tydzień
|
||||
MONTH: miesiąc
|
||||
YEAR: rok
|
||||
DECADE: dekada
|
||||
SEC: sek
|
||||
MIN: min
|
||||
HR: godz
|
||||
WK: tydź
|
||||
MO: mieś
|
||||
YR: rok
|
||||
DEC: dekada
|
||||
SECOND_PLURAL: sekund
|
||||
MINUTE_PLURAL: minut
|
||||
HOUR_PLURAL: godzin
|
||||
DAY_PLURAL: dni
|
||||
WEEK_PLURAL: tygodnie
|
||||
MONTH_PLURAL: miesięcy
|
||||
YEAR_PLURAL: lat
|
||||
DECADE_PLURAL: dekad
|
||||
SEC_PLURAL: sekund
|
||||
MIN_PLURAL: minut
|
||||
HR_PLURAL: godz
|
||||
WK_PLURAL: tyg
|
||||
MO_PLURAL: mieś
|
||||
YR_PLURAL: lat
|
||||
DEC_PLURAL: dekad
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Weryfikacja nie powiodła się:</b>'
|
||||
INVALID_INPUT: Nieprawidłowe dane w
|
||||
MISSING_REQUIRED_FIELD: 'Opuszczono wymagane pole:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Styczeń
|
||||
- Luty
|
||||
- Marzec
|
||||
- Kwiecień
|
||||
- Maj
|
||||
- Czerwiec
|
||||
- Lipiec
|
||||
- Sierpień
|
||||
- Wrzesień
|
||||
- Październik
|
||||
- Listopad
|
||||
- Grudzień
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Poniedziałek
|
||||
- Wtorek
|
||||
- Środa
|
||||
- Czwartek
|
||||
- Piątek
|
||||
- Sobota
|
||||
- Niedziela
|
||||
|
||||
@@ -1,2 +1,56 @@
|
||||
MONTHS_OF_THE_YEAR: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro']
|
||||
DAYS_OF_THE_WEEK: ['Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado', 'Domingo']
|
||||
---
|
||||
INFLECTOR_UNCOUNTABLE:
|
||||
1: informação
|
||||
2: arroz
|
||||
3: dinheiro
|
||||
INFLECTOR_IRREGULAR:
|
||||
man: homens
|
||||
sex: sexos
|
||||
NICETIME:
|
||||
SECOND: segundo
|
||||
MINUTE: minuto
|
||||
HOUR: hora
|
||||
DAY: dia
|
||||
WEEK: semana
|
||||
MONTH: mês
|
||||
YEAR: ano
|
||||
DECADE: década
|
||||
SEC: seg
|
||||
MIN: mín
|
||||
MO: mês
|
||||
YR: ano
|
||||
SECOND_PLURAL: segundos
|
||||
MINUTE_PLURAL: minutos
|
||||
HOUR_PLURAL: horas
|
||||
DAY_PLURAL: dias
|
||||
WEEK_PLURAL: semanas
|
||||
MONTH_PLURAL: meses
|
||||
YEAR_PLURAL: anos
|
||||
DECADE_PLURAL: décadas
|
||||
SEC_PLURAL: seg
|
||||
MIN_PLURAL: mins
|
||||
HR_PLURAL: hrs
|
||||
YR_PLURAL: anos
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Validação falhada: </b>'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Janeiro
|
||||
- Fevereiro
|
||||
- Março
|
||||
- Abril
|
||||
- Maio
|
||||
- Junho
|
||||
- Julho
|
||||
- Agosto
|
||||
- Setembro
|
||||
- Outubro
|
||||
- Novembro
|
||||
- Dezembro
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Segunda
|
||||
- Terça
|
||||
- Quarta
|
||||
- Quinta
|
||||
- Sexta
|
||||
- Sábado
|
||||
- Domingo
|
||||
|
||||
@@ -1,2 +1,21 @@
|
||||
MONTHS_OF_THE_YEAR: ['Ianuarie', 'Februarie', 'Martie', 'Aprilue', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie']
|
||||
DAYS_OF_THE_WEEK: ['Luni', 'Marti', 'Miercuri', 'Joi', 'Vineri', 'Sâmbătă', 'Duminică']
|
||||
---
|
||||
MONTHS_OF_THE_YEAR:
|
||||
0: Ianuarie
|
||||
1: Februarie
|
||||
2: Martie
|
||||
3: Aprilue
|
||||
4: Mai
|
||||
5: Iunie
|
||||
6: Iulie
|
||||
8: Septembrie
|
||||
9: Octombrie
|
||||
10: Noiembrie
|
||||
11: Decembrie
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Luni
|
||||
- Marti
|
||||
- Miercuri
|
||||
- Joi
|
||||
- Vineri
|
||||
- Sâmbătă
|
||||
- Duminică
|
||||
|
||||
@@ -1,45 +1,67 @@
|
||||
---
|
||||
INFLECTOR_IRREGULAR:
|
||||
'person': 'люди'
|
||||
'man': 'человек'
|
||||
'child': 'ребенок'
|
||||
'sex': 'пол'
|
||||
'move': 'движется'
|
||||
person: люди
|
||||
man: человек
|
||||
child: ребенок
|
||||
sex: пол
|
||||
move: движется
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Дата не указана
|
||||
BAD_DATE: Неверная дата
|
||||
AGO: назад
|
||||
FROM_NOW: теперь
|
||||
SECOND: секунда
|
||||
MINUTE: минута
|
||||
HOUR: час
|
||||
DAY: день
|
||||
WEEK: неделя
|
||||
MONTH: месяц
|
||||
YEAR: год
|
||||
DECADE: десятилетие
|
||||
SEC: с
|
||||
MIN: мин
|
||||
HR: ч
|
||||
DAY: д
|
||||
WK: нед
|
||||
MO: мес
|
||||
YR: г.
|
||||
DEC: гг.
|
||||
SECOND_PLURAL: секунды
|
||||
MINUTE_PLURAL: минуты
|
||||
HOUR_PLURAL: часы
|
||||
DAY_PLURAL: дни
|
||||
WEEK_PLURAL: недели
|
||||
MONTH_PLURAL: месяцы
|
||||
YEAR_PLURAL: годы
|
||||
DECADE_PLURAL: десятилетия
|
||||
SEC_PLURAL: с
|
||||
MIN_PLURAL: мин
|
||||
HR_PLURAL: ч
|
||||
DAY_PLURAL: д
|
||||
WK_PLURAL: нед
|
||||
MO_PLURAL: мес
|
||||
YR_PLURAL: г.
|
||||
DEC_PLURAL: гг.
|
||||
MONTHS_OF_THE_YEAR: ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь']
|
||||
DAYS_OF_THE_WEEK: ['Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье']
|
||||
NO_DATE_PROVIDED: Дата не указана
|
||||
BAD_DATE: Неверная дата
|
||||
AGO: назад
|
||||
FROM_NOW: теперь
|
||||
SECOND: секунда
|
||||
MINUTE: минута
|
||||
HOUR: час
|
||||
DAY: д
|
||||
WEEK: неделя
|
||||
MONTH: месяц
|
||||
YEAR: год
|
||||
DECADE: десятилетие
|
||||
SEC: с
|
||||
MIN: мин
|
||||
HR: ч
|
||||
WK: нед
|
||||
MO: мес
|
||||
YR: г.
|
||||
DEC: гг.
|
||||
SECOND_PLURAL: секунды
|
||||
MINUTE_PLURAL: минуты
|
||||
HOUR_PLURAL: часы
|
||||
DAY_PLURAL: д
|
||||
WEEK_PLURAL: недели
|
||||
MONTH_PLURAL: месяцы
|
||||
YEAR_PLURAL: годы
|
||||
DECADE_PLURAL: десятилетия
|
||||
SEC_PLURAL: с
|
||||
MIN_PLURAL: мин
|
||||
HR_PLURAL: ч
|
||||
WK_PLURAL: нед
|
||||
MO_PLURAL: мес
|
||||
YR_PLURAL: г.
|
||||
DEC_PLURAL: гг.
|
||||
FORM:
|
||||
VALIDATION_FAIL: '<b>Проверка не удалась:</b>'
|
||||
INVALID_INPUT: Неверный ввод в
|
||||
MISSING_REQUIRED_FIELD: 'Отсутствует необходимое поле:'
|
||||
MONTHS_OF_THE_YEAR:
|
||||
- Январь
|
||||
- Февраль
|
||||
- Март
|
||||
- Апрель
|
||||
- Май
|
||||
- Июнь
|
||||
- Июль
|
||||
- Август
|
||||
- Сентябрь
|
||||
- Октябрь
|
||||
- Ноябрь
|
||||
- Декабрь
|
||||
DAYS_OF_THE_WEEK:
|
||||
- Понедельник
|
||||
- Вторник
|
||||
- Среда
|
||||
- Четверг
|
||||
- Пятница
|
||||
- Суббота
|
||||
- Воскресенье
|
||||
|
||||
1
system/languages/sk.yaml
Normal file
1
system/languages/sk.yaml
Normal file
@@ -0,0 +1 @@
|
||||
---
|
||||
3
system/languages/sv.yaml
Normal file
3
system/languages/sv.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
NICETIME:
|
||||
DAY: dag
|
||||
@@ -1,37 +1,36 @@
|
||||
---
|
||||
NICETIME:
|
||||
NO_DATE_PROVIDED: Tarih yok
|
||||
BAD_DATE: Yanlış tarih
|
||||
AGO: önce
|
||||
FROM_NOW: (şimdiden)
|
||||
SECOND: saniye
|
||||
MINUTE: dakika
|
||||
HOUR: saat
|
||||
DAY: gün
|
||||
WEEK: hafta
|
||||
MONTH: ay
|
||||
YEAR: yıl
|
||||
DECADE: onyıl
|
||||
SEC: sn
|
||||
MIN: dk
|
||||
HR: sa
|
||||
DAY: gün
|
||||
WK: hft
|
||||
MO: ay
|
||||
YR: yl
|
||||
DEC: onyl
|
||||
SECOND_PLURAL: saniye
|
||||
MINUTE_PLURAL: dakika
|
||||
HOUR_PLURAL: saat
|
||||
DAY_PLURAL: gün
|
||||
WEEK_PLURAL: hafta
|
||||
MONTH_PLURAL: ay
|
||||
YEAR_PLURAL: yıl
|
||||
DECADE_PLURAL: onyıl
|
||||
SEC_PLURAL: sn
|
||||
MIN_PLURAL: dk
|
||||
HR_PLURAL: sa
|
||||
DAY_PLURAL: gün
|
||||
WK_PLURAL: hft
|
||||
MO_PLURAL: ay
|
||||
YR_PLURAL: yl
|
||||
DEC_PLURAL: onyl
|
||||
NO_DATE_PROVIDED: Tarih yok
|
||||
BAD_DATE: Yanlış tarih
|
||||
AGO: önce
|
||||
FROM_NOW: (şimdiden)
|
||||
SECOND: saniye
|
||||
MINUTE: dakika
|
||||
HOUR: saat
|
||||
DAY: gün
|
||||
WEEK: hafta
|
||||
MONTH: ay
|
||||
YEAR: yıl
|
||||
DECADE: onyıl
|
||||
SEC: sn
|
||||
MIN: dk
|
||||
HR: sa
|
||||
WK: hft
|
||||
MO: ay
|
||||
YR: yl
|
||||
DEC: onyl
|
||||
SECOND_PLURAL: saniye
|
||||
MINUTE_PLURAL: dakika
|
||||
HOUR_PLURAL: saat
|
||||
DAY_PLURAL: gün
|
||||
WEEK_PLURAL: hafta
|
||||
MONTH_PLURAL: ay
|
||||
YEAR_PLURAL: yıl
|
||||
DECADE_PLURAL: onyıl
|
||||
SEC_PLURAL: sn
|
||||
MIN_PLURAL: dk
|
||||
HR_PLURAL: sa
|
||||
WK_PLURAL: hft
|
||||
MO_PLURAL: ay
|
||||
YR_PLURAL: yl
|
||||
DEC_PLURAL: onyl
|
||||
|
||||
@@ -8,6 +8,7 @@ use Grav\Common\Config\Config;
|
||||
use RecursiveDirectoryIterator;
|
||||
use RecursiveIteratorIterator;
|
||||
use RegexIterator;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
define('CSS_ASSET', true);
|
||||
define('JS_ASSET', false);
|
||||
@@ -64,11 +65,12 @@ class Assets
|
||||
protected $js_pipeline = false;
|
||||
|
||||
// The asset holding arrays
|
||||
protected $collections = array();
|
||||
protected $css = array();
|
||||
protected $js = array();
|
||||
protected $inline_css = array();
|
||||
protected $inline_js = array();
|
||||
protected $collections = [];
|
||||
protected $css = [];
|
||||
protected $js = [];
|
||||
protected $inline_css = [];
|
||||
protected $inline_js = [];
|
||||
protected $imports = [];
|
||||
|
||||
// Some configuration variables
|
||||
protected $config;
|
||||
@@ -84,10 +86,15 @@ class Assets
|
||||
protected $js_minify = true;
|
||||
|
||||
// Arrays to hold assets that should NOT be pipelined
|
||||
protected $css_no_pipeline = array();
|
||||
protected $js_no_pipeline = array();
|
||||
protected $css_no_pipeline = [];
|
||||
protected $js_no_pipeline = [];
|
||||
|
||||
public function __construct(array $options = array())
|
||||
/**
|
||||
* Assets constructor.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = [])
|
||||
{
|
||||
// Forward config options
|
||||
if ($options) {
|
||||
@@ -163,7 +170,6 @@ class Assets
|
||||
$this->timestamp = '?' . self::getGrav()['cache']->getKey();
|
||||
}
|
||||
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -177,10 +183,10 @@ class Assets
|
||||
$base_url = self::getGrav()['base_url'];
|
||||
$asset_config = (array)$config->get('system.assets');
|
||||
|
||||
/** @var Locator $locator */
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = self::$grav['locator'];
|
||||
$this->assets_dir = self::getGrav()['locator']->findResource('asset://') . DS;
|
||||
$this->assets_url = self::getGrav()['locator']->findResource('asset://', false);
|
||||
$this->assets_dir = $locator->findResource('asset://') . DS;
|
||||
$this->assets_url = $locator->findResource('asset://', false);
|
||||
|
||||
$this->config($asset_config);
|
||||
$this->base_url = $base_url . '/';
|
||||
@@ -237,9 +243,9 @@ class Assets
|
||||
* You may add more than one asset passing an array as argument.
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param null $group
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param null $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -249,9 +255,11 @@ class Assets
|
||||
foreach ($asset as $a) {
|
||||
$this->addCss($a, $priority, $pipeline, $group);
|
||||
}
|
||||
|
||||
return $this;
|
||||
} elseif (isset($this->collections[$asset])) {
|
||||
$this->add($this->collections[$asset], $priority, $pipeline, $group);
|
||||
$this->addCss($this->collections[$asset], $priority, $pipeline, $group);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -268,12 +276,12 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->css),
|
||||
'pipeline' => (bool) $pipeline,
|
||||
'group' => $group ?: 'head'
|
||||
'pipeline' => (bool)$pipeline,
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
if (func_num_args() == 2) {
|
||||
if (func_num_args() > 1) {
|
||||
$dynamic_arg = func_get_arg(1);
|
||||
if (is_array($dynamic_arg)) {
|
||||
$data = array_merge($data, $dynamic_arg);
|
||||
@@ -294,11 +302,12 @@ class Assets
|
||||
* It checks for duplicates.
|
||||
* You may add more than one asset passing an array as argument.
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param string $loading how the asset is loaded (async/defer)
|
||||
* @param string $group name of the group
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param bool $pipeline false if this should not be pipelined
|
||||
* @param string $loading how the asset is loaded (async/defer)
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addJs($asset, $priority = null, $pipeline = true, $loading = null, $group = null)
|
||||
@@ -307,9 +316,11 @@ class Assets
|
||||
foreach ($asset as $a) {
|
||||
$this->addJs($a, $priority, $pipeline, $loading, $group);
|
||||
}
|
||||
|
||||
return $this;
|
||||
} elseif (isset($this->collections[$asset])) {
|
||||
$this->add($this->collections[$asset], $priority, $pipeline, $loading, $group);
|
||||
$this->addJs($this->collections[$asset], $priority, $pipeline, $loading, $group);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -326,16 +337,16 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->js),
|
||||
'pipeline' => (bool) $pipeline,
|
||||
'pipeline' => (bool)$pipeline,
|
||||
'loading' => $loading ?: '',
|
||||
'group' => $group ?: 'head'
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
if (func_num_args() == 2) {
|
||||
if (func_num_args() > 1) {
|
||||
$dynamic_arg = func_get_arg(1);
|
||||
if (is_array($dynamic_arg)) {
|
||||
$data = array_merge($data, $dynamic_arg);
|
||||
$data = array_merge($data, $dynamic_arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,9 +361,9 @@ class Assets
|
||||
/**
|
||||
* Convenience wrapper for async loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'async']
|
||||
@@ -367,9 +378,9 @@ class Assets
|
||||
/**
|
||||
* Convenience wrapper for deferred loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'defer']
|
||||
@@ -388,8 +399,8 @@ class Assets
|
||||
* For adding chunks of string-based inline CSS
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param null $group
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param null $group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -398,21 +409,20 @@ class Assets
|
||||
$asset = trim($asset);
|
||||
|
||||
if (is_a($asset, 'Twig_Markup')) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
|
||||
if (isset($matches[3])) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches);
|
||||
if (isset($matches[3])) {
|
||||
$asset = $matches[3];
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->inline_css),
|
||||
'asset' => $asset,
|
||||
'group' => $group ?: 'head'
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->inline_css),
|
||||
'asset' => $asset,
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
$count_args = func_num_args();
|
||||
if (func_num_args() == 2) {
|
||||
$dynamic_arg = func_get_arg(1);
|
||||
if (is_array($dynamic_arg)) {
|
||||
@@ -436,7 +446,7 @@ class Assets
|
||||
*
|
||||
* @param mixed $asset
|
||||
* @param int $priority the priority, bigger comes first
|
||||
* @param string $group name of the group
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -445,8 +455,8 @@ class Assets
|
||||
$asset = trim($asset);
|
||||
|
||||
if (is_a($asset, 'Twig_Markup')) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches );
|
||||
if (isset($matches[3])) {
|
||||
preg_match(self::HTML_TAG_REGEX, $asset, $matches);
|
||||
if (isset($matches[3])) {
|
||||
$asset = $matches[3];
|
||||
}
|
||||
}
|
||||
@@ -455,11 +465,10 @@ class Assets
|
||||
'asset' => $asset,
|
||||
'priority' => intval($priority ?: 10),
|
||||
'order' => count($this->js),
|
||||
'group' => $group ?: 'head'
|
||||
'group' => $group ?: 'head'
|
||||
];
|
||||
|
||||
// check for dynamic array and merge with defaults
|
||||
$count_args = func_num_args();
|
||||
if (func_num_args() == 2) {
|
||||
$dynamic_arg = func_get_arg(1);
|
||||
if (is_array($dynamic_arg)) {
|
||||
@@ -479,7 +488,7 @@ class Assets
|
||||
* Build the CSS link tags.
|
||||
*
|
||||
* @param string $group name of the group
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -495,6 +504,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
|
||||
@@ -502,6 +512,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
}
|
||||
@@ -552,7 +563,7 @@ class Assets
|
||||
* Build the JavaScript script tags.
|
||||
*
|
||||
* @param string $group name of the group
|
||||
* @param array $attributes
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -567,6 +578,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
|
||||
@@ -574,6 +586,7 @@ class Assets
|
||||
if ($a['priority'] == $b['priority']) {
|
||||
return $b['order'] - $a['order'];
|
||||
}
|
||||
|
||||
return $a['priority'] - $b['priority'];
|
||||
});
|
||||
|
||||
@@ -592,7 +605,7 @@ class Assets
|
||||
}
|
||||
foreach ($this->js_no_pipeline as $file) {
|
||||
if ($group && $file['group'] == $group) {
|
||||
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading']. '></script>' . "\n";
|
||||
$output .= '<script src="' . $file['asset'] . $this->timestamp . '"' . $attributes . ' ' . $file['loading'] . '></script>' . "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -618,9 +631,11 @@ class Assets
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify and concatenate CSS.
|
||||
* Minify and concatenate CSS
|
||||
*
|
||||
* @return string
|
||||
* @param string $group
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function pipelineCss($group = 'head')
|
||||
{
|
||||
@@ -679,6 +694,7 @@ class Assets
|
||||
// Write file
|
||||
if (strlen(trim($buffer)) > 0) {
|
||||
file_put_contents($absolute_path, $buffer);
|
||||
|
||||
return $relative_path . $key;
|
||||
} else {
|
||||
return false;
|
||||
@@ -688,6 +704,8 @@ class Assets
|
||||
/**
|
||||
* Minify and concatenate JS files.
|
||||
*
|
||||
* @param string $group
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function pipelineJs($group = 'head')
|
||||
@@ -737,6 +755,7 @@ class Assets
|
||||
// Write file
|
||||
if (strlen(trim($buffer)) > 0) {
|
||||
file_put_contents($absolute_path, $buffer);
|
||||
|
||||
return $relative_path . $key;
|
||||
} else {
|
||||
return false;
|
||||
@@ -782,9 +801,7 @@ class Assets
|
||||
*/
|
||||
public function exists($asset)
|
||||
{
|
||||
if (isset($this->collections[$asset]) ||
|
||||
isset($this->css[$asset]) ||
|
||||
isset($this->js[$asset])) {
|
||||
if (isset($this->collections[$asset]) || isset($this->css[$asset]) || isset($this->js[$asset])) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -826,7 +843,8 @@ class Assets
|
||||
*/
|
||||
public function resetJs()
|
||||
{
|
||||
$this->js = array();
|
||||
$this->js = [];
|
||||
$this->inline_js = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -838,15 +856,28 @@ class Assets
|
||||
*/
|
||||
public function resetCss()
|
||||
{
|
||||
$this->css = array();
|
||||
$this->css = [];
|
||||
$this->inline_css = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all CSS assets within $directory (relative to public dir).
|
||||
* Add all JavaScript assets within $directory
|
||||
*
|
||||
* @param string $directory Relative to $this->public_dir
|
||||
* @param string $directory Relative to the Grav root path, or a stream identifier
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDirJs($directory)
|
||||
{
|
||||
return $this->addDir($directory, self::JS_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all CSS assets within $directory
|
||||
*
|
||||
* @param string $directory Relative to the Grav root path, or a stream identifier
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -858,7 +889,7 @@ class Assets
|
||||
/**
|
||||
* Add all assets matching $pattern within $directory.
|
||||
*
|
||||
* @param string $directory Relative to $this->public_dir
|
||||
* @param string $directory Relative to the Grav root path, or a stream identifier
|
||||
* @param string $pattern (regex)
|
||||
*
|
||||
* @return $this
|
||||
@@ -866,13 +897,15 @@ class Assets
|
||||
*/
|
||||
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
|
||||
{
|
||||
// Check if public_dir exists
|
||||
if (!is_dir($this->assets_dir)) {
|
||||
throw new Exception('Assets: Public dir not found');
|
||||
$root_dir = rtrim(ROOT_DIR, '/');
|
||||
|
||||
// Check if $directory is a stream.
|
||||
if (strpos($directory, '://')) {
|
||||
$directory = self::$grav['locator']->findResource($directory, null);
|
||||
}
|
||||
|
||||
// Get files
|
||||
$files = $this->rglob($this->assets_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $this->assets_dir);
|
||||
$files = $this->rglob($root_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $root_dir . '/');
|
||||
|
||||
// No luck? Nothing to do
|
||||
if (!$files) {
|
||||
@@ -881,27 +914,25 @@ class Assets
|
||||
|
||||
// Add CSS files
|
||||
if ($pattern === self::CSS_REGEX) {
|
||||
$this->css = array_unique(array_merge($this->css, $files));
|
||||
foreach ($files as $file) {
|
||||
$this->addCss($file);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Add JavaScript files
|
||||
if ($pattern === self::JS_REGEX) {
|
||||
$this->js = array_unique(array_merge($this->js, $files));
|
||||
foreach ($files as $file) {
|
||||
$this->addJs($file);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// Unknown pattern. We must poll to know the extension :(
|
||||
// Unknown pattern.
|
||||
foreach ($files as $asset) {
|
||||
$info = pathinfo($asset);
|
||||
if (isset($info['extension'])) {
|
||||
$ext = strtolower($info['extension']);
|
||||
if ($ext === 'css' && !in_array($asset, $this->css)) {
|
||||
$this->css[] = $asset;
|
||||
} elseif ($ext === 'js' && !in_array($asset, $this->js)) {
|
||||
$this->js[] = $asset;
|
||||
}
|
||||
}
|
||||
$this->add($asset);
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -918,8 +949,8 @@ class Assets
|
||||
*/
|
||||
protected function isRemoteLink($link)
|
||||
{
|
||||
return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8)
|
||||
|| '//' === substr($link, 0, 2));
|
||||
return ('http://' === substr($link, 0, 7) || 'https://' === substr($link, 0, 8) || '//' === substr($link, 0,
|
||||
2));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -972,18 +1003,18 @@ class Assets
|
||||
* Download and concatenate the content of several links.
|
||||
*
|
||||
* @param array $links
|
||||
* @param bool $css
|
||||
* @param bool $css
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function gatherLinks(array $links, $css = true)
|
||||
{
|
||||
|
||||
|
||||
$buffer = '';
|
||||
$local = true;
|
||||
|
||||
foreach ($links as $asset) {
|
||||
$relative_dir = '';
|
||||
|
||||
$link = $asset['asset'];
|
||||
$relative_path = $link;
|
||||
|
||||
@@ -1034,8 +1065,8 @@ class Assets
|
||||
/**
|
||||
* Finds relative CSS urls() and rewrites the URL with an absolute one
|
||||
*
|
||||
* @param $file the css source file
|
||||
* @param $relative_path relative path to the css file
|
||||
* @param string $file the css source file
|
||||
* @param string $relative_path relative path to the css file
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -1046,23 +1077,19 @@ class Assets
|
||||
|
||||
// Find any css url() elements, grab the URLs and calculate an absolute path
|
||||
// Then replace the old url with the new one
|
||||
$file = preg_replace_callback(
|
||||
self::CSS_URL_REGEX,
|
||||
function ($matches) use ($relative_path) {
|
||||
$file = preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use ($relative_path) {
|
||||
|
||||
$old_url = $matches[1];
|
||||
$old_url = $matches[1];
|
||||
|
||||
// ensure this is not a data url
|
||||
if (strpos($old_url, 'data:') === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
// ensure this is not a data url
|
||||
if (strpos($old_url, 'data:') === 0) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
|
||||
$new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/');
|
||||
|
||||
return str_replace($old_url, $new_url, $matches[0]);
|
||||
},
|
||||
$file
|
||||
);
|
||||
return str_replace($old_url, $new_url, $matches[0]);
|
||||
}, $file);
|
||||
|
||||
return $file;
|
||||
}
|
||||
@@ -1076,16 +1103,13 @@ class Assets
|
||||
*/
|
||||
protected function moveImports($file)
|
||||
{
|
||||
$this->imports = array();
|
||||
$this->imports = [];
|
||||
|
||||
$file = preg_replace_callback(
|
||||
self::CSS_IMPORT_REGEX,
|
||||
function ($matches) {
|
||||
$this->imports[] = $matches[0];
|
||||
return '';
|
||||
},
|
||||
$file
|
||||
);
|
||||
$file = preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) {
|
||||
$this->imports[] = $matches[0];
|
||||
|
||||
return '';
|
||||
}, $file);
|
||||
|
||||
return implode("\n", $this->imports) . "\n\n" . $file;
|
||||
}
|
||||
@@ -1101,17 +1125,10 @@ class Assets
|
||||
*/
|
||||
protected function rglob($directory, $pattern, $ltrim = null)
|
||||
{
|
||||
$iterator = new RegexIterator(
|
||||
new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator(
|
||||
$directory,
|
||||
FilesystemIterator::SKIP_DOTS
|
||||
)
|
||||
),
|
||||
$pattern
|
||||
);
|
||||
$iterator = new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory,
|
||||
FilesystemIterator::SKIP_DOTS)), $pattern);
|
||||
$offset = strlen($ltrim);
|
||||
$files = array();
|
||||
$files = [];
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = substr($file->getPathname(), $offset);
|
||||
@@ -1120,18 +1137,6 @@ class Assets
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all JavaScript assets within $directory.
|
||||
*
|
||||
* @param string $directory Relative to $this->public_dir
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addDirJs($directory)
|
||||
{
|
||||
return $this->addDir($directory, self::JS_REGEX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the state of CSS Pipeline
|
||||
*
|
||||
@@ -1139,7 +1144,7 @@ class Assets
|
||||
*/
|
||||
public function setCssPipeline($value)
|
||||
{
|
||||
$this->css_pipeline = (bool) $value;
|
||||
$this->css_pipeline = (bool)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1149,7 +1154,7 @@ class Assets
|
||||
*/
|
||||
public function setJsPipeline($value)
|
||||
{
|
||||
$this->js_pipeline = (bool) $value;
|
||||
$this->js_pipeline = (bool)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1159,9 +1164,12 @@ class Assets
|
||||
*/
|
||||
public function setTimestamp($value)
|
||||
{
|
||||
$this->timestamp = '?'.$value;
|
||||
$this->timestamp = '?' . $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return '';
|
||||
|
||||
@@ -29,6 +29,14 @@ class ZipBackup
|
||||
'.idea'
|
||||
];
|
||||
|
||||
/**
|
||||
* Backup
|
||||
*
|
||||
* @param null $destination
|
||||
* @param callable|null $messager
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public static function backup($destination = null, callable $messager = null)
|
||||
{
|
||||
if (!$destination) {
|
||||
|
||||
@@ -2,13 +2,20 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
/**
|
||||
* Simple wrapper for the very simple parse_user_agent() function
|
||||
* Handles browser and platform versions
|
||||
*
|
||||
* Internally uses the PhpUserAgent package https://github.com/donatj/PhpUserAgent
|
||||
*
|
||||
* @author RocketTHeme
|
||||
* @licence MIT
|
||||
*/
|
||||
class Browser
|
||||
{
|
||||
|
||||
protected $useragent = [];
|
||||
|
||||
/**
|
||||
* Browser constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
@@ -18,29 +25,99 @@ class Browser
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current browser identifier
|
||||
*
|
||||
* Currently detected browsers:
|
||||
*
|
||||
* Android Browser
|
||||
* BlackBerry Browser
|
||||
* Camino
|
||||
* Kindle / Silk
|
||||
* Firefox / Iceweasel
|
||||
* Safari
|
||||
* Internet Explorer
|
||||
* IEMobile
|
||||
* Chrome
|
||||
* Opera
|
||||
* Midori
|
||||
* Vivaldi
|
||||
* TizenBrowser
|
||||
* Lynx
|
||||
* Wget
|
||||
* Curl
|
||||
*
|
||||
* @return string the lowercase browser name
|
||||
*/
|
||||
public function getBrowser()
|
||||
{
|
||||
return strtolower($this->useragent['browser']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current platform identifier
|
||||
*
|
||||
* Currently detected platforms:
|
||||
*
|
||||
* Desktop
|
||||
* -> Windows
|
||||
* -> Linux
|
||||
* -> Macintosh
|
||||
* -> Chrome OS
|
||||
* Mobile
|
||||
* -> Android
|
||||
* -> iPhone
|
||||
* -> iPad / iPod Touch
|
||||
* -> Windows Phone OS
|
||||
* -> Kindle
|
||||
* -> Kindle Fire
|
||||
* -> BlackBerry
|
||||
* -> Playbook
|
||||
* -> Tizen
|
||||
* Console
|
||||
* -> Nintendo 3DS
|
||||
* -> New Nintendo 3DS
|
||||
* -> Nintendo Wii
|
||||
* -> Nintendo WiiU
|
||||
* -> PlayStation 3
|
||||
* -> PlayStation 4
|
||||
* -> PlayStation Vita
|
||||
* -> Xbox 360
|
||||
* -> Xbox One
|
||||
*
|
||||
* @return string the lowercase platform name
|
||||
*/
|
||||
public function getPlatform()
|
||||
{
|
||||
return strtolower($this->useragent['platform']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current full version identifier
|
||||
*
|
||||
* @return string the browser full version identifier
|
||||
*/
|
||||
public function getLongVersion()
|
||||
{
|
||||
return $this->useragent['version'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current major version identifier
|
||||
*
|
||||
* @return string the browser major version identifier
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
$version = explode('.', $this->getLongVersion());
|
||||
|
||||
return intval($version[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the request comes from a human, or from a bot/crawler
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isHuman()
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use \Doctrine\Common\Cache\Cache as DoctrineCache;
|
||||
use \Doctrine\Common\Cache as DoctrineCache;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
|
||||
@@ -16,7 +16,7 @@ use Grav\Common\Filesystem\Folder;
|
||||
* MemCacheD
|
||||
* FileSystem
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Cache extends Getters
|
||||
@@ -31,10 +31,11 @@ class Cache extends Getters
|
||||
protected $lifetime;
|
||||
protected $now;
|
||||
|
||||
/** @var Config $config */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var DoctrineCache
|
||||
* @var DoctrineCache\CacheProvider
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
@@ -79,7 +80,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @params Grav $grav
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
@@ -90,6 +91,7 @@ class Cache extends Getters
|
||||
* Initialization that sets a base key and the driver based on configuration settings
|
||||
*
|
||||
* @param Grav $grav
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function init(Grav $grav)
|
||||
@@ -105,10 +107,11 @@ class Cache extends Getters
|
||||
|
||||
$prefix = $this->config->get('system.cache.prefix');
|
||||
|
||||
$this->enabled = (bool) $this->config->get('system.cache.enabled');
|
||||
$this->enabled = (bool)$this->config->get('system.cache.enabled');
|
||||
|
||||
// Cache key allows us to invalidate all cache on configuration changes.
|
||||
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
|
||||
$this->key = ($prefix ? $prefix : 'g') . '-' . substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION),
|
||||
2, 8);
|
||||
|
||||
$this->driver_setting = $this->config->get('system.cache.driver');
|
||||
|
||||
@@ -127,7 +130,7 @@ class Cache extends Getters
|
||||
* If there is no config option for $driver in the config, or it's set to 'auto', it will
|
||||
* pick the best option based on which cache extensions are installed.
|
||||
*
|
||||
* @return DoctrineCacheDriver The cache driver to use
|
||||
* @return DoctrineCache\CacheProvider The cache driver to use
|
||||
*/
|
||||
public function getCacheDriver()
|
||||
{
|
||||
@@ -152,40 +155,40 @@ class Cache extends Getters
|
||||
|
||||
switch ($driver_name) {
|
||||
case 'apc':
|
||||
$driver = new \Doctrine\Common\Cache\ApcCache();
|
||||
$driver = new DoctrineCache\ApcCache();
|
||||
break;
|
||||
|
||||
case 'apcu':
|
||||
$driver = new \Doctrine\Common\Cache\ApcuCache();
|
||||
$driver = new DoctrineCache\ApcuCache();
|
||||
break;
|
||||
|
||||
case 'wincache':
|
||||
$driver = new \Doctrine\Common\Cache\WinCacheCache();
|
||||
$driver = new DoctrineCache\WinCacheCache();
|
||||
break;
|
||||
|
||||
case 'xcache':
|
||||
$driver = new \Doctrine\Common\Cache\XcacheCache();
|
||||
$driver = new DoctrineCache\XcacheCache();
|
||||
break;
|
||||
|
||||
case 'memcache':
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect($this->config->get('system.cache.memcache.server','localhost'),
|
||||
$this->config->get('system.cache.memcache.port', 11211));
|
||||
$driver = new \Doctrine\Common\Cache\MemcacheCache();
|
||||
$memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcache.port', 11211));
|
||||
$driver = new DoctrineCache\MemcacheCache();
|
||||
$driver->setMemcache($memcache);
|
||||
break;
|
||||
|
||||
case 'redis':
|
||||
$redis = new \Redis();
|
||||
$redis->connect($this->config->get('system.cache.redis.server','localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
|
||||
$driver = new \Doctrine\Common\Cache\RedisCache();
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
break;
|
||||
|
||||
default:
|
||||
$driver = new \Doctrine\Common\Cache\FilesystemCache($this->cache_dir);
|
||||
$driver = new DoctrineCache\FilesystemCache($this->cache_dir);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -196,6 +199,7 @@ class Cache extends Getters
|
||||
* Gets a cached entry if it exists based on an id. If it does not exist, it returns false
|
||||
*
|
||||
* @param string $id the id of the cached entry
|
||||
*
|
||||
* @return object returns the cached entry, can be any type, or false if doesn't exist
|
||||
*/
|
||||
public function fetch($id)
|
||||
@@ -210,9 +214,9 @@ class Cache extends Getters
|
||||
/**
|
||||
* Stores a new cached entry.
|
||||
*
|
||||
* @param string $id the id of the cached entry
|
||||
* @param string $id the id of the cached entry
|
||||
* @param array|object $data the data for the cached entry to store
|
||||
* @param int $lifetime the lifetime to store the entry in seconds
|
||||
* @param int $lifetime the lifetime to store the entry in seconds
|
||||
*/
|
||||
public function save($id, $data, $lifetime = null)
|
||||
{
|
||||
@@ -235,7 +239,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* Helper method to clear all Grav caches
|
||||
*
|
||||
* @param string $remove standard|all|assets-only|images-only|cache-only
|
||||
* @param string $remove standard|all|assets-only|images-only|cache-only
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -245,7 +249,7 @@ class Cache extends Getters
|
||||
$output = [];
|
||||
$user_config = USER_DIR . 'config/system.yaml';
|
||||
|
||||
switch($remove) {
|
||||
switch ($remove) {
|
||||
case 'all':
|
||||
$remove_paths = self::$all_remove;
|
||||
break;
|
||||
@@ -268,8 +272,9 @@ class Cache extends Getters
|
||||
// Convert stream to a real path
|
||||
$path = $locator->findResource($stream, true, true);
|
||||
// Make sure path exists before proceeding, otherwise we would wipe ROOT_DIR
|
||||
if (!$path)
|
||||
if (!$path) {
|
||||
throw new \RuntimeException("Stream '{$stream}' not found", 500);
|
||||
}
|
||||
|
||||
$anything = false;
|
||||
$files = glob($path . '/*');
|
||||
|
||||
@@ -35,6 +35,11 @@ class Composer
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the composer executable file path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getComposerExecutor()
|
||||
{
|
||||
$executor = PHP_BINARY . ' ';
|
||||
|
||||
@@ -158,7 +158,7 @@ class Setup extends Data
|
||||
}
|
||||
|
||||
// Update streams.
|
||||
foreach ($files as $path) {
|
||||
foreach (array_reverse($files) as $path) {
|
||||
$file = CompiledYamlFile::instance($path);
|
||||
$content = $file->content();
|
||||
if (!empty($content['schemes'])) {
|
||||
|
||||
@@ -283,7 +283,7 @@ class Validation
|
||||
|
||||
protected static function filterFile($value, array $params, array $field)
|
||||
{
|
||||
if (isset($field['multiple']) && $field['multiple'] == true) {
|
||||
if (isset($field['multiple']) && $field['multiple'] === true) {
|
||||
return (array) $value;
|
||||
}
|
||||
|
||||
@@ -559,6 +559,10 @@ class Validation
|
||||
$options = isset($field['options']) ? array_keys($field['options']) : array();
|
||||
$multi = isset($field['multiple']) ? $field['multiple'] : false;
|
||||
|
||||
if (count($values) == 1 && isset($values[0]) && $values[0] == '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($options) {
|
||||
$useKey = isset($field['use']) && $field['use'] == 'keys';
|
||||
foreach ($values as $key => $value) {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use DebugBar\DataCollector\ConfigCollector;
|
||||
use DebugBar\JavascriptRenderer;
|
||||
use DebugBar\StandardDebugBar;
|
||||
use Grav\Common\Config\Config;
|
||||
|
||||
/**
|
||||
* Class Debugger
|
||||
@@ -10,45 +12,79 @@ use DebugBar\StandardDebugBar;
|
||||
*/
|
||||
class Debugger
|
||||
{
|
||||
/** @var Grav $grav */
|
||||
protected $grav;
|
||||
protected $debugbar;
|
||||
|
||||
/** @var Config $config */
|
||||
protected $config;
|
||||
|
||||
/** @var JavascriptRenderer $renderer */
|
||||
protected $renderer;
|
||||
|
||||
/** @var StandardDebugBar $debugbar */
|
||||
protected $debugbar;
|
||||
|
||||
protected $enabled;
|
||||
|
||||
protected $timers = [];
|
||||
|
||||
/**
|
||||
* Debugger constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->debugbar = new StandardDebugBar();
|
||||
$this->debugbar['time']->addMeasure('Loading', $this->debugbar['time']->getRequestStartTime(), microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the debugger
|
||||
*
|
||||
* @return $this
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->grav = Grav::instance();
|
||||
$this->config = $this->grav['config'];
|
||||
|
||||
if ($this->enabled()) {
|
||||
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('system'), 'Config'));
|
||||
$this->debugbar->addCollector(new \DebugBar\DataCollector\ConfigCollector((array)$this->grav['config']->get('plugins'), 'Plugins'));
|
||||
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('system'), 'Config'));
|
||||
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('plugins'), 'Plugins'));
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set/get the enabled state of the debugger
|
||||
*
|
||||
* @param bool $state If null, the method returns the enabled value. If set, the method sets the enabled state
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function enabled($state = null)
|
||||
{
|
||||
if (isset($state)) {
|
||||
$this->enabled = $state;
|
||||
} else {
|
||||
if (!isset($this->enabled)) {
|
||||
$this->enabled = $this->grav['config']->get('system.debugger.enabled');
|
||||
$this->enabled = $this->config->get('system.debugger.enabled');
|
||||
}
|
||||
}
|
||||
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the debugger assets to the Grav Assets
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addAssets()
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
/** @var Assets $assets */
|
||||
$assets = $this->grav['assets'];
|
||||
|
||||
// Add jquery library
|
||||
@@ -69,58 +105,113 @@ class Debugger
|
||||
$assets->addJs($js);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a data collector
|
||||
*
|
||||
* @param $collector
|
||||
*
|
||||
* @return $this
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function addCollector($collector)
|
||||
{
|
||||
$this->debugbar->addCollector($collector);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data collector
|
||||
*
|
||||
* @param $collector
|
||||
*
|
||||
* @return \DebugBar\DataCollector\DataCollectorInterface
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function getCollector($collector)
|
||||
{
|
||||
return $this->debugbar->getCollector($collector);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the debug bar
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
echo $this->renderer->render();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the data through the HTTP headers
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function sendDataInHeaders()
|
||||
{
|
||||
$this->debugbar->sendDataInHeaders();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start a timer with an associated name and description
|
||||
*
|
||||
* @param $name
|
||||
* @param string|null $description
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function startTimer($name, $description = null)
|
||||
{
|
||||
if ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled')) {
|
||||
if ($name[0] == '_' || $this->config->get('system.debugger.enabled')) {
|
||||
$this->debugbar['time']->startMeasure($name, $description);
|
||||
$this->timers[] = $name;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the named timer
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function stopTimer($name)
|
||||
{
|
||||
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->grav['config']->get('system.debugger.enabled'))) {
|
||||
if (in_array($name, $this->timers) && ($name[0] == '_' || $this->config->get('system.debugger.enabled'))) {
|
||||
$this->debugbar['time']->stopMeasure($name);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dump variables into the Messages tab of the Debug Bar
|
||||
*
|
||||
* @param $message
|
||||
* @param string $label
|
||||
* @param bool $isString
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addMessage($message, $label = 'info', $isString = true)
|
||||
{
|
||||
if ($this->enabled()) {
|
||||
$this->debugbar['messages']->addMessage($message, $label, $isString);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ class Errors
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$config = $grav['config']->get('system.errors');
|
||||
$jsonRequest = $_SERVER && $_SERVER['HTTP_ACCEPT'] && $_SERVER['HTTP_ACCEPT'] == 'application/json';
|
||||
|
||||
// Setup Whoops-based error handler
|
||||
$whoops = new \Whoops\Run;
|
||||
@@ -30,11 +31,15 @@ class Errors
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('Whoops\isAjaxRequest')) { //Whoops 2
|
||||
if (Whoops\isAjaxRequest()) {
|
||||
if (method_exists('Whoops\Util\Misc', 'isAjaxRequest')) { //Whoops 2.0
|
||||
if (Whoops\Util\Misc::isAjaxRequest() || $jsonRequest) {
|
||||
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
|
||||
}
|
||||
} else { //Whoops 1
|
||||
} elseif (function_exists('Whoops\isAjaxRequest')) { //Whoops 2.0.0-alpha
|
||||
if (Whoops\isAjaxRequest() || $jsonRequest) {
|
||||
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
|
||||
}
|
||||
} else { //Whoops 1.x
|
||||
$json_page = new Whoops\Handler\JsonResponseHandler;
|
||||
$json_page->onlyForAjaxRequests(true);
|
||||
}
|
||||
|
||||
@@ -64,8 +64,9 @@ abstract class Folder
|
||||
/**
|
||||
* Get relative path between target and base path. If path isn't relative, return full path.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $base
|
||||
* @param string $path
|
||||
* @param mixed|string $base
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getRelativePath($path, $base = GRAV_ROOT)
|
||||
@@ -141,7 +142,7 @@ abstract class Folder
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public static function all($path, array $params = array())
|
||||
public static function all($path, array $params = [])
|
||||
{
|
||||
if ($path === false) {
|
||||
throw new \RuntimeException("Path to {$path} doesn't exist.");
|
||||
@@ -166,7 +167,7 @@ abstract class Folder
|
||||
$iterator = new \FilesystemIterator($path);
|
||||
}
|
||||
|
||||
$results = array();
|
||||
$results = [];
|
||||
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
|
||||
@@ -3,12 +3,21 @@ namespace Grav\Common\Filesystem;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
|
||||
/**
|
||||
* Class RecursiveFolderFilterIterator
|
||||
* @package Grav\Common\Filesystem
|
||||
*/
|
||||
class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
protected static $folder_ignores;
|
||||
|
||||
/**
|
||||
* Create a RecursiveFilterIterator from a RecursiveIterator
|
||||
*
|
||||
* @param RecursiveIterator $iterator
|
||||
*/
|
||||
public function __construct(\RecursiveIterator $iterator)
|
||||
{
|
||||
parent::__construct($iterator);
|
||||
@@ -17,9 +26,13 @@ class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the current element of the iterator is acceptable
|
||||
*
|
||||
* @return bool true if the current element is acceptable, otherwise false.
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
|
||||
/** @var $current \SplFileInfo */
|
||||
$current = $this->current();
|
||||
|
||||
|
||||
@@ -121,6 +121,10 @@ class Installer
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $state
|
||||
* @param $install_path
|
||||
*/
|
||||
protected static function flightProcessing($state, $install_path)
|
||||
{
|
||||
$blueprints_path = $install_path . DS . 'blueprints.yaml';
|
||||
@@ -140,6 +144,13 @@ class Installer
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ZipArchive $zip
|
||||
* @param $install_path
|
||||
* @param $tmp
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function moveInstall(\ZipArchive $zip, $install_path, $tmp)
|
||||
{
|
||||
$container = $zip->getNameIndex(0);
|
||||
@@ -152,6 +163,13 @@ class Installer
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ZipArchive $zip
|
||||
* @param $install_path
|
||||
* @param $tmp
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function copyInstall(\ZipArchive $zip, $install_path, $tmp)
|
||||
{
|
||||
$firstDir = $zip->getNameIndex(0);
|
||||
@@ -165,6 +183,13 @@ class Installer
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ZipArchive $zip
|
||||
* @param $install_path
|
||||
* @param $tmp
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function sophisticatedInstall(\ZipArchive $zip, $install_path, $tmp)
|
||||
{
|
||||
for ($i = 0, $l = $zip->numFiles; $i < $l; $i++) {
|
||||
@@ -279,8 +304,6 @@ class Installer
|
||||
*/
|
||||
public static function lastErrorMsg()
|
||||
{
|
||||
$msg = 'Unknown Error';
|
||||
|
||||
if (is_string(self::$error)) {
|
||||
return self::$error;
|
||||
}
|
||||
@@ -319,7 +342,7 @@ class Installer
|
||||
break;
|
||||
|
||||
default:
|
||||
return 'Unknown error';
|
||||
$msg = 'Unknown Error';
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,16 @@
|
||||
namespace Grav\Common\GPM;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\GravTrait;
|
||||
|
||||
/**
|
||||
* Class Response
|
||||
* @package Grav\Common\GPM
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/**
|
||||
* The callback for the progress
|
||||
*
|
||||
@@ -122,8 +129,7 @@ class Response
|
||||
|
||||
/**
|
||||
* Progress normalized for cURL and Fopen
|
||||
*
|
||||
* @param args Variable length of arguments passed in by stream method
|
||||
* Accepts a vsariable length of arguments passed in by stream method
|
||||
*
|
||||
* @return array Normalized array with useful data.
|
||||
* Format: ['code' => int|false, 'filesize' => bytes, 'transferred' => bytes, 'percent' => int]
|
||||
@@ -192,6 +198,12 @@ class Response
|
||||
$options = $args[1];
|
||||
$callback = $args[2];
|
||||
|
||||
// if proxy set add that
|
||||
$proxy_url = self::getGrav()['config']->get('system.proxy_url');
|
||||
if ($proxy_url) {
|
||||
$options['fopen']['proxy'] = $proxy_url;
|
||||
}
|
||||
|
||||
if ($callback) {
|
||||
$options['fopen']['notification'] = ['self', 'progress'];
|
||||
}
|
||||
@@ -222,9 +234,10 @@ class Response
|
||||
|
||||
$ch = curl_init($uri);
|
||||
|
||||
$response = static::_curl_exec_follow($ch, $options, $callback);
|
||||
$response = static::curlExecFollow($ch, $options, $callback);
|
||||
$errno = curl_errno($ch);
|
||||
|
||||
if ($errno = curl_errno($ch)) {
|
||||
if ($errno) {
|
||||
$error_message = curl_strerror($errno);
|
||||
throw new \RuntimeException("cURL error ({$errno}):\n {$error_message}");
|
||||
}
|
||||
@@ -234,7 +247,14 @@ class Response
|
||||
return $response;
|
||||
}
|
||||
|
||||
private static function _curl_exec_follow($ch, $options, $callback)
|
||||
/**
|
||||
* @param $ch
|
||||
* @param $options
|
||||
* @param $callback
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
private static function curlExecFollow($ch, $options, $callback)
|
||||
{
|
||||
if ($callback) {
|
||||
curl_setopt_array(
|
||||
@@ -246,6 +266,12 @@ class Response
|
||||
);
|
||||
}
|
||||
|
||||
// if proxy set add that
|
||||
$proxy_url = self::getGrav()['config']->get('system.proxy_url');
|
||||
if ($proxy_url) {
|
||||
$options['curl'][CURLOPT_PROXY] = $proxy_url;
|
||||
}
|
||||
|
||||
// no open_basedir set, we can proceed normally
|
||||
if (!ini_get('open_basedir')) {
|
||||
curl_setopt_array($ch, $options['curl']);
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Grav\Common;
|
||||
* Abstract class to implement magic __get(), __set(), __isset() and __unset().
|
||||
* Also implements ArrayAccess.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
abstract class Getters implements \ArrayAccess, \Countable
|
||||
@@ -32,6 +32,7 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
* Magic getter method
|
||||
*
|
||||
* @param mixed $offset Medium name value
|
||||
*
|
||||
* @return mixed Medium value
|
||||
*/
|
||||
public function __get($offset)
|
||||
@@ -42,7 +43,8 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
/**
|
||||
* Magic method to determine if the attribute is set
|
||||
*
|
||||
* @param mixed $offset Medium name value
|
||||
* @param mixed $offset Medium name value
|
||||
*
|
||||
* @return boolean True if the value is set
|
||||
*/
|
||||
public function __isset($offset)
|
||||
@@ -62,12 +64,14 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
if ($this->gettersVariable) {
|
||||
$var = $this->gettersVariable;
|
||||
|
||||
return isset($this->{$var}[$offset]);
|
||||
} else {
|
||||
return isset($this->{$offset});
|
||||
@@ -76,12 +80,14 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if ($this->gettersVariable) {
|
||||
$var = $this->gettersVariable;
|
||||
|
||||
return isset($this->{$var}[$offset]) ? $this->{$var}[$offset] : null;
|
||||
} else {
|
||||
return isset($this->{$offset}) ? $this->{$offset} : null;
|
||||
@@ -137,13 +143,17 @@ abstract class Getters implements \ArrayAccess, \Countable
|
||||
{
|
||||
if ($this->gettersVariable) {
|
||||
$var = $this->gettersVariable;
|
||||
|
||||
return $this->{$var};
|
||||
} else {
|
||||
$properties = (array) $this;
|
||||
$list = array();
|
||||
$properties = (array)$this;
|
||||
$list = [];
|
||||
foreach ($properties as $property => $value) {
|
||||
if ($property[0] != "\0") $list[$property] = $value;
|
||||
if ($property[0] != "\0") {
|
||||
$list[$property] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Medium\ImageMedium;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Service\ConfigServiceProvider;
|
||||
use Grav\Common\Service\ErrorServiceProvider;
|
||||
@@ -16,8 +19,8 @@ use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
/**
|
||||
* Grav
|
||||
*
|
||||
* @author Andy Miller
|
||||
* @link http://www.rockettheme.com
|
||||
* @author Andy Miller
|
||||
* @link http://www.rockettheme.com
|
||||
* @license http://opensource.org/licenses/MIT
|
||||
*
|
||||
* Influenced by Pico, Stacey, Kirby, PieCrust and other great platforms...
|
||||
@@ -34,7 +37,14 @@ class Grav extends Container
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
public static function instance(array $values = array())
|
||||
/**
|
||||
* Return the Grav instance. Create it if it's not already instanced
|
||||
*
|
||||
* @param array $values
|
||||
*
|
||||
* @return Grav
|
||||
*/
|
||||
public static function instance(array $values = [])
|
||||
{
|
||||
if (!self::$instance) {
|
||||
self::$instance = static::load($values);
|
||||
@@ -51,6 +61,13 @@ class Grav extends Container
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize and return a Grav instance
|
||||
*
|
||||
* @param array $values
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
protected static function load(array $values)
|
||||
{
|
||||
$container = new static($values);
|
||||
@@ -58,52 +75,63 @@ class Grav extends Container
|
||||
$container['grav'] = $container;
|
||||
|
||||
$container['debugger'] = new Debugger();
|
||||
$container['debugger']->startTimer('_init', 'Initialize');
|
||||
$container['debugger']->startTimer('_services', 'Services');
|
||||
|
||||
$container->register(new LoggerServiceProvider);
|
||||
|
||||
$container->register(new ErrorServiceProvider);
|
||||
|
||||
$container['uri'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Uri($c);
|
||||
};
|
||||
|
||||
$container['task'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return !empty($_POST['task']) ? $_POST['task'] : $c['uri']->param('task');
|
||||
};
|
||||
|
||||
$container['events'] = function ($c) {
|
||||
$container['events'] = function () {
|
||||
return new EventDispatcher;
|
||||
};
|
||||
$container['cache'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Cache($c);
|
||||
};
|
||||
$container['session'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Session($c);
|
||||
};
|
||||
$container['plugins'] = function ($c) {
|
||||
$container['plugins'] = function () {
|
||||
return new Plugins();
|
||||
};
|
||||
$container['themes'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Themes($c);
|
||||
};
|
||||
$container['twig'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Twig($c);
|
||||
};
|
||||
$container['taxonomy'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Taxonomy($c);
|
||||
};
|
||||
$container['language'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return new Language($c);
|
||||
};
|
||||
|
||||
$container['pages'] = function ($c) {
|
||||
return new Page\Pages($c);
|
||||
/** @var Grav $c */
|
||||
return new Pages($c);
|
||||
};
|
||||
|
||||
$container['assets'] = new Assets();
|
||||
|
||||
$container['page'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $c['pages'];
|
||||
/** @var Language $language */
|
||||
@@ -138,7 +166,7 @@ class Grav extends Container
|
||||
if (!$page || !$page->routable()) {
|
||||
|
||||
// Try fallback URL stuff...
|
||||
$c->fallbackUrl($page, $path);
|
||||
$c->fallbackUrl($path);
|
||||
|
||||
// If no page found, fire event
|
||||
$event = $c->fireEvent('onPageNotFound');
|
||||
@@ -149,23 +177,17 @@ class Grav extends Container
|
||||
throw new \RuntimeException('Page Not Found', 404);
|
||||
}
|
||||
}
|
||||
|
||||
return $page;
|
||||
};
|
||||
|
||||
$container['output'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
return $c['twig']->processSite($c['uri']->extension());
|
||||
};
|
||||
$container['browser'] = function ($c) {
|
||||
return new Browser();
|
||||
};
|
||||
|
||||
$container['base_url_absolute'] = function ($c) {
|
||||
return $c['config']->get('system.base_url_absolute') ?: $c['uri']->rootUrl(true);
|
||||
};
|
||||
$container['base_url_relative'] = function ($c) {
|
||||
return $c['config']->get('system.base_url_relative') ?: $c['uri']->rootUrl(false);
|
||||
};
|
||||
$container['base_url'] = function ($c) {
|
||||
return $c['config']->get('system.absolute_urls') ? $c['base_url_absolute'] : $c['base_url_relative'];
|
||||
$container['browser'] = function () {
|
||||
return new Browser();
|
||||
};
|
||||
|
||||
$container->register(new StreamsServiceProvider);
|
||||
@@ -173,51 +195,64 @@ class Grav extends Container
|
||||
|
||||
$container['inflector'] = new Inflector();
|
||||
|
||||
$container['debugger']->stopTimer('_init');
|
||||
$container['debugger']->stopTimer('_services');
|
||||
|
||||
return $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a request
|
||||
*/
|
||||
public function process()
|
||||
{
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $this['debugger'];
|
||||
|
||||
// Load site setup and initializing streams.
|
||||
$debugger->startTimer('_setup', 'Site Setup');
|
||||
$this['setup']->init();
|
||||
$this['streams'];
|
||||
$debugger->stopTimer('_setup');
|
||||
|
||||
// Initialize configuration.
|
||||
$debugger->startTimer('_config', 'Configuration');
|
||||
$this['config']->init();
|
||||
$this['errors']->resetHandlers();
|
||||
$this['uri']->init();
|
||||
$this['session']->init();
|
||||
|
||||
$debugger->init();
|
||||
$this['config']->debug();
|
||||
$debugger->stopTimer('_config');
|
||||
|
||||
// Initialize error handlers.
|
||||
$this['errors']->resetHandlers();
|
||||
|
||||
// Initialize debugger.
|
||||
$debugger->init();
|
||||
$debugger->startTimer('init', 'Initialize');
|
||||
$this['config']->debug();
|
||||
|
||||
// Use output buffering to prevent headers from being sent too early.
|
||||
ob_start();
|
||||
if ($this['config']->get('system.cache.gzip')) {
|
||||
// Enable zip/deflate with a fallback in case of if browser does not support compressing.
|
||||
if(!ob_start("ob_gzhandler")) {
|
||||
if (!ob_start("ob_gzhandler")) {
|
||||
ob_start();
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the timezone
|
||||
// Initialize the timezone.
|
||||
if ($this['config']->get('system.timezone')) {
|
||||
date_default_timezone_set($this['config']->get('system.timezone'));
|
||||
}
|
||||
|
||||
// Initialize Locale if set and configured
|
||||
// Initialize uri, session.
|
||||
$this['uri']->init();
|
||||
$this['session']->init();
|
||||
|
||||
// Initialize Locale if set and configured.
|
||||
if ($this['language']->enabled() && $this['config']->get('system.languages.override_locale')) {
|
||||
setlocale(LC_ALL, $this['language']->getLanguage());
|
||||
} elseif ($this['config']->get('system.default_locale')) {
|
||||
setlocale(LC_ALL, $this['config']->get('system.default_locale'));
|
||||
}
|
||||
|
||||
$debugger->startTimer('streams', 'Streams');
|
||||
$this['streams'];
|
||||
$debugger->stopTimer('streams');
|
||||
$debugger->stopTimer('init');
|
||||
|
||||
$debugger->startTimer('plugins', 'Plugins');
|
||||
$this['plugins']->init();
|
||||
@@ -268,7 +303,7 @@ class Grav extends Container
|
||||
* Redirect browser to another location.
|
||||
*
|
||||
* @param string $route Internal route.
|
||||
* @param int $code Redirection code (30x)
|
||||
* @param int $code Redirection code (30x)
|
||||
*/
|
||||
public function redirect($route, $code = null)
|
||||
{
|
||||
@@ -283,7 +318,7 @@ class Grav extends Container
|
||||
$code = $matches[2];
|
||||
}
|
||||
|
||||
if ($code == null) {
|
||||
if ($code === null) {
|
||||
$code = $this['config']->get('system.pages.redirect_default_code', 301);
|
||||
}
|
||||
|
||||
@@ -294,10 +329,13 @@ class Grav extends Container
|
||||
if ($uri->isExternal($route)) {
|
||||
$url = $route;
|
||||
} else {
|
||||
if ($this['config']->get('system.pages.redirect_trailing_slash', true))
|
||||
$url = rtrim($uri->rootUrl(), '/') .'/'. trim($route, '/'); // Remove trailing slash
|
||||
else
|
||||
$url = rtrim($uri->rootUrl(), '/') .'/'. ltrim($route, '/'); // Support trailing slash default routes
|
||||
$url = rtrim($uri->rootUrl(), '/') . '/';
|
||||
|
||||
if ($this['config']->get('system.pages.redirect_trailing_slash', true)) {
|
||||
$url .= trim($route, '/'); // Remove trailing slash
|
||||
} else {
|
||||
$url .= ltrim($route, '/'); // Support trailing slash default routes
|
||||
}
|
||||
}
|
||||
|
||||
header("Location: {$url}", true, $code);
|
||||
@@ -308,7 +346,7 @@ class Grav extends Container
|
||||
* Redirect browser to another location taking language into account (preferred)
|
||||
*
|
||||
* @param string $route Internal route.
|
||||
* @param int $code Redirection code (30x)
|
||||
* @param int $code Redirection code (30x)
|
||||
*/
|
||||
public function redirectLangSafe($route, $code = null)
|
||||
{
|
||||
@@ -316,9 +354,9 @@ class Grav extends Container
|
||||
$language = $this['language'];
|
||||
|
||||
if (!$this['uri']->isExternal($route) && $language->enabled() && $language->isIncludeDefaultLanguage()) {
|
||||
return $this->redirect($language->getLanguage() . $route, $code);
|
||||
$this->redirect($language->getLanguage() . $route, $code);
|
||||
} else {
|
||||
return $this->redirect($route, $code);
|
||||
$this->redirect($route, $code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,6 +364,7 @@ class Grav extends Container
|
||||
* Returns mime type for the file format.
|
||||
*
|
||||
* @param string $format
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function mime($format)
|
||||
@@ -342,6 +381,7 @@ class Grav extends Container
|
||||
case 'xml':
|
||||
return 'application/xml';
|
||||
}
|
||||
|
||||
return 'text/html';
|
||||
}
|
||||
|
||||
@@ -363,7 +403,7 @@ class Grav extends Container
|
||||
if ($expires > 0) {
|
||||
$expires_date = gmdate('D, d M Y H:i:s', time() + $expires) . ' GMT';
|
||||
header('Cache-Control: max-age=' . $expires);
|
||||
header('Expires: '. $expires_date);
|
||||
header('Expires: ' . $expires_date);
|
||||
}
|
||||
|
||||
// Set the last modified time
|
||||
@@ -398,12 +438,14 @@ class Grav extends Container
|
||||
*
|
||||
* @param string $eventName
|
||||
* @param Event $event
|
||||
*
|
||||
* @return Event
|
||||
*/
|
||||
public function fireEvent($eventName, Event $event = null)
|
||||
{
|
||||
/** @var EventDispatcher $events */
|
||||
$events = $this['events'];
|
||||
|
||||
return $events->dispatch($eventName, $event);
|
||||
}
|
||||
|
||||
@@ -461,10 +503,10 @@ class Grav extends Container
|
||||
|
||||
/**
|
||||
* This attempts to find media, other files, and download them
|
||||
* @param $page
|
||||
*
|
||||
* @param $path
|
||||
*/
|
||||
protected function fallbackUrl($page, $path)
|
||||
protected function fallbackUrl($path)
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
@@ -484,20 +526,22 @@ class Grav extends Container
|
||||
}
|
||||
|
||||
$path_parts = pathinfo($path);
|
||||
|
||||
/** @var Page $page */
|
||||
$page = $this['pages']->dispatch($path_parts['dirname'], true);
|
||||
|
||||
if ($page) {
|
||||
$media = $page->media()->all();
|
||||
|
||||
$parsed_url = parse_url(rawurldecode($uri->basename()));
|
||||
|
||||
$media_file = $parsed_url['path'];
|
||||
|
||||
// if this is a media object, try actions first
|
||||
if (isset($media[$media_file])) {
|
||||
/** @var Medium $medium */
|
||||
$medium = $media[$media_file];
|
||||
foreach ($uri->query(null, true) as $action => $params) {
|
||||
if (in_array($action, ImageMedium::$magic_actions)) {
|
||||
call_user_func_array(array(&$medium, $action), explode(',', $params));
|
||||
call_user_func_array([&$medium, $action], explode(',', $params));
|
||||
}
|
||||
}
|
||||
Utils::download($medium->path(), false);
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<?php
|
||||
namespace Grav\Common;
|
||||
|
||||
/**
|
||||
* Class GravTrait
|
||||
*
|
||||
* @package Grav\Common
|
||||
*/
|
||||
trait GravTrait
|
||||
{
|
||||
/**
|
||||
@@ -16,6 +21,7 @@ trait GravTrait
|
||||
if (!self::$grav) {
|
||||
self::$grav = Grav::instance();
|
||||
}
|
||||
|
||||
return self::$grav;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ class Truncator {
|
||||
list($txt, $nb, $opts) = static::truncateNode($doc, $childNode, $remaining, $opts);
|
||||
}
|
||||
else if ($childNode->nodeType === XML_TEXT_NODE) {
|
||||
list($txt, $nb, $opts) = static::truncateText($doc, $childNode, $remaining, $opts);
|
||||
list($txt, $nb, $opts) = static::truncateText($childNode, $remaining, $opts);
|
||||
} else {
|
||||
$txt = '';
|
||||
$nb = 0;
|
||||
@@ -141,7 +141,7 @@ class Truncator {
|
||||
return array($inner, $remaining, $opts);
|
||||
}
|
||||
|
||||
protected static function truncateText($doc, $node, $length, $opts)
|
||||
protected static function truncateText($node, $length, $opts)
|
||||
{
|
||||
$string = $node->textContent;
|
||||
|
||||
@@ -165,7 +165,7 @@ class Truncator {
|
||||
$words = $words[0];
|
||||
$count = count($words);
|
||||
if ($count <= $length && $length > 0) {
|
||||
return array($xhtml, $count, $opts);
|
||||
return array($string, $count, $opts);
|
||||
}
|
||||
return array(implode('', array_slice($words, 0, $length)), $count, $opts);
|
||||
}
|
||||
|
||||
@@ -4,20 +4,19 @@ namespace Grav\Common;
|
||||
/**
|
||||
* This file was originally part of the Akelos Framework
|
||||
*/
|
||||
use Grav\Common\Language\Language;
|
||||
|
||||
/**
|
||||
* Inflector for pluralize and singularize English nouns.
|
||||
*
|
||||
* This Inflector is a port of Ruby on Rails Inflector.
|
||||
*
|
||||
* It can be really helpful for developers that want to
|
||||
* create frameworks based on naming conventions rather than
|
||||
* configurations.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
* Inflector for pluralize and singularize English nouns.
|
||||
*
|
||||
* This Inflector is a port of Ruby on Rails Inflector.
|
||||
*
|
||||
* It can be really helpful for developers that want to
|
||||
* create frameworks based on naming conventions rather than
|
||||
* configurations.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
class Inflector
|
||||
{
|
||||
@@ -42,11 +41,13 @@ class Inflector
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to pluralize
|
||||
* @return string Plural noun
|
||||
*/
|
||||
* Pluralizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to pluralize
|
||||
* @param int $count The count
|
||||
*
|
||||
* @return string Plural noun
|
||||
*/
|
||||
public function pluralize($word, $count = 2)
|
||||
{
|
||||
$this->init();
|
||||
@@ -58,14 +59,14 @@ class Inflector
|
||||
$lowercased_word = strtolower($word);
|
||||
|
||||
foreach ($this->uncountable as $_uncountable) {
|
||||
if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) {
|
||||
if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->irregular as $_plural => $_singular) {
|
||||
if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
|
||||
return preg_replace('/('.$_plural.')$/i', substr($arr[0], 0, 1).substr($_singular, 1), $word);
|
||||
if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) {
|
||||
return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,17 +75,19 @@ class Inflector
|
||||
return preg_replace($rule, $replacement, $word);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Singularizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to singularize
|
||||
* @param int $count
|
||||
* @return string Singular noun.
|
||||
*/
|
||||
* Singularizes English nouns.
|
||||
*
|
||||
* @param string $word English noun to singularize
|
||||
* @param int $count
|
||||
*
|
||||
* @return string Singular noun.
|
||||
*/
|
||||
public function singularize($word, $count = 1)
|
||||
{
|
||||
$this->init();
|
||||
@@ -95,14 +98,14 @@ class Inflector
|
||||
|
||||
$lowercased_word = strtolower($word);
|
||||
foreach ($this->uncountable as $_uncountable) {
|
||||
if (substr($lowercased_word, (-1*strlen($_uncountable))) == $_uncountable) {
|
||||
if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->irregular as $_plural => $_singular) {
|
||||
if (preg_match('/('.$_singular.')$/i', $word, $arr)) {
|
||||
return preg_replace('/('.$_singular.')$/i', substr($arr[0], 0, 1).substr($_plural, 1), $word);
|
||||
if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) {
|
||||
return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,181 +119,206 @@ class Inflector
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an underscored or CamelCase word into a English
|
||||
* sentence.
|
||||
*
|
||||
* The titleize public function converts text like "WelcomePage",
|
||||
* "welcome_page" or "welcome page" to this "Welcome
|
||||
* Page".
|
||||
* If second parameter is set to 'first' it will only
|
||||
* capitalize the first character of the title.
|
||||
*
|
||||
* @param string $word Word to format as tile
|
||||
* @param string $uppercase If set to 'first' it will only uppercase the
|
||||
* first character. Otherwise it will uppercase all
|
||||
* the words in the title.
|
||||
* @return string Text formatted as title
|
||||
*/
|
||||
* Converts an underscored or CamelCase word into a English
|
||||
* sentence.
|
||||
*
|
||||
* The titleize public function converts text like "WelcomePage",
|
||||
* "welcome_page" or "welcome page" to this "Welcome
|
||||
* Page".
|
||||
* If second parameter is set to 'first' it will only
|
||||
* capitalize the first character of the title.
|
||||
*
|
||||
* @param string $word Word to format as tile
|
||||
* @param string $uppercase If set to 'first' it will only uppercase the
|
||||
* first character. Otherwise it will uppercase all
|
||||
* the words in the title.
|
||||
*
|
||||
* @return string Text formatted as title
|
||||
*/
|
||||
public function titleize($word, $uppercase = '')
|
||||
{
|
||||
$uppercase = $uppercase == 'first' ? 'ucfirst' : 'ucwords';
|
||||
|
||||
return $uppercase($this->humanize($this->underscorize($word)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns given word as CamelCased
|
||||
*
|
||||
* Converts a word like "send_email" to "SendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "WhoSOnline"
|
||||
*
|
||||
* @see variablize
|
||||
* @param string $word Word to convert to camel case
|
||||
* @return string UpperCamelCasedWord
|
||||
*/
|
||||
* Returns given word as CamelCased
|
||||
*
|
||||
* Converts a word like "send_email" to "SendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "WhoSOnline"
|
||||
*
|
||||
* @see variablize
|
||||
*
|
||||
* @param string $word Word to convert to camel case
|
||||
*
|
||||
* @return string UpperCamelCasedWord
|
||||
*/
|
||||
public function camelize($word)
|
||||
{
|
||||
return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a word "into_it_s_underscored_version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "underscored_word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to underscore
|
||||
* @return string Underscored word
|
||||
*/
|
||||
* Converts a word "into_it_s_underscored_version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "underscored_word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to underscore
|
||||
*
|
||||
* @return string Underscored word
|
||||
*/
|
||||
public function underscorize($word)
|
||||
{
|
||||
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1_\2', $word);
|
||||
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1_\2', $regex1);
|
||||
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '_', $regex2);
|
||||
return strtolower($regex3);
|
||||
|
||||
return strtolower($regex3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a word "into-it-s-hyphenated-version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "hyphenated-word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to hyphenate
|
||||
* @return string hyphenized word
|
||||
*/
|
||||
* Converts a word "into-it-s-hyphenated-version"
|
||||
*
|
||||
* Convert any "CamelCased" or "ordinary Word" into an
|
||||
* "hyphenated-word".
|
||||
*
|
||||
* This can be really useful for creating friendly URLs.
|
||||
*
|
||||
* @param string $word Word to hyphenate
|
||||
*
|
||||
* @return string hyphenized word
|
||||
*/
|
||||
public function hyphenize($word)
|
||||
{
|
||||
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word);
|
||||
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1-\2', $regex1);
|
||||
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex2);
|
||||
return strtolower($regex3);
|
||||
|
||||
return strtolower($regex3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable string from $word
|
||||
*
|
||||
* Returns a human-readable string from $word, by replacing
|
||||
* underscores with a space, and by upper-casing the initial
|
||||
* character by default.
|
||||
*
|
||||
* If you need to uppercase all the words you just have to
|
||||
* pass 'all' as a second parameter.
|
||||
*
|
||||
* @param string $word String to "humanize"
|
||||
* @param string $uppercase If set to 'all' it will uppercase all the words
|
||||
* instead of just the first one.
|
||||
* @return string Human-readable word
|
||||
*/
|
||||
* Returns a human-readable string from $word
|
||||
*
|
||||
* Returns a human-readable string from $word, by replacing
|
||||
* underscores with a space, and by upper-casing the initial
|
||||
* character by default.
|
||||
*
|
||||
* If you need to uppercase all the words you just have to
|
||||
* pass 'all' as a second parameter.
|
||||
*
|
||||
* @param string $word String to "humanize"
|
||||
* @param string $uppercase If set to 'all' it will uppercase all the words
|
||||
* instead of just the first one.
|
||||
*
|
||||
* @return string Human-readable word
|
||||
*/
|
||||
public function humanize($word, $uppercase = '')
|
||||
{
|
||||
$uppercase = $uppercase == 'all' ? 'ucwords' : 'ucfirst';
|
||||
|
||||
return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as camelize but first char is underscored
|
||||
*
|
||||
* Converts a word like "send_email" to "sendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "whoSOnline"
|
||||
*
|
||||
* @see camelize
|
||||
* @param string $word Word to lowerCamelCase
|
||||
* @return string Returns a lowerCamelCasedWord
|
||||
*/
|
||||
* Same as camelize but first char is underscored
|
||||
*
|
||||
* Converts a word like "send_email" to "sendEmail". It
|
||||
* will remove non alphanumeric character from the word, so
|
||||
* "who's online" will be converted to "whoSOnline"
|
||||
*
|
||||
* @see camelize
|
||||
*
|
||||
* @param string $word Word to lowerCamelCase
|
||||
*
|
||||
* @return string Returns a lowerCamelCasedWord
|
||||
*/
|
||||
public function variablize($word)
|
||||
{
|
||||
$word = $this->camelize($word);
|
||||
return strtolower($word[0]).substr($word, 1);
|
||||
|
||||
return strtolower($word[0]) . substr($word, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a class name to its table name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "Person" to "people"
|
||||
*
|
||||
* @see classify
|
||||
* @param string $class_name Class name for getting related table_name.
|
||||
* @return string plural_table_name
|
||||
*/
|
||||
* Converts a class name to its table name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "Person" to "people"
|
||||
*
|
||||
* @see classify
|
||||
*
|
||||
* @param string $class_name Class name for getting related table_name.
|
||||
*
|
||||
* @return string plural_table_name
|
||||
*/
|
||||
public function tableize($class_name)
|
||||
{
|
||||
return $this->pluralize($this->underscore($class_name));
|
||||
return $this->pluralize($this->underscorize($class_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a table name to its class name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "people" to "Person"
|
||||
*
|
||||
* @see tableize
|
||||
* @param string $table_name Table name for getting related ClassName.
|
||||
* @return string SingularClassName
|
||||
*/
|
||||
* Converts a table name to its class name according to rails
|
||||
* naming conventions.
|
||||
*
|
||||
* Converts "people" to "Person"
|
||||
*
|
||||
* @see tableize
|
||||
*
|
||||
* @param string $table_name Table name for getting related ClassName.
|
||||
*
|
||||
* @return string SingularClassName
|
||||
*/
|
||||
public function classify($table_name)
|
||||
{
|
||||
return $this->camelize($this->singularize($table_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts number to its ordinal English form.
|
||||
*
|
||||
* This method converts 13 to 13th, 2 to 2nd ...
|
||||
*
|
||||
* @param integer $number Number to get its ordinal value
|
||||
* @return string Ordinal representation of given string.
|
||||
*/
|
||||
* Converts number to its ordinal English form.
|
||||
*
|
||||
* This method converts 13 to 13th, 2 to 2nd ...
|
||||
*
|
||||
* @param integer $number Number to get its ordinal value
|
||||
*
|
||||
* @return string Ordinal representation of given string.
|
||||
*/
|
||||
public function ordinalize($number)
|
||||
{
|
||||
$this->init();
|
||||
|
||||
|
||||
if (in_array(($number % 100), range(11, 13))) {
|
||||
return $number.$this->ordinals['default'];
|
||||
return $number . $this->ordinals['default'];
|
||||
} else {
|
||||
switch (($number % 10)) {
|
||||
case 1:
|
||||
return $number.$this->ordinals['first'];
|
||||
return $number . $this->ordinals['first'];
|
||||
break;
|
||||
case 2:
|
||||
return $number.$this->ordinals['second'];
|
||||
return $number . $this->ordinals['second'];
|
||||
break;
|
||||
case 3:
|
||||
return $number.$this->ordinals['third'];
|
||||
return $number . $this->ordinals['third'];
|
||||
break;
|
||||
default:
|
||||
return $number.$this->ordinals['default'];
|
||||
return $number . $this->ordinals['default'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a number of days to a number of months
|
||||
*
|
||||
* @param int $days
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function monthize($days)
|
||||
{
|
||||
$now = new \DateTime();
|
||||
@@ -300,9 +328,9 @@ class Inflector
|
||||
|
||||
$diff = $end->add($duration)->diff($now);
|
||||
|
||||
// handle years
|
||||
// handle years
|
||||
if ($diff->y > 0) {
|
||||
$diff->m = $diff->m + 12*$diff->y;
|
||||
$diff->m = $diff->m + 12 * $diff->y;
|
||||
}
|
||||
|
||||
return $diff->m;
|
||||
|
||||
@@ -26,6 +26,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $args
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($key, $args)
|
||||
@@ -79,11 +80,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
* Return nth item.
|
||||
*
|
||||
* @param int $key
|
||||
*
|
||||
* @return mixed|bool
|
||||
*/
|
||||
public function nth($key)
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
|
||||
return (isset($items[$key])) ? $this->offsetGet($items[$key]) : false;
|
||||
}
|
||||
|
||||
@@ -95,6 +98,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
public function first()
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
|
||||
return $this->offsetGet(array_shift($items));
|
||||
}
|
||||
|
||||
@@ -106,6 +110,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
public function last()
|
||||
{
|
||||
$items = array_keys($this->items);
|
||||
|
||||
return $this->offsetGet(array_pop($items));
|
||||
}
|
||||
|
||||
@@ -117,11 +122,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
public function reverse()
|
||||
{
|
||||
$this->items = array_reverse($this->items);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $needle Searched value.
|
||||
*
|
||||
* @return string|bool Key if found, otherwise false.
|
||||
*/
|
||||
public function indexOf($needle)
|
||||
@@ -131,6 +138,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -144,7 +152,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
$keys = array_keys($this->items);
|
||||
shuffle($keys);
|
||||
|
||||
$new = array();
|
||||
$new = [];
|
||||
foreach ($keys as $key) {
|
||||
$new[$key] = $this->items[$key];
|
||||
}
|
||||
@@ -159,6 +167,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function slice($offset, $length = null)
|
||||
@@ -171,12 +180,13 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
/**
|
||||
* Pick one or more random entries.
|
||||
*
|
||||
* @param int $num Specifies how many entries should be picked.
|
||||
* @param int $num Specifies how many entries should be picked.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function random($num = 1)
|
||||
{
|
||||
$this->items = array_intersect_key($this->items, array_flip((array) array_rand($this->items, $num)));
|
||||
$this->items = array_intersect_key($this->items, array_flip((array)array_rand($this->items, $num)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -184,7 +194,8 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
/**
|
||||
* Append new elements to the list.
|
||||
*
|
||||
* @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values.
|
||||
* @param array|Iterator $items Items to be appended. Existing keys will be overridden with the new values.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function append($items)
|
||||
@@ -192,14 +203,17 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
if ($items instanceof static) {
|
||||
$items = $items->toArray();
|
||||
}
|
||||
$this->items = array_merge($this->items, (array) $items);
|
||||
$this->items = array_merge($this->items, (array)$items);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter elements from the list
|
||||
* @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate filter status
|
||||
*
|
||||
* @param callable|null $callback A function the receives ($value, $key) and must return a boolean to indicate
|
||||
* filter status
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(callable $callback = null)
|
||||
@@ -207,7 +221,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
foreach ($this->items as $key => $value) {
|
||||
if (
|
||||
($callback && !call_user_func($callback, $value, $key)) ||
|
||||
(!$callback && !(bool) $value)
|
||||
(!$callback && !(bool)$value)
|
||||
) {
|
||||
unset($this->items[$key]);
|
||||
}
|
||||
@@ -230,7 +244,9 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
*/
|
||||
public function sort(callable $callback = null, $desc = false)
|
||||
{
|
||||
if (!$callback || !is_callable($callback)) { return $this; }
|
||||
if (!$callback || !is_callable($callback)) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$items = $this->items;
|
||||
uasort($items, $callback);
|
||||
|
||||
@@ -252,6 +252,8 @@ class Language
|
||||
/**
|
||||
* Gets an array of valid extensions with active first, then fallback extensions
|
||||
*
|
||||
* @param string|null $file_ext
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getFallbackPageExtensions($file_ext = null)
|
||||
@@ -328,15 +330,15 @@ class Language
|
||||
/**
|
||||
* Translate a key and possibly arguments into a string using current lang and fallbacks
|
||||
*
|
||||
* @param $args first argument is the lookup key value
|
||||
* other arguments can be passed and replaced in the translation with sprintf syntax
|
||||
* @param Array $languages
|
||||
* @param mixed $args The first argument is the lookup key value
|
||||
* Other arguments can be passed and replaced in the translation with sprintf syntax
|
||||
* @param array $languages
|
||||
* @param bool $array_support
|
||||
* @param bool $html_out
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function translate($args, Array $languages = null, $array_support = false, $html_out = false)
|
||||
public function translate($args, array $languages = null, $array_support = false, $html_out = false)
|
||||
{
|
||||
if (is_array($args)) {
|
||||
$lookup = array_shift($args);
|
||||
@@ -345,7 +347,6 @@ class Language
|
||||
$args = [];
|
||||
}
|
||||
|
||||
|
||||
if ($this->config->get('system.languages.translations', true)) {
|
||||
if ($this->enabled() && $lookup) {
|
||||
if (empty($languages)) {
|
||||
@@ -422,8 +423,8 @@ class Language
|
||||
/**
|
||||
* Lookup the translation text for a given lang and key
|
||||
*
|
||||
* @param $lang lang code
|
||||
* @param $key key to lookup with
|
||||
* @param string $lang lang code
|
||||
* @param string $key key to lookup with
|
||||
* @param bool $array_support
|
||||
*
|
||||
* @return string
|
||||
@@ -438,6 +439,13 @@ class Language
|
||||
return $translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the browser accepted languages
|
||||
*
|
||||
* @param array $accept_langs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBrowserLanguages($accept_langs = [])
|
||||
{
|
||||
if (empty($this->http_accept_language)) {
|
||||
@@ -451,9 +459,9 @@ class Language
|
||||
// split $pref again by ';q='
|
||||
// and decorate the language entries by inverted position
|
||||
if (false !== ($i = strpos($pref, ';q='))) {
|
||||
$langs[substr($pref, 0, $i)] = array((float)substr($pref, $i + 3), -$k);
|
||||
$langs[substr($pref, 0, $i)] = [(float)substr($pref, $i + 3), -$k];
|
||||
} else {
|
||||
$langs[$pref] = array(1, -$k);
|
||||
$langs[$pref] = [1, -$k];
|
||||
}
|
||||
}
|
||||
arsort($langs);
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<?php
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
/**
|
||||
* Class Parsedown
|
||||
* @package Grav\Common\Markdown
|
||||
*/
|
||||
class Parsedown extends \Parsedown
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
/**
|
||||
* Parsedown constructor.
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
*/
|
||||
public function __construct($page, $defaults)
|
||||
{
|
||||
$this->init($page, $defaults);
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<?php
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
/**
|
||||
* Class ParsedownExtra
|
||||
* @package Grav\Common\Markdown
|
||||
*/
|
||||
class ParsedownExtra extends \ParsedownExtra
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
/**
|
||||
* ParsedownExtra constructor.
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
*/
|
||||
public function __construct($page, $defaults)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\GravTrait;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Common\Uri;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
@@ -11,12 +13,20 @@ use RocketTheme\Toolbox\Event\Event;
|
||||
trait ParsedownGravTrait
|
||||
{
|
||||
use GravTrait;
|
||||
|
||||
/** @var Page $page */
|
||||
protected $page;
|
||||
|
||||
/** @var Pages $pages */
|
||||
protected $pages;
|
||||
protected $base_url;
|
||||
|
||||
/** @var Uri $uri */
|
||||
protected $uri;
|
||||
|
||||
protected $pages_dir;
|
||||
protected $special_chars;
|
||||
protected $twig_link_regex = '/\!*\[(?:.*)\]\((\{([\{%#])\s*(.*?)\s*(?:\2|\})\})\)/';
|
||||
protected $special_protocols = ['xmpp', 'mailto', 'tel', 'sms'];
|
||||
|
||||
public $completable_blocks = [];
|
||||
public $continuable_blocks = [];
|
||||
@@ -33,10 +43,10 @@ trait ParsedownGravTrait
|
||||
|
||||
$this->page = $page;
|
||||
$this->pages = $grav['pages'];
|
||||
$this->uri = $grav['uri'];
|
||||
$this->BlockTypes['{'] [] = "TwigTag";
|
||||
$this->base_url = rtrim(self::getGrav()['base_url'] . self::getGrav()['pages']->base(), '/');
|
||||
$this->pages_dir = self::getGrav()['locator']->findResource('page://');
|
||||
$this->special_chars = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
|
||||
$this->special_chars = ['>' => 'gt', '<' => 'lt', '"' => 'quot'];
|
||||
|
||||
if ($defaults === null) {
|
||||
$defaults = self::getGrav()['config']->get('system.pages.markdown');
|
||||
@@ -59,7 +69,7 @@ trait ParsedownGravTrait
|
||||
*/
|
||||
public function addBlockType($type, $tag, $continuable = false, $completable = false)
|
||||
{
|
||||
$this->BlockTypes[$type] []= $tag;
|
||||
$this->BlockTypes[$type] [] = $tag;
|
||||
|
||||
if ($continuable) {
|
||||
$this->continuable_blocks[] = $tag;
|
||||
@@ -78,7 +88,7 @@ trait ParsedownGravTrait
|
||||
*/
|
||||
public function addInlineType($type, $tag)
|
||||
{
|
||||
$this->InlineTypes[$type] []= $tag;
|
||||
$this->InlineTypes[$type] [] = $tag;
|
||||
$this->inlineMarkerList .= $type;
|
||||
}
|
||||
|
||||
@@ -86,11 +96,13 @@ trait ParsedownGravTrait
|
||||
* Overrides the default behavior to allow for plugin-provided blocks to be continuable
|
||||
*
|
||||
* @param $Type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlockContinuable($Type)
|
||||
{
|
||||
$continuable = in_array($Type, $this->continuable_blocks) || method_exists($this, 'block'.$Type.'Continue');
|
||||
$continuable = in_array($Type, $this->continuable_blocks) || method_exists($this, 'block' . $Type . 'Continue');
|
||||
|
||||
return $continuable;
|
||||
}
|
||||
|
||||
@@ -98,11 +110,13 @@ trait ParsedownGravTrait
|
||||
* Overrides the default behavior to allow for plugin-provided blocks to be completable
|
||||
*
|
||||
* @param $Type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlockCompletable($Type)
|
||||
{
|
||||
$completable = in_array($Type, $this->completable_blocks) || method_exists($this, 'block'.$Type.'Complete');
|
||||
$completable = in_array($Type, $this->completable_blocks) || method_exists($this, 'block' . $Type . 'Complete');
|
||||
|
||||
return $completable;
|
||||
}
|
||||
|
||||
@@ -110,7 +124,8 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Make the element function publicly accessible, Medium uses this to render from Twig
|
||||
*
|
||||
* @param array $Element
|
||||
* @param array $Element
|
||||
*
|
||||
* @return string markup
|
||||
*/
|
||||
public function elementToHtml(array $Element)
|
||||
@@ -138,27 +153,28 @@ trait ParsedownGravTrait
|
||||
protected function blockTwigTag($Line)
|
||||
{
|
||||
if (preg_match('/(?:{{|{%|{#)(.*)(?:}}|%}|#})/', $Line['body'], $matches)) {
|
||||
$Block = array(
|
||||
$Block = [
|
||||
'markup' => $Line['body'],
|
||||
);
|
||||
];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function inlineSpecialCharacter($Excerpt)
|
||||
{
|
||||
if ($Excerpt['text'][0] === '&' && ! preg_match('/^&#?\w+;/', $Excerpt['text'])) {
|
||||
return array(
|
||||
if ($Excerpt['text'][0] === '&' && !preg_match('/^&#?\w+;/', $Excerpt['text'])) {
|
||||
return [
|
||||
'markup' => '&',
|
||||
'extent' => 1,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
if (isset($this->special_chars[$Excerpt['text'][0]])) {
|
||||
return array(
|
||||
'markup' => '&'.$this->special_chars[$Excerpt['text'][0]].';',
|
||||
return [
|
||||
'markup' => '&' . $this->special_chars[$Excerpt['text'][0]] . ';',
|
||||
'extent' => 1,
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +185,7 @@ trait ParsedownGravTrait
|
||||
$excerpt = parent::inlineImage($excerpt);
|
||||
$excerpt['element']['attributes']['src'] = $matches[1];
|
||||
$excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1;
|
||||
|
||||
return $excerpt;
|
||||
} else {
|
||||
$excerpt['type'] = 'image';
|
||||
@@ -176,7 +193,7 @@ trait ParsedownGravTrait
|
||||
}
|
||||
|
||||
// Some stuff we will need
|
||||
$actions = array();
|
||||
$actions = [];
|
||||
$media = null;
|
||||
|
||||
// if this is an image
|
||||
@@ -188,23 +205,24 @@ trait ParsedownGravTrait
|
||||
//get the url and parse it
|
||||
$url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['src']));
|
||||
|
||||
$this_host = isset($url['host']) && $url['host'] == $this->uri->host();
|
||||
|
||||
// if there is no host set but there is a path, the file is local
|
||||
if (!isset($url['host']) && isset($url['path'])) {
|
||||
if ((!isset($url['host']) || $this_host) && isset($url['path'])) {
|
||||
$path_parts = pathinfo($url['path']);
|
||||
|
||||
// get the local path to page media if possible
|
||||
if ($path_parts['dirname'] == $this->page->url(false, false, false)) {
|
||||
$url['path'] = urldecode($path_parts['basename']);
|
||||
// get the media objects for this page
|
||||
$media = $this->page->media();
|
||||
} else {
|
||||
// see if this is an external page to this one
|
||||
$page_route = str_replace($this->base_url, '', $path_parts['dirname']);
|
||||
$base_url = rtrim(self::getGrav()['base_url_relative'] . self::getGrav()['pages']->base(), '/');
|
||||
$page_route = '/' . ltrim(str_replace($base_url, '', $path_parts['dirname']), '/');
|
||||
|
||||
$ext_page = $this->pages->dispatch($page_route, true);
|
||||
if ($ext_page) {
|
||||
$media = $ext_page->media();
|
||||
$url['path'] = urldecode($path_parts['basename']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +236,7 @@ trait ParsedownGravTrait
|
||||
$actions = array_reduce(explode('&', $url['query']), function ($carry, $item) {
|
||||
$parts = explode('=', $item, 2);
|
||||
$value = isset($parts[1]) ? $parts[1] : null;
|
||||
$carry[] = [ 'method' => $parts[0], 'params' => $value ];
|
||||
$carry[] = ['method' => $parts[0], 'params' => $value];
|
||||
|
||||
return $carry;
|
||||
}, []);
|
||||
@@ -226,14 +244,15 @@ trait ParsedownGravTrait
|
||||
|
||||
// loop through actions for the image and call them
|
||||
foreach ($actions as $action) {
|
||||
$medium = call_user_func_array(array($medium, $action['method']), explode(',', urldecode($action['params'])));
|
||||
$medium = call_user_func_array([$medium, $action['method']],
|
||||
explode(',', urldecode($action['params'])));
|
||||
}
|
||||
|
||||
if (isset($url['fragment'])) {
|
||||
$medium->urlHash($url['fragment']);
|
||||
}
|
||||
|
||||
$excerpt['element'] = $medium->parseDownElement($title, $alt, $class);
|
||||
$excerpt['element'] = $medium->parseDownElement($title, $alt, $class, true);
|
||||
|
||||
} else {
|
||||
// not a current page media file, see if it needs converting to relative
|
||||
@@ -259,6 +278,7 @@ trait ParsedownGravTrait
|
||||
$excerpt = parent::inlineLink($excerpt);
|
||||
$excerpt['element']['attributes']['href'] = $matches[1];
|
||||
$excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1;
|
||||
|
||||
return $excerpt;
|
||||
} else {
|
||||
$excerpt = parent::inlineLink($excerpt);
|
||||
@@ -300,8 +320,7 @@ trait ParsedownGravTrait
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$url['query']= http_build_query($actions, null, '&', PHP_QUERY_RFC3986);
|
||||
$url['query'] = http_build_query($actions, null, '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
// if no query elements left, unset query
|
||||
@@ -309,12 +328,21 @@ trait ParsedownGravTrait
|
||||
unset ($url['query']);
|
||||
}
|
||||
|
||||
// if there is no scheme, the file is local and we'll need to convert that URL
|
||||
if (!isset($url['scheme']) && (count($url) > 0)) {
|
||||
$excerpt['element']['attributes']['href'] = Uri::convertUrl($this->page, Uri::buildUrl($url), $type, true);
|
||||
} else {
|
||||
$excerpt['element']['attributes']['href'] = Uri::buildUrl($url);
|
||||
// set path to / if not set
|
||||
if (empty($url['path'])) {
|
||||
$url['path'] = '';
|
||||
}
|
||||
|
||||
// if special scheme, just return
|
||||
if(isset($url['scheme']) && in_array($url['scheme'], $this->special_protocols)) {
|
||||
return $excerpt;
|
||||
}
|
||||
|
||||
// handle paths and such
|
||||
$url = Uri::convertUrl($this->page, $url, $type);
|
||||
|
||||
// build the URL from the component parts and set it on the element
|
||||
$excerpt['element']['attributes']['href'] = Uri::buildUrl($url);
|
||||
}
|
||||
|
||||
return $excerpt;
|
||||
@@ -325,6 +353,7 @@ trait ParsedownGravTrait
|
||||
{
|
||||
if (isset($this->$method) === true) {
|
||||
$func = $this->$method;
|
||||
|
||||
return call_user_func_array($func, $args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use Grav\Common\Utils;
|
||||
/**
|
||||
* Collection of Pages.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Collection extends Iterator
|
||||
@@ -23,7 +23,14 @@ class Collection extends Iterator
|
||||
*/
|
||||
protected $params;
|
||||
|
||||
public function __construct($items = array(), array $params = array(), Pages $pages = null)
|
||||
/**
|
||||
* Collection constructor.
|
||||
*
|
||||
* @param array $items
|
||||
* @param array $params
|
||||
* @param Pages|null $pages
|
||||
*/
|
||||
public function __construct($items = [], array $params = [], Pages $pages = null)
|
||||
{
|
||||
parent::__construct($items);
|
||||
|
||||
@@ -31,6 +38,11 @@ class Collection extends Iterator
|
||||
$this->pages = $pages ? $pages : Grav::instance()->offsetGet('pages');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection params
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function params()
|
||||
{
|
||||
return $this->params;
|
||||
@@ -40,11 +52,13 @@ class Collection extends Iterator
|
||||
* Add a single page to a collection
|
||||
*
|
||||
* @param Page $page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPage(Page $page)
|
||||
{
|
||||
$this->items[$page->path()] = ['slug' => $page->slug()];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -63,11 +77,13 @@ class Collection extends Iterator
|
||||
* Set parameters to the Collection
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParams(array $params)
|
||||
{
|
||||
$this->params = array_merge($this->params, $params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -79,6 +95,7 @@ class Collection extends Iterator
|
||||
public function current()
|
||||
{
|
||||
$current = parent::key();
|
||||
|
||||
return $this->pages->get($current);
|
||||
}
|
||||
|
||||
@@ -90,13 +107,15 @@ class Collection extends Iterator
|
||||
public function key()
|
||||
{
|
||||
$current = parent::current();
|
||||
|
||||
return $current['slug'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
*
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
@@ -108,6 +127,7 @@ class Collection extends Iterator
|
||||
* Remove item from the list.
|
||||
*
|
||||
* @param Page|string|null $key
|
||||
*
|
||||
* @return $this|void
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
@@ -123,6 +143,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
parent::remove($key);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -132,6 +153,7 @@ class Collection extends Iterator
|
||||
* @param string $by
|
||||
* @param string $dir
|
||||
* @param array $manual
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function order($by, $dir = 'asc', $manual = null)
|
||||
@@ -145,6 +167,7 @@ class Collection extends Iterator
|
||||
* Check to see if this item is the first in the collection.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return boolean True if item is first.
|
||||
*/
|
||||
public function isFirst($path)
|
||||
@@ -160,11 +183,12 @@ class Collection extends Iterator
|
||||
* Check to see if this item is the last in the collection.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return boolean True if item is last.
|
||||
*/
|
||||
public function isLast($path)
|
||||
{
|
||||
if ($this->items && $path == array_keys($this->items)[count($this->items)-1]) {
|
||||
if ($this->items && $path == array_keys($this->items)[count($this->items) - 1]) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -174,7 +198,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Gets the previous sibling based on current position.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
*
|
||||
* @return Page The previous item.
|
||||
*/
|
||||
public function prevSibling($path)
|
||||
@@ -185,7 +210,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Gets the next sibling based on current position.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
*
|
||||
* @return Page The next item.
|
||||
*/
|
||||
public function nextSibling($path)
|
||||
@@ -198,6 +224,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path
|
||||
* @param integer $direction either -1 or +1
|
||||
*
|
||||
* @return Page The sibling item.
|
||||
*/
|
||||
public function adjacentSibling($path, $direction = 1)
|
||||
@@ -210,6 +237,7 @@ class Collection extends Iterator
|
||||
|
||||
return isset($values[$index]) ? $this->offsetGet($values[$index]) : $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
@@ -217,7 +245,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Returns the item in the current position.
|
||||
*
|
||||
* @param string $path the path the item
|
||||
* @param string $path the path the item
|
||||
*
|
||||
* @return Page Item in the array the the current position.
|
||||
*/
|
||||
public function currentPosition($path)
|
||||
@@ -256,6 +285,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $date_range;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -275,6 +305,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -294,6 +325,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $visible;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -313,6 +345,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $modular;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -332,6 +365,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $modular;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -351,6 +385,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $published;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -370,6 +405,7 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $published;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -391,6 +427,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $routable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -410,12 +447,15 @@ class Collection extends Iterator
|
||||
}
|
||||
}
|
||||
$this->items = $routable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new collection with only pages of the specified type
|
||||
*
|
||||
* @param $type
|
||||
*
|
||||
* @return Collection The collection
|
||||
*/
|
||||
public function ofType($type)
|
||||
@@ -430,12 +470,15 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new collection with only pages of one of the specified types
|
||||
*
|
||||
* @param $types
|
||||
*
|
||||
* @return Collection The collection
|
||||
*/
|
||||
public function ofOneOfTheseTypes($types)
|
||||
@@ -450,12 +493,15 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates new collection with only pages of one of the specified access levels
|
||||
*
|
||||
* @param $accessLevels
|
||||
*
|
||||
* @return Collection The collection
|
||||
*/
|
||||
public function ofOneOfTheseAccessLevels($accessLevels)
|
||||
@@ -472,7 +518,7 @@ class Collection extends Iterator
|
||||
|
||||
foreach ($page->header()->access as $index => $accessLevel) {
|
||||
if (is_array($accessLevel)) {
|
||||
foreach($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
foreach ($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
if (in_array($innerAccessLevel, $accessLevels)) {
|
||||
$valid = true;
|
||||
}
|
||||
@@ -497,11 +543,7 @@ class Collection extends Iterator
|
||||
}
|
||||
|
||||
$this->items = $items;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,10 @@ namespace Grav\Common\Page;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Constructor;
|
||||
use RocketTheme\Toolbox\ArrayTraits\NestedArrayAccess;
|
||||
|
||||
/**
|
||||
* Class Header
|
||||
* @package Grav\Common\Page
|
||||
*/
|
||||
class Header implements \ArrayAccess
|
||||
{
|
||||
use NestedArrayAccess, Constructor;
|
||||
|
||||
@@ -20,11 +20,11 @@ class Media extends Getters
|
||||
protected $gettersVariable = 'instances';
|
||||
protected $path;
|
||||
|
||||
protected $instances = array();
|
||||
protected $images = array();
|
||||
protected $videos = array();
|
||||
protected $audios = array();
|
||||
protected $files = array();
|
||||
protected $instances = [];
|
||||
protected $images = [];
|
||||
protected $videos = [];
|
||||
protected $audios = [];
|
||||
protected $files = [];
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Medium;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
|
||||
class ImageMedium extends Medium
|
||||
@@ -136,7 +137,15 @@ class ImageMedium extends Medium
|
||||
*/
|
||||
public function url($reset = true)
|
||||
{
|
||||
$output = preg_replace('|^' . preg_quote(GRAV_ROOT) . '|', '', $this->saveImage());
|
||||
$image_path = self::$grav['locator']->findResource('cache://images', true);
|
||||
$image_dir = self::$grav['locator']->findResource('cache://images', false);
|
||||
$saved_image_path = $this->saveImage();
|
||||
|
||||
$output = preg_replace('|^' . preg_quote(GRAV_ROOT) . '|', '', $saved_image_path);
|
||||
|
||||
if (Utils::startsWith($output, $image_path)) {
|
||||
$output = '/' . $image_dir . preg_replace('|^' . preg_quote($image_path) . '|', '', $output);
|
||||
}
|
||||
|
||||
if ($reset) {
|
||||
$this->reset();
|
||||
@@ -155,6 +164,7 @@ class ImageMedium extends Medium
|
||||
if (!$this->image) {
|
||||
$this->image();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -261,6 +271,7 @@ class ImageMedium extends Medium
|
||||
if ($this->image) {
|
||||
$this->image();
|
||||
$this->image->clearOperations(); // Clear previously applied operations
|
||||
$this->querystring('');
|
||||
$this->filter();
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ class Medium extends Data implements RenderableInterface
|
||||
* Return PATH to file.
|
||||
*
|
||||
* @param bool $reset
|
||||
* @return string path to file
|
||||
* @return string path to file
|
||||
*/
|
||||
public function path($reset = true)
|
||||
{
|
||||
@@ -155,7 +155,7 @@ class Medium extends Data implements RenderableInterface
|
||||
*/
|
||||
public function querystring($querystring = null, $withQuestionmark = true)
|
||||
{
|
||||
if ($querystring) {
|
||||
if (!is_null($querystring)) {
|
||||
$this->set('querystring', ltrim($querystring, '?&'));
|
||||
|
||||
foreach ($this->alternatives as $alt) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,24 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Cache;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Language;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\Blueprints;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Plugin\Admin;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use Whoops\Exception\ErrorException;
|
||||
|
||||
/**
|
||||
* GravPages is the class that is the entry point into the hierarchy of pages
|
||||
* Pages is the class that is the entry point into the hierarchy of pages
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Pages
|
||||
@@ -46,7 +46,7 @@ class Pages
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected $routes = array();
|
||||
protected $routes = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@@ -63,8 +63,19 @@ class Pages
|
||||
*/
|
||||
protected $last_modified;
|
||||
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected $ignore_files;
|
||||
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected $ignore_folders;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $ignore_hidden;
|
||||
|
||||
/**
|
||||
@@ -72,6 +83,9 @@ class Pages
|
||||
*/
|
||||
static protected $types;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
static protected $home_route;
|
||||
|
||||
/**
|
||||
@@ -89,6 +103,7 @@ class Pages
|
||||
* Get or set base path for the pages.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function base($path = null)
|
||||
@@ -111,6 +126,10 @@ class Pages
|
||||
$this->ignore_folders = $config->get('system.pages.ignore_folders');
|
||||
$this->ignore_hidden = $config->get('system.pages.ignore_hidden');
|
||||
|
||||
$this->instances = [];
|
||||
$this->children = [];
|
||||
$this->routes = [];
|
||||
|
||||
$this->buildPages();
|
||||
}
|
||||
|
||||
@@ -118,6 +137,7 @@ class Pages
|
||||
* Get or set last modification time.
|
||||
*
|
||||
* @param int $modified
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function lastModified($modified = null)
|
||||
@@ -125,6 +145,7 @@ class Pages
|
||||
if ($modified && $modified > $this->last_modified) {
|
||||
$this->last_modified = $modified;
|
||||
}
|
||||
|
||||
return $this->last_modified;
|
||||
}
|
||||
|
||||
@@ -151,8 +172,8 @@ class Pages
|
||||
/**
|
||||
* Adds a page and assigns a route to it.
|
||||
*
|
||||
* @param Page $page Page to be added.
|
||||
* @param string $route Optional route (uses route from the object if not set).
|
||||
* @param Page $page Page to be added.
|
||||
* @param string $route Optional route (uses route from the object if not set).
|
||||
*/
|
||||
public function addPage(Page $page, $route = null)
|
||||
{
|
||||
@@ -161,7 +182,7 @@ class Pages
|
||||
}
|
||||
$route = $page->route($route);
|
||||
if ($page->parent()) {
|
||||
$this->children[$page->parent()->path()][$page->path()] = array('slug' => $page->slug());
|
||||
$this->children[$page->parent()->path()][$page->path()] = ['slug' => $page->slug()];
|
||||
}
|
||||
$this->routes[$route] = $page->path();
|
||||
}
|
||||
@@ -169,7 +190,7 @@ class Pages
|
||||
/**
|
||||
* Sort sub-pages in a page.
|
||||
*
|
||||
* @param Page $page
|
||||
* @param Page $page
|
||||
* @param string $order_by
|
||||
* @param string $order_dir
|
||||
*
|
||||
@@ -185,7 +206,7 @@ class Pages
|
||||
}
|
||||
|
||||
$path = $page->path();
|
||||
$children = isset($this->children[$path]) ? $this->children[$path] : array();
|
||||
$children = isset($this->children[$path]) ? $this->children[$path] : [];
|
||||
|
||||
if (!$children) {
|
||||
return $children;
|
||||
@@ -206,9 +227,10 @@ class Pages
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @param $orderBy
|
||||
* @param string $orderDir
|
||||
* @param null $orderManual
|
||||
* @param $orderBy
|
||||
* @param string $orderDir
|
||||
* @param null $orderManual
|
||||
*
|
||||
* @return array
|
||||
* @internal
|
||||
*/
|
||||
@@ -219,7 +241,7 @@ class Pages
|
||||
return [];
|
||||
}
|
||||
|
||||
$lookup = md5(json_encode($items));
|
||||
$lookup = md5(json_encode($items) . json_encode($orderManual) . $orderBy . $orderDir);
|
||||
if (!isset($this->sort[$lookup][$orderBy])) {
|
||||
$this->buildSort($lookup, $items, $orderBy, $orderManual);
|
||||
}
|
||||
@@ -237,7 +259,8 @@ class Pages
|
||||
/**
|
||||
* Get a page instance.
|
||||
*
|
||||
* @param string $path The filesystem full path of the page
|
||||
* @param string $path The filesystem full path of the page
|
||||
*
|
||||
* @return Page
|
||||
* @throws \Exception
|
||||
*/
|
||||
@@ -246,26 +269,30 @@ class Pages
|
||||
if (!is_null($path) && !is_string($path)) {
|
||||
throw new \Exception();
|
||||
}
|
||||
return isset($this->instances[(string) $path]) ? $this->instances[(string) $path] : null;
|
||||
|
||||
return isset($this->instances[(string)$path]) ? $this->instances[(string)$path] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get children of the path.
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function children($path)
|
||||
{
|
||||
$children = isset($this->children[(string) $path]) ? $this->children[(string) $path] : array();
|
||||
return new Collection($children, array(), $this);
|
||||
$children = isset($this->children[(string)$path]) ? $this->children[(string)$path] : [];
|
||||
|
||||
return new Collection($children, [], $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch URI to a page.
|
||||
*
|
||||
* @param string $url The relative URL of the page
|
||||
* @param bool $all
|
||||
* @param bool $all
|
||||
*
|
||||
* @return Page|null
|
||||
*/
|
||||
public function dispatch($url, $all = false)
|
||||
@@ -297,28 +324,34 @@ class Pages
|
||||
$page = $this->dispatch($route, $all);
|
||||
} else {
|
||||
// Try Regex style redirects
|
||||
foreach ((array)$config->get("site.redirects") as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$this->grav->redirectLangSafe($found);
|
||||
$site_redirects = $config->get("site.redirects");
|
||||
if (is_array($site_redirects)) {
|
||||
foreach ((array)$site_redirects as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$this->grav->redirectLangSafe($found);
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Try Regex style routes
|
||||
foreach ((array)$config->get("site.routes") as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$page = $this->dispatch($found, $all);
|
||||
$site_routes = $config->get("site.routes");
|
||||
if (is_array($site_routes)) {
|
||||
foreach ((array)$site_routes as $pattern => $replace) {
|
||||
$pattern = '#' . $pattern . '#';
|
||||
try {
|
||||
$found = preg_replace($pattern, $replace, $url);
|
||||
if ($found != $url) {
|
||||
$page = $this->dispatch($found, $all);
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.routes: ' . $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
} catch (ErrorException $e) {
|
||||
$this->grav['log']->error('site.routes: '. $pattern . '-> ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -336,14 +369,14 @@ class Pages
|
||||
{
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
|
||||
return $this->instances[rtrim($locator->findResource('page://'), DS)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a blueprint for a page type.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $type
|
||||
*
|
||||
* @return Blueprint
|
||||
*/
|
||||
public function blueprints($type)
|
||||
@@ -370,6 +403,7 @@ class Pages
|
||||
* Get all pages
|
||||
*
|
||||
* @param \Grav\Common\Page\Page $current
|
||||
*
|
||||
* @return \Grav\Common\Page\Collection
|
||||
*/
|
||||
public function all(Page $current = null)
|
||||
@@ -380,7 +414,7 @@ class Pages
|
||||
$current = $current ?: $this->root();
|
||||
|
||||
if (!$current->root()) {
|
||||
$all[$current->path()] = [ 'slug' => $current->slug() ];
|
||||
$all[$current->path()] = ['slug' => $current->slug()];
|
||||
}
|
||||
|
||||
foreach ($current->children() as $next) {
|
||||
@@ -394,11 +428,14 @@ class Pages
|
||||
* Get list of route/title of all pages.
|
||||
*
|
||||
* @param Page $current
|
||||
* @param int $level
|
||||
* @param int $level
|
||||
* @param bool $rawRoutes
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function getList(Page $current = null, $level = 0)
|
||||
public function getList(Page $current = null, $level = 0, $rawRoutes = false)
|
||||
{
|
||||
if (!$current) {
|
||||
if ($level) {
|
||||
@@ -408,14 +445,19 @@ class Pages
|
||||
$current = $this->root();
|
||||
}
|
||||
|
||||
$list = array();
|
||||
$list = [];
|
||||
|
||||
if (!$current->root()) {
|
||||
$list[$current->route()] = str_repeat(' ', ($level-1)*2) . $current->title();
|
||||
if ($rawRoutes) {
|
||||
$route = $current->rawRoute();
|
||||
} else {
|
||||
$route = $current->route();
|
||||
}
|
||||
$list[$route] = str_repeat(' ', ($level - 1) * 2) . $current->title();
|
||||
}
|
||||
|
||||
foreach ($current->children() as $next) {
|
||||
$list = array_merge($list, $this->getList($next, $level + 1));
|
||||
$list = array_merge($list, $this->getList($next, $level + 1, $rawRoutes));
|
||||
}
|
||||
|
||||
return $list;
|
||||
@@ -494,12 +536,12 @@ class Pages
|
||||
public function accessLevels()
|
||||
{
|
||||
$accessLevels = [];
|
||||
foreach($this->all() as $page) {
|
||||
foreach ($this->all() as $page) {
|
||||
if (isset($page->header()->access)) {
|
||||
if (is_array($page->header()->access)) {
|
||||
foreach($page->header()->access as $index => $accessLevel) {
|
||||
foreach ($page->header()->access as $index => $accessLevel) {
|
||||
if (is_array($accessLevel)) {
|
||||
foreach($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
foreach ($accessLevel as $innerIndex => $innerAccessLevel) {
|
||||
array_push($accessLevels, $innerIndex);
|
||||
}
|
||||
} else {
|
||||
@@ -517,18 +559,44 @@ class Pages
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available parents.
|
||||
* Get available parents routes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parents()
|
||||
{
|
||||
$rawRoutes = false;
|
||||
|
||||
return self::getParents($rawRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available parents raw routes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parentsRawRoutes()
|
||||
{
|
||||
$rawRoutes = true;
|
||||
|
||||
return self::getParents($rawRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available parents routes
|
||||
*
|
||||
* @param bool $rawRoutes get the raw route or the normal route
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getParents($rawRoutes)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Pages $pages */
|
||||
$pages = $grav['pages'];
|
||||
|
||||
$parents = $pages->getList();
|
||||
$parents = $pages->getList(null, 0, $rawRoutes);
|
||||
|
||||
/** @var Admin $admin */
|
||||
$admin = $grav['admin'];
|
||||
@@ -547,13 +615,13 @@ class Pages
|
||||
}
|
||||
|
||||
/**
|
||||
* Get's the home route
|
||||
* Gets the home route
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getHomeRoute()
|
||||
{
|
||||
if (empty(self::$home)) {
|
||||
if (empty(self::$home_route)) {
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Config $config */
|
||||
@@ -585,9 +653,19 @@ class Pages
|
||||
|
||||
self::$home_route = trim($home, '/');
|
||||
}
|
||||
|
||||
return self::$home_route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed for testing where we change the home route via config
|
||||
*/
|
||||
public static function resetHomeRoute()
|
||||
{
|
||||
self::$home_route = null;
|
||||
return self::getHomeRoute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds pages.
|
||||
*
|
||||
@@ -595,7 +673,7 @@ class Pages
|
||||
*/
|
||||
protected function buildPages()
|
||||
{
|
||||
$this->sort = array();
|
||||
$this->sort = [];
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
@@ -626,7 +704,7 @@ class Pages
|
||||
$last_modified = Folder::lastModifiedFile($pages_dir);
|
||||
}
|
||||
|
||||
$page_cache_id = md5(USER_DIR.$last_modified.$language->getActive().$config->checksum());
|
||||
$page_cache_id = md5(USER_DIR . $last_modified . $language->getActive() . $config->checksum());
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
|
||||
if (!$this->instances) {
|
||||
@@ -659,35 +737,33 @@ class Pages
|
||||
|
||||
// cache if needed
|
||||
if ($this->grav['config']->get('system.cache.enabled')) {
|
||||
/** @var Cache $cache */
|
||||
/** @var Cache $cache */
|
||||
$cache = $this->grav['cache'];
|
||||
/** @var Taxonomy $taxonomy */
|
||||
$taxonomy = $this->grav['taxonomy'];
|
||||
|
||||
// save pages, routes, taxonomy, and sort to cache
|
||||
$cache->save(
|
||||
$page_cache_id,
|
||||
array($this->instances, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort)
|
||||
);
|
||||
$cache->save($page_cache_id, [$this->instances, $this->routes, $this->children, $taxonomy->taxonomy(), $this->sort]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive function to load & build page relationships.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param string $directory
|
||||
* @param Page|null $parent
|
||||
*
|
||||
* @return Page
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
*/
|
||||
protected function recurse($directory, Page &$parent = null)
|
||||
{
|
||||
$directory = rtrim($directory, DS);
|
||||
$page = new Page;
|
||||
$directory = rtrim($directory, DS);
|
||||
$page = new Page;
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
$config = $this->grav['config'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
@@ -713,20 +789,21 @@ class Pages
|
||||
if (!isset($this->instances[$page->path()])) {
|
||||
$this->instances[$page->path()] = $page;
|
||||
if ($parent && $page->path()) {
|
||||
$this->children[$parent->path()][$page->path()] = array('slug' => $page->slug());
|
||||
$this->children[$parent->path()][$page->path()] = ['slug' => $page->slug()];
|
||||
}
|
||||
} else {
|
||||
throw new \RuntimeException('Fatal error when creating page instances.');
|
||||
}
|
||||
|
||||
$content_exists = false;
|
||||
$pages_found = glob($directory.'/*'.CONTENT_EXT);
|
||||
$page_extensions = $language->getFallbackPageExtensions();
|
||||
$pages_found = glob($directory . '/*' . CONTENT_EXT);
|
||||
$page_extension = '';
|
||||
|
||||
if ($pages_found) {
|
||||
$page_extensions = $language->getFallbackPageExtensions();
|
||||
foreach ($page_extensions as $extension) {
|
||||
foreach ($pages_found as $found) {
|
||||
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+('.$extension.')$/', $found)) {
|
||||
if (preg_match('/^.*\/[0-9A-Za-z\-\_]+(' . $extension . ')$/', $found)) {
|
||||
$page_found = $found;
|
||||
$page_extension = $extension;
|
||||
break 2;
|
||||
@@ -770,14 +847,14 @@ class Pages
|
||||
$page->path($file->getPath());
|
||||
}
|
||||
|
||||
$path = $directory.DS.$name;
|
||||
$path = $directory . DS . $name;
|
||||
$child = $this->recurse($path, $page);
|
||||
|
||||
if (Utils::startsWith($name, '_')) {
|
||||
$child->routable(false);
|
||||
}
|
||||
|
||||
$this->children[$page->path()][$child->path()] = array('slug' => $child->slug());
|
||||
$this->children[$page->path()][$child->path()] = ['slug' => $child->slug()];
|
||||
|
||||
if ($config->get('system.pages.events.page')) {
|
||||
$this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
|
||||
@@ -790,9 +867,20 @@ class Pages
|
||||
$page->routable(false);
|
||||
}
|
||||
|
||||
// Override the modified time if modular
|
||||
if ($page->template() == 'modular') {
|
||||
foreach ($page->collection() as $child) {
|
||||
$modified = $child->modified();
|
||||
|
||||
if ($modified > $last_modified) {
|
||||
$last_modified = $modified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Override the modified and ID so that it takes the latest change into account
|
||||
$page->modified($last_modified);
|
||||
$page->id($last_modified.md5($page->filePath()));
|
||||
$page->id($last_modified . md5($page->filePath()));
|
||||
|
||||
// Sort based on Defaults or Page Overridden sort order
|
||||
$this->children[$page->path()] = $this->sort($page);
|
||||
@@ -809,7 +897,7 @@ class Pages
|
||||
$taxonomy = $this->grav['taxonomy'];
|
||||
|
||||
// Get the home route
|
||||
$home = self::getHomeRoute();
|
||||
$home = self::resetHomeRoute();
|
||||
|
||||
// Build routes and taxonomy map.
|
||||
/** @var $page Page */
|
||||
@@ -818,7 +906,7 @@ class Pages
|
||||
// process taxonomy
|
||||
$taxonomy->addTaxonomy($page);
|
||||
|
||||
$route = $page->route();
|
||||
$route = $page->route();
|
||||
$raw_route = $page->rawRoute();
|
||||
$page_path = $page->path();
|
||||
|
||||
@@ -855,19 +943,20 @@ class Pages
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
* @param array $pages
|
||||
* @param array $pages
|
||||
* @param string $order_by
|
||||
* @param array $manual
|
||||
* @param array $manual
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
*/
|
||||
protected function buildSort($path, array $pages, $order_by = 'default', $manual = null)
|
||||
{
|
||||
$list = array();
|
||||
$list = [];
|
||||
$header_default = null;
|
||||
$header_query = null;
|
||||
|
||||
// do this headery query work only once
|
||||
// do this header query work only once
|
||||
if (strpos($order_by, 'header.') === 0) {
|
||||
$header_query = explode('|', str_replace('header.', '', $order_by));
|
||||
if (isset($header_query[1])) {
|
||||
@@ -924,7 +1013,7 @@ class Pages
|
||||
|
||||
// Move manually ordered items into the beginning of the list. Order of the unlisted items does not change.
|
||||
if (is_array($manual) && !empty($manual)) {
|
||||
$new_list = array();
|
||||
$new_list = [];
|
||||
$i = count($manual);
|
||||
|
||||
foreach ($list as $key => $dummy) {
|
||||
@@ -933,7 +1022,7 @@ class Pages
|
||||
if ($order === false) {
|
||||
$order = $i++;
|
||||
}
|
||||
$new_list[$key] = (int) $order;
|
||||
$new_list[$key] = (int)$order;
|
||||
}
|
||||
|
||||
$list = $new_list;
|
||||
@@ -948,13 +1037,19 @@ class Pages
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffles and associative array
|
||||
/**
|
||||
* Shuffles an associative array
|
||||
*
|
||||
* @param array $list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function arrayShuffle($list)
|
||||
{
|
||||
$keys = array_keys($list);
|
||||
shuffle($keys);
|
||||
|
||||
$new = array();
|
||||
$new = [];
|
||||
foreach ($keys as $key) {
|
||||
$new[$key] = $list[$key];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use RocketTheme\Toolbox\File\YamlFile;
|
||||
/**
|
||||
* The Plugin object just holds the id and path to a plugin.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Plugin implements EventSubscriberInterface
|
||||
@@ -41,7 +41,7 @@ class Plugin implements EventSubscriberInterface
|
||||
{
|
||||
$methods = get_class_methods(get_called_class());
|
||||
|
||||
$list = array();
|
||||
$list = [];
|
||||
foreach ($methods as $method) {
|
||||
if (strpos($method, 'on') === 0) {
|
||||
$list[$method] = [$method, 0];
|
||||
@@ -54,9 +54,9 @@ class Plugin implements EventSubscriberInterface
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name
|
||||
* @param Grav $grav
|
||||
* @param Config $config
|
||||
* @param string $name
|
||||
* @param Grav $grav
|
||||
* @param Config $config
|
||||
*/
|
||||
public function __construct($name, Grav $grav, Config $config)
|
||||
{
|
||||
@@ -70,6 +70,7 @@ class Plugin implements EventSubscriberInterface
|
||||
if (isset($this->grav['admin'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -83,12 +84,12 @@ class Plugin implements EventSubscriberInterface
|
||||
|
||||
foreach ($events as $eventName => $params) {
|
||||
if (is_string($params)) {
|
||||
$dispatcher->addListener($eventName, array($this, $params));
|
||||
$dispatcher->addListener($eventName, [$this, $params]);
|
||||
} elseif (is_string($params[0])) {
|
||||
$dispatcher->addListener($eventName, array($this, $params[0]), isset($params[1]) ? $params[1] : 0);
|
||||
$dispatcher->addListener($eventName, [$this, $params[0]], isset($params[1]) ? $params[1] : 0);
|
||||
} else {
|
||||
foreach ($params as $listener) {
|
||||
$dispatcher->addListener($eventName, array($this, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
|
||||
$dispatcher->addListener($eventName, [$this, $listener[0]], isset($listener[1]) ? $listener[1] : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,12 +105,12 @@ class Plugin implements EventSubscriberInterface
|
||||
|
||||
foreach ($events as $eventName => $params) {
|
||||
if (is_string($params)) {
|
||||
$dispatcher->removeListener($eventName, array($this, $params));
|
||||
$dispatcher->removeListener($eventName, [$this, $params]);
|
||||
} elseif (is_string($params[0])) {
|
||||
$dispatcher->removeListener($eventName, array($this, $params[0]));
|
||||
$dispatcher->removeListener($eventName, [$this, $params[0]]);
|
||||
} else {
|
||||
foreach ($params as $listener) {
|
||||
$dispatcher->removeListener($eventName, array($this, $listener[0]));
|
||||
$dispatcher->removeListener($eventName, [$this, $listener[0]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,15 +123,16 @@ class Plugin implements EventSubscriberInterface
|
||||
*
|
||||
* format: [plugin:myplugin_name](function_data)
|
||||
*
|
||||
* @param $content The string to perform operations upon
|
||||
* @param $function The anonymous callback function
|
||||
* @param string $internal_regex Optional internal regex to extra data from
|
||||
* @param string $content The string to perform operations upon
|
||||
* @param callable $function The anonymous callback function
|
||||
* @param string $internal_regex Optional internal regex to extra data from
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function parseLinks($content, $function, $internal_regex = '(.*)')
|
||||
{
|
||||
$regex = '/\[plugin:(?:'.$this->name.')\]\('.$internal_regex.'\)/i';
|
||||
$regex = '/\[plugin:(?:' . $this->name . ')\]\(' . $internal_regex . '\)/i';
|
||||
|
||||
return preg_replace_callback($regex, $function, $content);
|
||||
}
|
||||
|
||||
@@ -149,7 +151,7 @@ class Plugin implements EventSubscriberInterface
|
||||
{
|
||||
$class_name = $this->name;
|
||||
$class_name_merged = $class_name . '.merged';
|
||||
$defaults = $this->config->get('plugins.'. $class_name, []);
|
||||
$defaults = $this->config->get('plugins.' . $class_name, []);
|
||||
$page_header = $page->header();
|
||||
$header = [];
|
||||
if (!isset($page_header->$class_name_merged) && isset($page_header->$class_name)) {
|
||||
@@ -180,6 +182,7 @@ class Plugin implements EventSubscriberInterface
|
||||
} else {
|
||||
$header = array_merge($header, $params);
|
||||
}
|
||||
|
||||
// Return configurations as a new data config class
|
||||
return new Data($header);
|
||||
}
|
||||
@@ -187,11 +190,12 @@ class Plugin implements EventSubscriberInterface
|
||||
/**
|
||||
* Persists to disk the plugin parameters currently stored in the Grav Config object
|
||||
*
|
||||
* @param string $plugin_name The name of the plugin whose config it should store.
|
||||
* @param string $plugin_name The name of the plugin whose config it should store.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public static function saveConfig($plugin_name) {
|
||||
public static function saveConfig($plugin_name)
|
||||
{
|
||||
if (!$plugin_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use RocketTheme\Toolbox\Event\EventSubscriberInterface;
|
||||
* The Plugins object holds an array of all the plugin objects that
|
||||
* Grav knows about
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Plugins extends Iterator
|
||||
@@ -29,7 +29,7 @@ class Plugins extends Iterator
|
||||
{
|
||||
/** @var Config $config */
|
||||
$config = self::getGrav()['config'];
|
||||
$plugins = (array) $config->get('plugins');
|
||||
$plugins = (array)$config->get('plugins');
|
||||
|
||||
$inflector = self::getGrav()['inflector'];
|
||||
|
||||
@@ -52,8 +52,8 @@ class Plugins extends Iterator
|
||||
require_once $filePath;
|
||||
|
||||
$pluginClassFormat = [
|
||||
'Grav\\Plugin\\'.ucfirst($plugin).'Plugin',
|
||||
'Grav\\Plugin\\'.$inflector->camelize($plugin).'Plugin'
|
||||
'Grav\\Plugin\\' . ucfirst($plugin) . 'Plugin',
|
||||
'Grav\\Plugin\\' . $inflector->camelize($plugin) . 'Plugin'
|
||||
];
|
||||
$pluginClassName = false;
|
||||
|
||||
@@ -65,7 +65,8 @@ class Plugins extends Iterator
|
||||
}
|
||||
|
||||
if (false === $pluginClassName) {
|
||||
throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", $plugin));
|
||||
throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.",
|
||||
$plugin));
|
||||
}
|
||||
|
||||
$instance = new $pluginClassName($plugin, self::getGrav(), $config);
|
||||
@@ -77,6 +78,11 @@ class Plugins extends Iterator
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a plugin
|
||||
*
|
||||
* @param $plugin
|
||||
*/
|
||||
public function add($plugin)
|
||||
{
|
||||
if (is_object($plugin)) {
|
||||
@@ -91,10 +97,10 @@ class Plugins extends Iterator
|
||||
*/
|
||||
public static function all()
|
||||
{
|
||||
$list = array();
|
||||
$list = [];
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$plugins = (array) $locator->findResources('plugins://', false);
|
||||
$plugins = (array)$locator->findResources('plugins://', false);
|
||||
foreach ($plugins as $path) {
|
||||
$iterator = new \DirectoryIterator($path);
|
||||
|
||||
@@ -117,6 +123,13 @@ class Plugins extends Iterator
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a plugin by name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Data|null
|
||||
*/
|
||||
public static function get($name)
|
||||
{
|
||||
$blueprints = new Blueprints('plugins://');
|
||||
|
||||
@@ -22,7 +22,7 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container['setup'] = function ($c) {
|
||||
return static::setup($c)->init();
|
||||
return static::setup($c);
|
||||
};
|
||||
|
||||
$container['blueprints'] = function ($c) {
|
||||
|
||||
@@ -9,11 +9,19 @@ class Session extends \RocketTheme\Toolbox\Session\Session
|
||||
protected $grav;
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* Session constructor.
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->grav = $grav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Session init
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
/** @var Uri $uri */
|
||||
@@ -37,10 +45,7 @@ class Session extends \RocketTheme\Toolbox\Session\Session
|
||||
|
||||
if ($config->get('system.session.enabled') || $is_admin) {
|
||||
// Define session service.
|
||||
parent::__construct(
|
||||
$session_timeout,
|
||||
$session_path
|
||||
);
|
||||
parent::__construct($session_timeout, $session_path);
|
||||
|
||||
$domain = $uri->host();
|
||||
if ($domain == 'localhost') {
|
||||
|
||||
@@ -22,7 +22,7 @@ use Grav\Common\Page\Page;
|
||||
* [tag][grav][path/to/item2]
|
||||
* [tag][dog][path/to/item3]
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Taxonomy
|
||||
@@ -32,10 +32,12 @@ class Taxonomy
|
||||
|
||||
/**
|
||||
* Constructor that resets the map
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
$this->taxonomy_map = array();
|
||||
$this->taxonomy_map = [];
|
||||
$this->grav = $grav;
|
||||
}
|
||||
|
||||
@@ -43,7 +45,7 @@ class Taxonomy
|
||||
* Takes an individual page and processes the taxonomies configured in its header. It
|
||||
* then adds those taxonomies to the map
|
||||
*
|
||||
* @param Page $page the page to process
|
||||
* @param Page $page the page to process
|
||||
* @param array $page_taxonomy
|
||||
*/
|
||||
public function addTaxonomy(Page $page, $page_taxonomy = null)
|
||||
@@ -59,10 +61,10 @@ class Taxonomy
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
if ($config->get('site.taxonomies')) {
|
||||
foreach ((array) $config->get('site.taxonomies') as $taxonomy) {
|
||||
foreach ((array)$config->get('site.taxonomies') as $taxonomy) {
|
||||
if (isset($page_taxonomy[$taxonomy])) {
|
||||
foreach ((array) $page_taxonomy[$taxonomy] as $item) {
|
||||
$this->taxonomy_map[$taxonomy][(string) $item][$page->path()] = array('slug' => $page->slug());
|
||||
foreach ((array)$page_taxonomy[$taxonomy] as $item) {
|
||||
$this->taxonomy_map[$taxonomy][(string)$item][$page->path()] = ['slug' => $page->slug()];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,8 +75,9 @@ class Taxonomy
|
||||
* Returns a new Page object with the sub-pages containing all the values set for a
|
||||
* particular taxonomy.
|
||||
*
|
||||
* @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
|
||||
* @param string $operator can be 'or' or 'and' (defaults to 'or')
|
||||
* @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
|
||||
* @param string $operator can be 'or' or 'and' (defaults to 'or')
|
||||
*
|
||||
* @return Collection Collection object set to contain matches found in the taxonomy map
|
||||
*/
|
||||
public function findTaxonomy($taxonomies, $operator = 'and')
|
||||
@@ -83,7 +86,7 @@ class Taxonomy
|
||||
$results = [];
|
||||
|
||||
foreach ((array)$taxonomies as $taxonomy => $items) {
|
||||
foreach ((array) $items as $item) {
|
||||
foreach ((array)$items as $item) {
|
||||
if (isset($this->taxonomy_map[$taxonomy][$item])) {
|
||||
$matches[] = $this->taxonomy_map[$taxonomy][$item];
|
||||
}
|
||||
@@ -108,6 +111,7 @@ class Taxonomy
|
||||
* Gets and Sets the taxonomy map
|
||||
*
|
||||
* @param array $var the taxonomy map
|
||||
*
|
||||
* @return array the taxonomy map
|
||||
*/
|
||||
public function taxonomy($var = null)
|
||||
@@ -115,6 +119,7 @@ class Taxonomy
|
||||
if ($var) {
|
||||
$this->taxonomy_map = $var;
|
||||
}
|
||||
|
||||
return $this->taxonomy_map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
|
||||
/**
|
||||
* Class Theme
|
||||
* @package Grav\Common
|
||||
*/
|
||||
class Theme extends Plugin
|
||||
{
|
||||
public $name;
|
||||
@@ -10,7 +15,7 @@ class Theme extends Plugin
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Grav $grav
|
||||
* @param Grav $grav
|
||||
* @param Config $config
|
||||
* @param string $name
|
||||
*/
|
||||
@@ -24,11 +29,12 @@ class Theme extends Plugin
|
||||
/**
|
||||
* Persists to disk the theme parameters currently stored in the Grav Config object
|
||||
*
|
||||
* @param string $theme_name The name of the theme whose config it should store.
|
||||
* @param string $theme_name The name of the theme whose config it should store.
|
||||
*
|
||||
* @return true
|
||||
*/
|
||||
public static function saveConfig($theme_name) {
|
||||
public static function saveConfig($theme_name)
|
||||
{
|
||||
if (!$theme_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
/**
|
||||
* The Themes object holds an array of all the theme objects that Grav knows about.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Themes extends Iterator
|
||||
@@ -23,6 +23,11 @@ class Themes extends Iterator
|
||||
/** @var Config */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Themes constructor.
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
parent::__construct();
|
||||
@@ -51,7 +56,7 @@ class Themes extends Iterator
|
||||
try {
|
||||
$instance = $themes->load();
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new \RuntimeException($this->current(). ' theme could not be found');
|
||||
throw new \RuntimeException($this->current() . ' theme could not be found');
|
||||
}
|
||||
|
||||
if ($instance instanceof EventSubscriberInterface) {
|
||||
@@ -73,10 +78,10 @@ class Themes extends Iterator
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$list = array();
|
||||
$list = [];
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
$themes = (array) $locator->findResources('themes://', false);
|
||||
$themes = (array)$locator->findResources('themes://', false);
|
||||
foreach ($themes as $path) {
|
||||
$iterator = new \DirectoryIterator($path);
|
||||
|
||||
@@ -102,7 +107,8 @@ class Themes extends Iterator
|
||||
/**
|
||||
* Get theme configuration or throw exception if it cannot be found.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $name
|
||||
*
|
||||
* @return Data
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
@@ -126,7 +132,9 @@ class Themes extends Iterator
|
||||
|
||||
// Find thumbnail.
|
||||
$thumb = "themes://{$name}/thumbnail.jpg";
|
||||
if ($path = $this->grav['locator']->findResource($thumb, false)) {
|
||||
$path = $this->grav['locator']->findResource($thumb, false);
|
||||
|
||||
if ($path) {
|
||||
$blueprint->set('thumbnail', $this->grav['base_url'] . '/' . $path);
|
||||
}
|
||||
|
||||
@@ -149,7 +157,7 @@ class Themes extends Iterator
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return (string) $this->config->get('system.pages.theme');
|
||||
return (string)$this->config->get('system.pages.theme');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,10 +184,9 @@ class Themes extends Iterator
|
||||
|
||||
if (!is_object($class)) {
|
||||
$themeClassFormat = [
|
||||
'Grav\\Theme\\'.ucfirst($name),
|
||||
'Grav\\Theme\\'.$inflector->camelize($name)
|
||||
'Grav\\Theme\\' . ucfirst($name),
|
||||
'Grav\\Theme\\' . $inflector->camelize($name)
|
||||
];
|
||||
$themeClassName = false;
|
||||
|
||||
foreach ($themeClassFormat as $themeClass) {
|
||||
if (class_exists($themeClass)) {
|
||||
@@ -253,8 +260,8 @@ class Themes extends Iterator
|
||||
/**
|
||||
* Load theme configuration.
|
||||
*
|
||||
* @param string $name Theme name
|
||||
* @param Config $config Configuration class
|
||||
* @param string $name Theme name
|
||||
* @param Config $config Configuration class
|
||||
*/
|
||||
protected function loadConfiguration($name, Config $config)
|
||||
{
|
||||
@@ -265,7 +272,7 @@ class Themes extends Iterator
|
||||
/**
|
||||
* Load theme languages.
|
||||
*
|
||||
* @param Config $config Configuration class
|
||||
* @param Config $config Configuration class
|
||||
*/
|
||||
protected function loadLanguages(Config $config)
|
||||
{
|
||||
@@ -282,7 +289,7 @@ class Themes extends Iterator
|
||||
|
||||
if ($languages) {
|
||||
$languages = call_user_func_array('array_replace_recursive', $languages);
|
||||
$config->getLanguages()->mergeRecursive($languages);
|
||||
$this->grav['languages']->mergeRecursive($languages);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -311,7 +318,7 @@ class Themes extends Iterator
|
||||
|
||||
// Load class
|
||||
if (file_exists($file)) {
|
||||
return include_once($file);
|
||||
return include_once($file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ namespace Grav\Common\Twig;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Page;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
@@ -12,7 +13,7 @@ use RocketTheme\Toolbox\Event\Event;
|
||||
* that is optimized so that it only needs to be initialized once and can be reused for individual
|
||||
* page template rendering as well as the main site template rendering.
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Twig
|
||||
@@ -25,7 +26,7 @@ class Twig
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $twig_vars;
|
||||
public $twig_vars = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
@@ -55,6 +56,8 @@ class Twig
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public function __construct(Grav $grav)
|
||||
{
|
||||
@@ -73,7 +76,6 @@ class Twig
|
||||
$config = $this->grav['config'];
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
$debugger = $this->grav['debugger'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
@@ -87,7 +89,7 @@ class Twig
|
||||
|
||||
// handle language templates if available
|
||||
if ($language->enabled()) {
|
||||
$lang_templates = $locator->findResource('theme://templates/'.($active_language ? $active_language : $language->getDefault()));
|
||||
$lang_templates = $locator->findResource('theme://templates/' . ($active_language ? $active_language : $language->getDefault()));
|
||||
if ($lang_templates) {
|
||||
$this->twig_paths[] = $lang_templates;
|
||||
}
|
||||
@@ -98,8 +100,8 @@ class Twig
|
||||
$this->grav->fireEvent('onTwigTemplatePaths');
|
||||
|
||||
$this->loader = new \Twig_Loader_Filesystem($this->twig_paths);
|
||||
$this->loaderArray = new \Twig_Loader_Array(array());
|
||||
$loader_chain = new \Twig_Loader_Chain(array($this->loaderArray, $this->loader));
|
||||
$this->loaderArray = new \Twig_Loader_Array([]);
|
||||
$loader_chain = new \Twig_Loader_Chain([$this->loaderArray, $this->loader]);
|
||||
|
||||
$params = $config->get('system.twig');
|
||||
if (!empty($params['cache'])) {
|
||||
@@ -114,7 +116,8 @@ class Twig
|
||||
return new \Twig_Function_Function($name);
|
||||
}
|
||||
|
||||
return new \Twig_Function_Function(function() {});
|
||||
return new \Twig_Function_Function(function () {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -124,7 +127,8 @@ class Twig
|
||||
return new \Twig_Filter_Function($name);
|
||||
}
|
||||
|
||||
return new \Twig_Filter_Function(function() {});
|
||||
return new \Twig_Filter_Function(function () {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,21 +147,21 @@ class Twig
|
||||
$this->grav->fireEvent('onTwigExtensions');
|
||||
|
||||
// Set some standard variables for twig
|
||||
$this->twig_vars = array(
|
||||
'config' => $config,
|
||||
'uri' => $this->grav['uri'],
|
||||
'base_dir' => rtrim(ROOT_DIR, '/'),
|
||||
'base_url' => $this->grav['base_url'] . $language_append,
|
||||
'base_url_simple' => $this->grav['base_url'],
|
||||
'base_url_absolute' => $this->grav['base_url_absolute'] . $language_append,
|
||||
'base_url_relative' => $this->grav['base_url_relative'] . $language_append,
|
||||
'theme_dir' => $locator->findResource('theme://'),
|
||||
'theme_url' => $this->grav['base_url'] .'/'. $locator->findResource('theme://', false),
|
||||
'site' => $config->get('site'),
|
||||
'assets' => $this->grav['assets'],
|
||||
'taxonomy' => $this->grav['taxonomy'],
|
||||
'browser' => $this->grav['browser'],
|
||||
);
|
||||
$this->twig_vars = $this->twig_vars + [
|
||||
'config' => $config,
|
||||
'uri' => $this->grav['uri'],
|
||||
'base_dir' => rtrim(ROOT_DIR, '/'),
|
||||
'base_url' => $this->grav['base_url'] . $language_append,
|
||||
'base_url_simple' => $this->grav['base_url'],
|
||||
'base_url_absolute' => $this->grav['base_url_absolute'] . $language_append,
|
||||
'base_url_relative' => $this->grav['base_url_relative'] . $language_append,
|
||||
'theme_dir' => $locator->findResource('theme://'),
|
||||
'theme_url' => $this->grav['base_url'] . '/' . $locator->findResource('theme://', false),
|
||||
'site' => $config->get('site'),
|
||||
'assets' => $this->grav['assets'],
|
||||
'taxonomy' => $this->grav['taxonomy'],
|
||||
'browser' => $this->grav['browser'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +199,7 @@ class Twig
|
||||
*
|
||||
* @param Page $item The page item to render
|
||||
* @param string $content Optional content override
|
||||
*
|
||||
* @return string The rendered output
|
||||
* @throws \Twig_Error_Loader
|
||||
*/
|
||||
@@ -203,7 +208,7 @@ class Twig
|
||||
$content = $content !== null ? $content : $item->content();
|
||||
|
||||
// override the twig header vars for local resolution
|
||||
$this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item]));
|
||||
$this->grav->fireEvent('onTwigPageVariables', new Event(['page' => $item]));
|
||||
$twig_vars = $this->twig_vars;
|
||||
|
||||
$twig_vars['page'] = $item;
|
||||
@@ -214,6 +219,8 @@ class Twig
|
||||
$modular_twig = $item->modularTwig();
|
||||
$process_twig = isset($item->header()->process['twig']) ? $item->header()->process['twig'] : false;
|
||||
|
||||
$output = '';
|
||||
|
||||
try {
|
||||
// Process Modular Twig
|
||||
if ($modular_twig) {
|
||||
@@ -240,10 +247,11 @@ class Twig
|
||||
* and optional array of variables
|
||||
*
|
||||
* @param string $template template to render with
|
||||
* @param array $vars Optional variables
|
||||
* @param array $vars Optional variables
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function processTemplate($template, $vars = array())
|
||||
public function processTemplate($template, $vars = [])
|
||||
{
|
||||
// override the twig header vars for local resolution
|
||||
$this->grav->fireEvent('onTwigTemplateVariables');
|
||||
@@ -264,11 +272,12 @@ class Twig
|
||||
* Process a Twig template directly by using a Twig string
|
||||
* and optional array of variables
|
||||
*
|
||||
* @param string $string string to render.
|
||||
* @param array $vars Optional variables
|
||||
* @param string $string string to render.
|
||||
* @param array $vars Optional variables
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function processString($string, array $vars = array())
|
||||
public function processString($string, array $vars = [])
|
||||
{
|
||||
// override the twig header vars for local resolution
|
||||
$this->grav->fireEvent('onTwigStringVariables');
|
||||
@@ -291,6 +300,7 @@ class Twig
|
||||
* page and handles all the layout for the site display.
|
||||
*
|
||||
* @param string $format Output format (defaults to HTML).
|
||||
*
|
||||
* @return string the rendered output
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
@@ -301,7 +311,6 @@ class Twig
|
||||
$pages = $this->grav['pages'];
|
||||
$page = $this->grav['page'];
|
||||
$content = $page->content();
|
||||
$config = $this->grav['config'];
|
||||
|
||||
$twig_vars = $this->twig_vars;
|
||||
|
||||
@@ -326,9 +335,9 @@ class Twig
|
||||
} catch (\Twig_Error_Loader $e) {
|
||||
$error_msg = $e->getMessage();
|
||||
// Try html version of this template if initial template was NOT html
|
||||
if ($ext != '.html'.TWIG_EXT) {
|
||||
if ($ext != '.html' . TWIG_EXT) {
|
||||
try {
|
||||
$output = $this->twig->render($page->template().'.html'.TWIG_EXT, $twig_vars);
|
||||
$output = $this->twig->render($page->template() . '.html' . TWIG_EXT, $twig_vars);
|
||||
} catch (\Twig_Error_Loader $e) {
|
||||
throw new \RuntimeException($error_msg, 400, $e);
|
||||
}
|
||||
@@ -345,6 +354,7 @@ class Twig
|
||||
* the one being passed in
|
||||
*
|
||||
* @param string $template the template name
|
||||
*
|
||||
* @return string the template name
|
||||
*/
|
||||
public function template($template)
|
||||
|
||||
@@ -5,12 +5,13 @@ use Grav\Common\Grav;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Markdown\Parsedown;
|
||||
use Grav\Common\Markdown\ParsedownExtra;
|
||||
use Grav\Common\Uri;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
/**
|
||||
* The Twig extension adds some filters and functions that are useful for Grav
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class TwigExtension extends \Twig_Extension
|
||||
@@ -19,6 +20,9 @@ class TwigExtension extends \Twig_Extension
|
||||
protected $debugger;
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* TwigExtension constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->grav = Grav::instance();
|
||||
@@ -43,9 +47,9 @@ class TwigExtension extends \Twig_Extension
|
||||
*/
|
||||
public function getGlobals()
|
||||
{
|
||||
return array(
|
||||
return [
|
||||
'grav' => $this->grav,
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,30 +60,30 @@ class TwigExtension extends \Twig_Extension
|
||||
public function getFilters()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFilter('*ize', [$this,'inflectorFilter']),
|
||||
new \Twig_SimpleFilter('*ize', [$this, 'inflectorFilter']),
|
||||
new \Twig_SimpleFilter('absolute_url', [$this, 'absoluteUrlFilter']),
|
||||
new \Twig_SimpleFilter('contains', [$this, 'containsFilter']),
|
||||
new \Twig_SimpleFilter('defined', [$this, 'definedDefaultFilter']),
|
||||
new \Twig_SimpleFilter('ends_with', [$this, 'endsWithFilter']),
|
||||
new \Twig_SimpleFilter('fieldName', [$this,'fieldNameFilter']),
|
||||
new \Twig_SimpleFilter('ksort', [$this,'ksortFilter']),
|
||||
new \Twig_SimpleFilter('fieldName', [$this, 'fieldNameFilter']),
|
||||
new \Twig_SimpleFilter('ksort', [$this, 'ksortFilter']),
|
||||
new \Twig_SimpleFilter('ltrim', [$this, 'ltrimFilter']),
|
||||
new \Twig_SimpleFilter('markdown', [$this, 'markdownFilter']),
|
||||
new \Twig_SimpleFilter('md5', [$this,'md5Filter']),
|
||||
new \Twig_SimpleFilter('md5', [$this, 'md5Filter']),
|
||||
new \Twig_SimpleFilter('nicetime', [$this, 'nicetimeFilter']),
|
||||
new \Twig_SimpleFilter('randomize', [$this,'randomizeFilter']),
|
||||
new \Twig_SimpleFilter('modulus', [$this,'modulusFilter']),
|
||||
new \Twig_SimpleFilter('randomize', [$this, 'randomizeFilter']),
|
||||
new \Twig_SimpleFilter('modulus', [$this, 'modulusFilter']),
|
||||
new \Twig_SimpleFilter('rtrim', [$this, 'rtrimFilter']),
|
||||
new \Twig_SimpleFilter('pad', [$this, 'padFilter']),
|
||||
new \Twig_SimpleFilter('safe_email', [$this,'safeEmailFilter']),
|
||||
new \Twig_SimpleFilter('safe_truncate', ['\Grav\Common\Utils','safeTruncate']),
|
||||
new \Twig_SimpleFilter('safe_truncate_html', ['\Grav\Common\Utils','safeTruncateHTML']),
|
||||
new \Twig_SimpleFilter('sort_by_key', [$this,'sortByKeyFilter']),
|
||||
new \Twig_SimpleFilter('safe_email', [$this, 'safeEmailFilter']),
|
||||
new \Twig_SimpleFilter('safe_truncate', ['\Grav\Common\Utils', 'safeTruncate']),
|
||||
new \Twig_SimpleFilter('safe_truncate_html', ['\Grav\Common\Utils', 'safeTruncateHTML']),
|
||||
new \Twig_SimpleFilter('sort_by_key', [$this, 'sortByKeyFilter']),
|
||||
new \Twig_SimpleFilter('starts_with', [$this, 'startsWithFilter']),
|
||||
new \Twig_SimpleFilter('t', [$this, 'translate']),
|
||||
new \Twig_SimpleFilter('ta', [$this, 'translateArray']),
|
||||
new \Twig_SimpleFilter('truncate', ['\Grav\Common\Utils','truncate']),
|
||||
new \Twig_SimpleFilter('truncate_html', ['\Grav\Common\Utils','truncateHTML']),
|
||||
new \Twig_SimpleFilter('truncate', ['\Grav\Common\Utils', 'truncate']),
|
||||
new \Twig_SimpleFilter('truncate_html', ['\Grav\Common\Utils', 'truncateHTML']),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -112,7 +116,8 @@ class TwigExtension extends \Twig_Extension
|
||||
/**
|
||||
* Filters field name by changing dot notation into array notation.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function fieldNameFilter($str)
|
||||
@@ -125,7 +130,8 @@ class TwigExtension extends \Twig_Extension
|
||||
/**
|
||||
* Protects email address.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function safeEmailFilter($str)
|
||||
@@ -133,8 +139,9 @@ class TwigExtension extends \Twig_Extension
|
||||
$email = '';
|
||||
$str_len = strlen($str);
|
||||
for ($i = 0; $i < $str_len; $i++) {
|
||||
$email .= "&#" . ord($str[$i]). ";";
|
||||
$email .= "&#" . ord($str[$i]) . ";";
|
||||
}
|
||||
|
||||
return $email;
|
||||
}
|
||||
|
||||
@@ -142,7 +149,8 @@ class TwigExtension extends \Twig_Extension
|
||||
* Returns array in a random order.
|
||||
*
|
||||
* @param array $original
|
||||
* @param int $offset Can be used to return only slice of the array.
|
||||
* @param int $offset Can be used to return only slice of the array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function randomizeFilter($original, $offset = 0)
|
||||
@@ -160,41 +168,44 @@ class TwigExtension extends \Twig_Extension
|
||||
shuffle($random);
|
||||
|
||||
$sizeOf = sizeof($original);
|
||||
for ($x=0; $x < $sizeOf; $x++) {
|
||||
for ($x = 0; $x < $sizeOf; $x++) {
|
||||
if ($x < $offset) {
|
||||
$sorted[] = $original[$x];
|
||||
} else {
|
||||
$sorted[] = array_shift($random);
|
||||
}
|
||||
}
|
||||
|
||||
return $sorted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the modulus of an integer
|
||||
*
|
||||
* @param int $number
|
||||
* @param int $divider
|
||||
* @param int $number
|
||||
* @param int $divider
|
||||
* @param array $items array of items to select from to return
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function modulusFilter($number, $divider, $items = null)
|
||||
{
|
||||
if (is_string($number)) {
|
||||
$number = strlen($number);
|
||||
}
|
||||
public function modulusFilter($number, $divider, $items = null)
|
||||
{
|
||||
if (is_string($number)) {
|
||||
$number = strlen($number);
|
||||
}
|
||||
|
||||
$remainder = $number % $divider;
|
||||
$remainder = $number % $divider;
|
||||
|
||||
if (is_array($items)) {
|
||||
if (isset($items[$remainder])) {
|
||||
return $items[$remainder];
|
||||
} else {
|
||||
return $items[0];
|
||||
}
|
||||
}
|
||||
return $remainder;
|
||||
}
|
||||
if (is_array($items)) {
|
||||
if (isset($items[$remainder])) {
|
||||
return $items[$remainder];
|
||||
} else {
|
||||
return $items[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $remainder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflector supports following notations:
|
||||
@@ -211,21 +222,22 @@ class TwigExtension extends \Twig_Extension
|
||||
*
|
||||
* @param string $action
|
||||
* @param string $data
|
||||
* @param int $count
|
||||
* @param int $count
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function inflectorFilter($action, $data, $count = null)
|
||||
{
|
||||
$action = $action.'ize';
|
||||
$action = $action . 'ize';
|
||||
|
||||
$inflector = $this->grav['inflector'];
|
||||
|
||||
if (in_array(
|
||||
$action,
|
||||
['titleize','camelize','underscorize','hyphenize', 'humanize','ordinalize','monthize']
|
||||
['titleize', 'camelize', 'underscorize', 'hyphenize', 'humanize', 'ordinalize', 'monthize']
|
||||
)) {
|
||||
return $inflector->$action($data);
|
||||
} elseif (in_array($action, ['pluralize','singularize'])) {
|
||||
} elseif (in_array($action, ['pluralize', 'singularize'])) {
|
||||
if ($count) {
|
||||
return $inflector->$action($data, $count);
|
||||
} else {
|
||||
@@ -240,6 +252,7 @@ class TwigExtension extends \Twig_Extension
|
||||
* Return MD5 hash from the input.
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function md5Filter($str)
|
||||
@@ -277,11 +290,13 @@ class TwigExtension extends \Twig_Extension
|
||||
* Return ksorted collection.
|
||||
*
|
||||
* @param array $array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function ksortFilter(array $array)
|
||||
{
|
||||
ksort($array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
@@ -314,14 +329,32 @@ class TwigExtension extends \Twig_Extension
|
||||
}
|
||||
|
||||
if ($long_strings) {
|
||||
$periods = array("NICETIME.SECOND", "NICETIME.MINUTE", "NICETIME.HOUR", "NICETIME.DAY", "NICETIME.WEEK", "NICETIME.MONTH", "NICETIME.YEAR", "NICETIME.DECADE");
|
||||
$periods = [
|
||||
"NICETIME.SECOND",
|
||||
"NICETIME.MINUTE",
|
||||
"NICETIME.HOUR",
|
||||
"NICETIME.DAY",
|
||||
"NICETIME.WEEK",
|
||||
"NICETIME.MONTH",
|
||||
"NICETIME.YEAR",
|
||||
"NICETIME.DECADE"
|
||||
];
|
||||
} else {
|
||||
$periods = array("NICETIME.SEC", "NICETIME.MIN", "NICETIME.HR", "NICETIME.DAY", "NICETIME.WK", "NICETIME.MO", "NICETIME.YR", "NICETIME.DEC");
|
||||
$periods = [
|
||||
"NICETIME.SEC",
|
||||
"NICETIME.MIN",
|
||||
"NICETIME.HR",
|
||||
"NICETIME.DAY",
|
||||
"NICETIME.WK",
|
||||
"NICETIME.MO",
|
||||
"NICETIME.YR",
|
||||
"NICETIME.DEC"
|
||||
];
|
||||
}
|
||||
|
||||
$lengths = array("60","60","24","7","4.35","12","10");
|
||||
$lengths = ["60", "60", "24", "7", "4.35", "12", "10"];
|
||||
|
||||
$now = time();
|
||||
$now = time();
|
||||
|
||||
// check if unix timestamp
|
||||
if ((string)(int)$date == $date) {
|
||||
@@ -337,15 +370,15 @@ class TwigExtension extends \Twig_Extension
|
||||
|
||||
// is it future date or past date
|
||||
if ($now > $unix_date) {
|
||||
$difference = $now - $unix_date;
|
||||
$tense = $this->grav['language']->translate('NICETIME.AGO', null, true);
|
||||
$difference = $now - $unix_date;
|
||||
$tense = $this->grav['language']->translate('NICETIME.AGO', null, true);
|
||||
|
||||
} else {
|
||||
$difference = $unix_date - $now;
|
||||
$tense = $this->grav['language']->translate('NICETIME.FROM_NOW', null, true);
|
||||
$difference = $unix_date - $now;
|
||||
$tense = $this->grav['language']->translate('NICETIME.FROM_NOW', null, true);
|
||||
}
|
||||
|
||||
for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths)-1; $j++) {
|
||||
for ($j = 0; $difference >= $lengths[$j] && $j < count($lengths) - 1; $j++) {
|
||||
$difference /= $lengths[$j];
|
||||
}
|
||||
|
||||
@@ -355,7 +388,9 @@ class TwigExtension extends \Twig_Extension
|
||||
$periods[$j] .= '_PLURAL';
|
||||
}
|
||||
|
||||
if ($this->grav['language']->getTranslation($this->grav['language']->getLanguage(), $periods[$j] . '_MORE_THAN_TWO')) {
|
||||
if ($this->grav['language']->getTranslation($this->grav['language']->getLanguage(),
|
||||
$periods[$j] . '_MORE_THAN_TWO')
|
||||
) {
|
||||
if ($difference > 2) {
|
||||
$periods[$j] .= '_MORE_THAN_TWO';
|
||||
}
|
||||
@@ -366,14 +401,25 @@ class TwigExtension extends \Twig_Extension
|
||||
return "$difference $periods[$j] {$tense}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function absoluteUrlFilter($string)
|
||||
{
|
||||
$url = $this->grav['uri']->base();
|
||||
$string = preg_replace('/((?:href|src) *= *[\'"](?!(http|ftp)))/i', "$1$url", $string);
|
||||
|
||||
return $string;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public function markdownFilter($string)
|
||||
{
|
||||
$page = $this->grav['page'];
|
||||
@@ -391,16 +437,34 @@ class TwigExtension extends \Twig_Extension
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $haystack
|
||||
* @param $needle
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function startsWithFilter($haystack, $needle)
|
||||
{
|
||||
return Utils::startsWith($haystack, $needle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $haystack
|
||||
* @param $needle
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function endsWithFilter($haystack, $needle)
|
||||
{
|
||||
return Utils::endsWith($haystack, $needle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param null $default
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function definedDefaultFilter($value, $default = null)
|
||||
{
|
||||
if (isset($value)) {
|
||||
@@ -410,21 +474,43 @@ class TwigExtension extends \Twig_Extension
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param null $chars
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function rtrimFilter($value, $chars = null)
|
||||
{
|
||||
return rtrim($value, $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param null $chars
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function ltrimFilter($value, $chars = null)
|
||||
{
|
||||
return ltrim($value, $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function translate()
|
||||
{
|
||||
return $this->grav['language']->translate(func_get_args());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @param $index
|
||||
* @param null $lang
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function translateArray($key, $index, $lang = null)
|
||||
{
|
||||
return $this->grav['language']->translateArray($key, $index, $lang);
|
||||
@@ -435,6 +521,7 @@ class TwigExtension extends \Twig_Extension
|
||||
*
|
||||
* @param string $input
|
||||
* @param int $multiplier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function repeatFunc($input, $multiplier)
|
||||
@@ -447,24 +534,30 @@ class TwigExtension extends \Twig_Extension
|
||||
*
|
||||
* @example {{ url('theme://images/logo.png')|default('http://www.placehold.it/150x100/f4f4f4') }}
|
||||
*
|
||||
* @param string $input Resource to be located.
|
||||
* @param bool $domain True to include domain name.
|
||||
* @param string $input Resource to be located.
|
||||
* @param bool $domain True to include domain name.
|
||||
*
|
||||
* @return string|null Returns url to the resource or null if resource was not found.
|
||||
*/
|
||||
public function urlFunc($input, $domain = false)
|
||||
{
|
||||
if (!trim((string) $input)) {
|
||||
if (!trim((string)$input)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos((string) $input, '://')) {
|
||||
if ($this->grav['config']->get('system.absolute_urls', false)) {
|
||||
$domain = true;
|
||||
}
|
||||
|
||||
|
||||
if (strpos((string)$input, '://')) {
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
|
||||
// Get relative path to the resource (or false if not found).
|
||||
$resource = $locator->findResource((string) $input, false);
|
||||
$resource = $locator->findResource((string)$input, false);
|
||||
} else {
|
||||
$resource = (string) $input;
|
||||
$resource = (string)$input;
|
||||
}
|
||||
|
||||
/** @var Uri $uri */
|
||||
@@ -478,7 +571,8 @@ class TwigExtension extends \Twig_Extension
|
||||
*
|
||||
* @example {{ evaluate('grav.language.getLanguage') }}
|
||||
*
|
||||
* @param string $input String to be evaluated
|
||||
* @param string $input String to be evaluated
|
||||
*
|
||||
* @return string Returns the evaluated string
|
||||
*/
|
||||
public function evaluateFunc($input)
|
||||
@@ -491,7 +585,7 @@ class TwigExtension extends \Twig_Extension
|
||||
* (c) 2011 Fabien Potencier
|
||||
*
|
||||
* @param \Twig_Environment $env
|
||||
* @param $context
|
||||
* @param $context
|
||||
*/
|
||||
public function dump(\Twig_Environment $env, $context)
|
||||
{
|
||||
@@ -525,11 +619,12 @@ class TwigExtension extends \Twig_Extension
|
||||
* Output a Gist
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function gistFunc($id)
|
||||
{
|
||||
return '<script src="https://gist.github.com/'.$id.'.js"></script>';
|
||||
return '<script src="https://gist.github.com/' . $id . '.js"></script>';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -556,7 +651,7 @@ class TwigExtension extends \Twig_Extension
|
||||
*/
|
||||
public static function padFilter($input, $pad_length, $pad_string = " ", $pad_type = STR_PAD_RIGHT)
|
||||
{
|
||||
return str_pad($input, (int) $pad_length, $pad_string, $pad_type);
|
||||
return str_pad($input, (int)$pad_length, $pad_string, $pad_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -569,7 +664,7 @@ class TwigExtension extends \Twig_Extension
|
||||
*/
|
||||
public function arrayFunc($value)
|
||||
{
|
||||
return (array) $value;
|
||||
return (array)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -625,18 +720,17 @@ class TwigExtension extends \Twig_Extension
|
||||
/**
|
||||
* Used to add a nonce to a form. Call {{ nonce_field('action') }} specifying a string representing the action.
|
||||
*
|
||||
* For maximum protection, ensure that the string representing the action is as specific as possible.
|
||||
* For maximum protection, ensure that the string representing the action is as specific as possible
|
||||
*
|
||||
* @todo evaluate if adding referrer or not
|
||||
*
|
||||
* @param string action the action
|
||||
* @param string nonceParamName a custom nonce param name
|
||||
* @param string $action the action
|
||||
* @param string $nonceParamName a custom nonce param name
|
||||
*
|
||||
* @return string the nonce input field
|
||||
*/
|
||||
public function nonceFieldFunc($action, $nonceParamName = 'nonce')
|
||||
{
|
||||
$string = '<input type="hidden" id="' . $nonceParamName . '" name="' . $nonceParamName . '" value="' . Utils::getNonce($action) .'" />';
|
||||
$string = '<input type="hidden" id="' . $nonceParamName . '" name="' . $nonceParamName . '" value="' . Utils::getNonce($action) . '" />';
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ trait WriteCacheFileTrait
|
||||
use GravTrait;
|
||||
|
||||
protected static $umask;
|
||||
|
||||
/**
|
||||
* This exists so template cache files use the same
|
||||
* group between apache and cli
|
||||
|
||||
@@ -6,7 +6,7 @@ use Grav\Common\Page\Page;
|
||||
/**
|
||||
* The URI object provides information about the current URL
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Uri
|
||||
@@ -15,68 +15,236 @@ class Uri
|
||||
|
||||
public $url;
|
||||
|
||||
protected $basename;
|
||||
protected $base;
|
||||
protected $root;
|
||||
protected $basename;
|
||||
protected $bits;
|
||||
protected $content_path;
|
||||
protected $extension;
|
||||
protected $host;
|
||||
protected $content_path;
|
||||
protected $env;
|
||||
protected $params;
|
||||
protected $path;
|
||||
protected $paths;
|
||||
protected $scheme;
|
||||
protected $port;
|
||||
protected $query;
|
||||
protected $params;
|
||||
protected $root;
|
||||
protected $root_path;
|
||||
protected $uri;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$name = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
|
||||
// Remove port from HTTP_HOST generated $name
|
||||
$name = Utils::substrToString($name, ':');
|
||||
// resets
|
||||
$this->paths = [];
|
||||
$this->params = [];
|
||||
$this->query = [];
|
||||
$this->name = $this->buildHostname();
|
||||
$this->env = $this->buildEnvironment();
|
||||
$this->port = $this->buildPort();
|
||||
$this->uri = $this->buildUri();
|
||||
$this->scheme = $this->buildScheme();
|
||||
$this->base = $this->buildBaseUrl();
|
||||
$this->host = $this->buildHost();
|
||||
$this->root_path = $this->buildRootPath();
|
||||
$this->root = $this->base . $this->root_path;
|
||||
$this->url = $this->base . $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the hostname from $_SERVER, validated and without port
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildHostname()
|
||||
{
|
||||
$hostname = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
|
||||
|
||||
// Remove port from HTTP_HOST generated $hostname
|
||||
$hostname = Utils::substrToString($hostname, ':');
|
||||
|
||||
// Validate the hostname
|
||||
$name = preg_match(Uri::HOSTNAME_REGEX, $name) ? $name : 'unknown';
|
||||
$hostname = $this->validateHostname($hostname) ? $hostname : 'unknown';
|
||||
|
||||
$port = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80;
|
||||
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
||||
return $hostname;
|
||||
}
|
||||
|
||||
$root_path = str_replace(' ', '%20', rtrim(substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php')), '/'));
|
||||
/**
|
||||
* Validate a hostname
|
||||
*
|
||||
* @param string $hostname The hostname
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function validateHostname($hostname)
|
||||
{
|
||||
return (bool)preg_match(Uri::HOSTNAME_REGEX, $hostname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the port from $_SERVER
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildPort()
|
||||
{
|
||||
$port = isset($_SERVER['SERVER_PORT']) ? (string)$_SERVER['SERVER_PORT'] : '80';
|
||||
|
||||
return $port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Uri from $_SERVER
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildUri()
|
||||
{
|
||||
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
private function buildScheme()
|
||||
{
|
||||
// set the base
|
||||
if (isset($_SERVER['HTTPS'])) {
|
||||
$base = (strtolower(@$_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
|
||||
$scheme = (strtolower(@$_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
|
||||
} else {
|
||||
$base = 'http://';
|
||||
$scheme = 'http://';
|
||||
}
|
||||
|
||||
// add the sever name
|
||||
$base .= $name;
|
||||
return $scheme;
|
||||
}
|
||||
|
||||
// add the port of needed
|
||||
if ($port != '80' && $port != '443') {
|
||||
$base .= ":".$port;
|
||||
}
|
||||
/**
|
||||
* Get the base URI with port if needed
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildBaseUrl()
|
||||
{
|
||||
return $this->scheme . $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Grav Root Path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildRootPath()
|
||||
{
|
||||
$root_path = str_replace(' ', '%20', rtrim(substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php')), '/'));
|
||||
|
||||
// check if userdir in the path and workaround PHP bug with PHP_SELF
|
||||
if (strpos($uri, '/~') !== false && strpos($_SERVER['PHP_SELF'], '/~') === false) {
|
||||
$root_path = substr($uri, 0, strpos($uri, '/', 1)) . $root_path;
|
||||
if (strpos($this->uri, '/~') !== false && strpos($_SERVER['PHP_SELF'], '/~') === false) {
|
||||
$root_path = substr($this->uri, 0, strpos($this->uri, '/', 1)) . $root_path;
|
||||
}
|
||||
|
||||
return $root_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hostname
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function buildHost()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
private function buildEnvironment()
|
||||
{
|
||||
// set hostname
|
||||
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
|
||||
|
||||
// check for localhost variations
|
||||
if ($name == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
|
||||
$this->host = 'localhost';
|
||||
if ($this->name == 'localhost' || $address == '::1' || $address == '127.0.0.1') {
|
||||
$env = 'localhost';
|
||||
} else {
|
||||
$this->host = $name;
|
||||
$env = $this->name;
|
||||
}
|
||||
|
||||
$this->base = $base;
|
||||
$this->root = $base . $root_path;
|
||||
$this->url = $base . $uri;
|
||||
return $env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the URI class with a url passed via parameter.
|
||||
* Used for testing purposes.
|
||||
*
|
||||
* @param string $url the URL to use in the class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function initializeWithUrl($url = '')
|
||||
{
|
||||
if (!$url) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$this->paths = [];
|
||||
$this->params = [];
|
||||
$this->query = [];
|
||||
$this->name = [];
|
||||
$this->env = [];
|
||||
$this->port = [];
|
||||
$this->uri = [];
|
||||
$this->base = [];
|
||||
$this->host = [];
|
||||
$this->root = [];
|
||||
$this->url = [];
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
$language = $grav['language'];
|
||||
|
||||
$uri_bits = Uri::parseUrl($url);
|
||||
|
||||
$this->name = $uri_bits['host'];
|
||||
$this->port = isset($uri_bits['port']) ? $uri_bits['port'] : '80';
|
||||
|
||||
$this->uri = $uri_bits['path'];
|
||||
|
||||
// set active language
|
||||
$uri = $language->setActiveFromUri($this->uri);
|
||||
|
||||
if (isset($uri_bits['params'])) {
|
||||
$this->params = $uri_bits['params'];
|
||||
}
|
||||
|
||||
if (isset($uri_bits['query'])) {
|
||||
$this->uri .= '?' . $uri_bits['query'];
|
||||
parse_str($uri_bits['query'], $this->query);
|
||||
}
|
||||
|
||||
$this->base = $this->buildBaseUrl();
|
||||
$this->host = $this->buildHost();
|
||||
$this->env = $this->buildEnvironment();
|
||||
$this->root_path = $this->buildRootPath();
|
||||
$this->root = $this->base . $this->root_path;
|
||||
$this->url = $this->root . $uri;
|
||||
$this->path = $uri;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the URI class by providing url and root_path arguments
|
||||
*
|
||||
* @param string $url
|
||||
* @param string $root_path
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function initializeWithUrlAndRootPath($url, $root_path)
|
||||
{
|
||||
$this->initializeWithUrl($url);
|
||||
$this->root_path = $root_path;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,10 +257,14 @@ class Uri
|
||||
$config = $grav['config'];
|
||||
$language = $grav['language'];
|
||||
|
||||
// resets
|
||||
$this->paths = [];
|
||||
$this->params = [];
|
||||
$this->query = [];
|
||||
// add the port to the base for non-standard ports
|
||||
if ($config->get('system.reverse_proxy_setup') === false && $this->port != '80' && $this->port != '443') {
|
||||
$this->base .= ":" . $this->port;
|
||||
}
|
||||
|
||||
// Set some defaults
|
||||
$this->root = $this->base . $this->root_path;
|
||||
$this->url = $this->base . $this->uri;
|
||||
|
||||
// get any params and remove them
|
||||
$uri = str_replace($this->root, '', $this->url);
|
||||
@@ -122,7 +294,9 @@ class Uri
|
||||
|
||||
// process query string
|
||||
if (isset($bits['query']) && isset($bits['path'])) {
|
||||
$this->query = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
|
||||
if (!$this->query) {
|
||||
$this->query = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
|
||||
}
|
||||
$uri = $bits['path'];
|
||||
}
|
||||
|
||||
@@ -140,8 +314,8 @@ class Uri
|
||||
$valid_page_types = implode('|', $config->get('system.pages.types'));
|
||||
|
||||
// Strip the file extension for valid page types
|
||||
if (preg_match("/\.(".$valid_page_types.")$/", $parts['basename'])) {
|
||||
$uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS). '/' .$parts['filename'];
|
||||
if (preg_match("/\.(" . $valid_page_types . ")$/", $parts['basename'])) {
|
||||
$uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS) . '/' . $parts['filename'];
|
||||
}
|
||||
|
||||
// set the new url
|
||||
@@ -151,6 +325,11 @@ class Uri
|
||||
if ($this->content_path != '') {
|
||||
$this->paths = explode('/', $this->content_path);
|
||||
}
|
||||
|
||||
// Set some Grav stuff
|
||||
$grav['base_url_absolute'] = $this->rootUrl(true);
|
||||
$grav['base_url_relative'] = $this->rootUrl(false);
|
||||
$grav['base_url'] = $grav['config']->get('system.absolute_urls') ? $grav['base_url_absolute'] : $grav['base_url_relative'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,7 +344,7 @@ class Uri
|
||||
{
|
||||
if (strpos($uri, $delimiter) !== false) {
|
||||
$bits = explode('/', $uri);
|
||||
$path = array();
|
||||
$path = [];
|
||||
foreach ($bits as $bit) {
|
||||
if (strpos($bit, $delimiter) !== false) {
|
||||
$param = explode($delimiter, $bit);
|
||||
@@ -179,13 +358,15 @@ class Uri
|
||||
}
|
||||
$uri = '/' . ltrim(implode('/', $path), '/');
|
||||
}
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return URI path.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function paths($id = null)
|
||||
@@ -200,8 +381,9 @@ class Uri
|
||||
/**
|
||||
* Return route to the current URI. By default route doesn't include base path.
|
||||
*
|
||||
* @param bool $absolute True to include full path.
|
||||
* @param bool $domain True to include domain. Works only if first parameter is also true.
|
||||
* @param bool $absolute True to include full path.
|
||||
* @param bool $domain True to include domain. Works only if first parameter is also true.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function route($absolute = false, $domain = false)
|
||||
@@ -212,8 +394,10 @@ class Uri
|
||||
/**
|
||||
* Return full query string or a single query attribute.
|
||||
*
|
||||
* @param string $id Optional attribute.
|
||||
* @return string
|
||||
* @param string $id Optional attribute. Get a single query attribute if set
|
||||
* @param bool $raw If true and $id is not set, return the full query array. Otherwise return the query string
|
||||
*
|
||||
* @return string|array Returns an array if $id = null and $raw = true
|
||||
*/
|
||||
public function query($id = null, $raw = false)
|
||||
{
|
||||
@@ -223,6 +407,10 @@ class Uri
|
||||
if ($raw) {
|
||||
return $this->query;
|
||||
} else {
|
||||
if (!$this->query) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return http_build_query($this->query);
|
||||
}
|
||||
}
|
||||
@@ -231,8 +419,9 @@ class Uri
|
||||
/**
|
||||
* Return all or a single query parameter as a URI compatible string.
|
||||
*
|
||||
* @param string $id Optional parameter name.
|
||||
* @param string $id Optional parameter name.
|
||||
* @param boolean $array return the array format or not
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function params($id = null, $array = false)
|
||||
@@ -244,16 +433,16 @@ class Uri
|
||||
if ($array) {
|
||||
return $this->params;
|
||||
}
|
||||
$output = array();
|
||||
$output = [];
|
||||
foreach ($this->params as $key => $value) {
|
||||
$output[] = $key . $config->get('system.param_sep') . $value;
|
||||
$params = '/'.implode('/', $output);
|
||||
$params = '/' . implode('/', $output);
|
||||
}
|
||||
} elseif (isset($this->params[$id])) {
|
||||
if ($array) {
|
||||
return $this->params[$id];
|
||||
}
|
||||
$params = "/{$id}". $config->get('system.param_sep') . $this->params[$id];
|
||||
$params = "/{$id}" . $config->get('system.param_sep') . $this->params[$id];
|
||||
}
|
||||
|
||||
return $params;
|
||||
@@ -262,7 +451,8 @@ class Uri
|
||||
/**
|
||||
* Get URI parameter.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function param($id)
|
||||
@@ -277,7 +467,8 @@ class Uri
|
||||
/**
|
||||
* Return URL.
|
||||
*
|
||||
* @param bool $include_host Include hostname.
|
||||
* @param bool $include_host Include hostname.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function url($include_host = false)
|
||||
@@ -286,6 +477,7 @@ class Uri
|
||||
return $this->url;
|
||||
} else {
|
||||
$url = (str_replace($this->base, '', rtrim($this->url, '/')));
|
||||
|
||||
return $url ? $url : '/';
|
||||
}
|
||||
}
|
||||
@@ -301,6 +493,7 @@ class Uri
|
||||
if ($path === '') {
|
||||
$path = '/';
|
||||
}
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
@@ -316,9 +509,21 @@ class Uri
|
||||
if (!$this->extension) {
|
||||
$this->extension = $default;
|
||||
}
|
||||
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scheme of the URI
|
||||
*
|
||||
* @return String The scheme of the URI
|
||||
*/
|
||||
public function scheme()
|
||||
{
|
||||
return $this->scheme;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the host of the URI
|
||||
*
|
||||
@@ -329,6 +534,16 @@ class Uri
|
||||
return $this->host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the port number
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function port()
|
||||
{
|
||||
return $this->port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the environment name
|
||||
*
|
||||
@@ -336,7 +551,7 @@ class Uri
|
||||
*/
|
||||
public function environment()
|
||||
{
|
||||
return $this->host();
|
||||
return $this->env;
|
||||
}
|
||||
|
||||
|
||||
@@ -363,7 +578,8 @@ class Uri
|
||||
/**
|
||||
* Return root URL to the site.
|
||||
*
|
||||
* @param bool $include_host Include hostname.
|
||||
* @param bool $include_host Include hostname.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rootUrl($include_host = false)
|
||||
@@ -372,6 +588,7 @@ class Uri
|
||||
return $this->root;
|
||||
} else {
|
||||
$root = str_replace($this->base, '', $this->root);
|
||||
|
||||
return $root;
|
||||
}
|
||||
}
|
||||
@@ -395,6 +612,7 @@ class Uri
|
||||
*
|
||||
* @param string $default
|
||||
* @param string $attributes
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function referrer($default = null, $attributes = null)
|
||||
@@ -450,7 +668,8 @@ class Uri
|
||||
/**
|
||||
* Is this an external URL? if it starts with `http` then yes, else false
|
||||
*
|
||||
* @param string $url the URL in question
|
||||
* @param string $url the URL in question
|
||||
*
|
||||
* @return boolean is eternal state
|
||||
*/
|
||||
public function isExternal($url)
|
||||
@@ -466,6 +685,7 @@ class Uri
|
||||
* The opposite of built-in PHP method parse_url()
|
||||
*
|
||||
* @param $parsed_url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function buildUrl($parsed_url)
|
||||
@@ -477,26 +697,241 @@ class Uri
|
||||
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
|
||||
$params = isset($parsed_url['params']) ? static::buildParams($parsed_url['params']) : '';
|
||||
$query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
|
||||
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
|
||||
return "$scheme$user$pass$host$port$path$query$fragment";
|
||||
|
||||
return "$scheme$user$pass$host$port$path$params$query$fragment";
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts links from absolute '/' or relative (../..) to a grav friendly format
|
||||
*
|
||||
* @param Page|the $page the current page to use as reference
|
||||
* @param string $markdown_url the URL as it was written in the markdown
|
||||
* @param string $type the type of URL, image | link
|
||||
* @param null $relative if null, will use system default, if true will use relative links internally
|
||||
*
|
||||
* @return string the more friendly formatted url
|
||||
*/
|
||||
public static function convertUrl(Page $page, $markdown_url, $type = 'link', $relative = null)
|
||||
public static function buildParams($params)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
$params_string = '';
|
||||
foreach ($params as $key => $value) {
|
||||
$output[] = $key . $grav['config']->get('system.param_sep') . $value;
|
||||
$params_string .= '/' . implode('/', $output);
|
||||
}
|
||||
return $params_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts links from absolute '/' or relative (../..) to a Grav friendly format
|
||||
*
|
||||
* @param Page $page the current page to use as reference
|
||||
* @param string $url the URL as it was written in the markdown
|
||||
* @param string $type the type of URL, image | link
|
||||
* @param null $absolute if null, will use system default, if true will use absolute links internally
|
||||
*
|
||||
* @return string the more friendly formatted url
|
||||
*/
|
||||
public static function convertUrl(Page $page, $url, $type = 'link', $absolute = false)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
$uri = $grav['uri'];
|
||||
|
||||
// Link processing should prepend language
|
||||
$language = $grav['language'];
|
||||
$language_append = '';
|
||||
if ($type == 'link' && $language->enabled()) {
|
||||
$language_append = $language->getLanguageURLPrefix();
|
||||
}
|
||||
|
||||
// Handle Excerpt style $url array
|
||||
if (is_array($url)) {
|
||||
$url_path = $url['path'];
|
||||
} else {
|
||||
$url_path = $url;
|
||||
}
|
||||
|
||||
$external = false;
|
||||
$base = $grav['base_url_relative'];
|
||||
$base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append;
|
||||
$pages_dir = $grav['locator']->findResource('page://');
|
||||
|
||||
// if absolute and starts with a base_url move on
|
||||
if (isset($url['scheme']) && Utils::startsWith($url['scheme'], 'http')) {
|
||||
$external = true;
|
||||
} elseif (($base_url != '' && Utils::startsWith($url_path, $base_url)) ||
|
||||
$url_path == '/' ||
|
||||
Utils::startsWith($url_path, '#')) {
|
||||
$url_path = $base_url . $url_path;
|
||||
} else {
|
||||
|
||||
// see if page is relative to this or absolute
|
||||
if (Utils::startsWith($url_path, '/')) {
|
||||
$normalized_url = Utils::normalizePath($base_url . $url_path);
|
||||
$normalized_path = Utils::normalizePath($pages_dir . $url_path);
|
||||
} else {
|
||||
$page_route = ($page->home() && !empty($url_path)) ? $page->rawRoute() : $page->route();
|
||||
$normalized_url = $base_url . Utils::normalizePath($page_route . '/' . $url_path);
|
||||
$normalized_path = Utils::normalizePath($page->path() . '/' . $url_path);
|
||||
}
|
||||
|
||||
// special check to see if path checking is required.
|
||||
$just_path = str_replace($normalized_url, '', $normalized_path);
|
||||
if ($just_path == $page->path() || $normalized_url == '/') {
|
||||
$url_path = $normalized_url;
|
||||
} else {
|
||||
$url_bits = static::parseUrl($normalized_path);
|
||||
$full_path = ($url_bits['path']);
|
||||
$raw_full_path = rawurldecode($full_path);
|
||||
|
||||
if (file_exists($raw_full_path)) {
|
||||
$full_path = $raw_full_path;
|
||||
} elseif (file_exists($full_path)) {
|
||||
// do nothing
|
||||
} else {
|
||||
$full_path = false;
|
||||
}
|
||||
|
||||
if ($full_path) {
|
||||
$path_info = pathinfo($full_path);
|
||||
$page_path = $path_info['dirname'];
|
||||
$filename = '';
|
||||
|
||||
if ($url_path == '..') {
|
||||
$page_path = $full_path;
|
||||
} else {
|
||||
// save the filename if a file is part of the path
|
||||
if (is_file($full_path)) {
|
||||
if ($path_info['extension'] != 'md') {
|
||||
$filename = '/' . $path_info['basename'];
|
||||
}
|
||||
} else {
|
||||
$page_path = $full_path;
|
||||
}
|
||||
}
|
||||
|
||||
// get page instances and try to find one that fits
|
||||
$instances = $grav['pages']->instances();
|
||||
if (isset($instances[$page_path])) {
|
||||
/** @var Page $target */
|
||||
$target = $instances[$page_path];
|
||||
$url_bits['path'] = $base_url . rtrim($target->route(), '/') . $filename;
|
||||
|
||||
$url_path = Uri::buildUrl($url_bits);
|
||||
} else {
|
||||
$url_path = $normalized_url;
|
||||
}
|
||||
} else {
|
||||
$url_path = $normalized_url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// handle absolute URLs
|
||||
if (!$external && ($absolute === true || $grav['config']->get('system.absolute_urls', false))) {
|
||||
|
||||
$url['scheme'] = str_replace('://', '', $uri->scheme());
|
||||
$url['host'] = $uri->host();
|
||||
|
||||
if ($uri->port() != 80 && $uri->port() != 443) {
|
||||
$url['port'] = $uri->port();
|
||||
}
|
||||
|
||||
// check if page exists for this route, and if so, check if it has SSL enabled
|
||||
$pages = $grav['pages'];
|
||||
$routes = $pages->routes();
|
||||
|
||||
// if this is an image, get the proper path
|
||||
$url_bits = pathinfo($url_path);
|
||||
if (isset($url_bits['extension'])) {
|
||||
$target_path = $url_bits['dirname'];
|
||||
} else {
|
||||
$target_path = $url_path;
|
||||
}
|
||||
|
||||
// strip base from this path
|
||||
$target_path = str_replace($uri->rootUrl(), '', $target_path);
|
||||
|
||||
// set to / if root
|
||||
if (empty($target_path)) {
|
||||
$target_path = '/';
|
||||
}
|
||||
|
||||
// look to see if this page exists and has ssl enabled
|
||||
if (isset($routes[$target_path])) {
|
||||
$target_page = $pages->get($routes[$target_path]);
|
||||
if ($target_page) {
|
||||
$ssl_enabled = $target_page->ssl();
|
||||
if (isset($ssl_enabled)) {
|
||||
if ($ssl_enabled) {
|
||||
$url['scheme'] = 'https';
|
||||
} else {
|
||||
$url['scheme'] = 'http';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// transform back to string/array as needed
|
||||
if (is_array($url)) {
|
||||
$url['path'] = $url_path;
|
||||
} else {
|
||||
$url = $url_path;
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public static function parseUrl($url)
|
||||
{
|
||||
$bits = parse_url($url);
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
list($stripped_path, $params) = static::extractParams($bits['path'], $grav['config']->get('system.param_sep'));
|
||||
|
||||
if (!empty($params)) {
|
||||
$bits['path'] = $stripped_path;
|
||||
$bits['params'] = $params;
|
||||
}
|
||||
|
||||
return $bits;
|
||||
}
|
||||
|
||||
public static function extractParams($uri, $delimiter)
|
||||
{
|
||||
$params = [];
|
||||
|
||||
if (strpos($uri, $delimiter) !== false) {
|
||||
$bits = explode('/', $uri);
|
||||
$path = [];
|
||||
foreach ($bits as $bit) {
|
||||
if (strpos($bit, $delimiter) !== false) {
|
||||
$param = explode($delimiter, $bit);
|
||||
if (count($param) == 2) {
|
||||
$plain_var = filter_var(rawurldecode($param[1]), FILTER_SANITIZE_STRING);
|
||||
$params[$param[0]] = $plain_var;
|
||||
}
|
||||
} else {
|
||||
$path[] = $bit;
|
||||
}
|
||||
}
|
||||
$uri = '/' . ltrim(implode('/', $path), '/');
|
||||
}
|
||||
|
||||
return [$uri, $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts links from absolute '/' or relative (../..) to a Grav friendly format
|
||||
*
|
||||
* @param Page $page the current page to use as reference
|
||||
* @param string $markdown_url the URL as it was written in the markdown
|
||||
* @param string $type the type of URL, image | link
|
||||
* @param null $relative if null, will use system default, if true will use relative links internally
|
||||
*
|
||||
* @return string the more friendly formatted url
|
||||
*/
|
||||
public static function convertUrlOld(Page $page, $markdown_url, $type = 'link', $relative = null)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Grav\Common\Language\Language $language */
|
||||
$language = $grav['language'];
|
||||
|
||||
// Link processing should prepend language
|
||||
@@ -509,7 +944,7 @@ class Uri
|
||||
if (is_null($relative)) {
|
||||
$base = $grav['base_url'];
|
||||
} else {
|
||||
$base = $relative ? $grav['base_url_relative'] : $grav['base_url_absolute'];
|
||||
$base = $relative ? $grav['base_url_relative'] : $grav['base_url_absolute'];
|
||||
}
|
||||
|
||||
$base_url = rtrim($base . $grav['pages']->base(), '/') . $language_append;
|
||||
@@ -555,7 +990,6 @@ class Uri
|
||||
$page_path = $path_info['dirname'];
|
||||
$filename = '';
|
||||
|
||||
|
||||
if ($markdown_url == '..') {
|
||||
$page_path = $full_path;
|
||||
} else {
|
||||
@@ -572,8 +1006,10 @@ class Uri
|
||||
// get page instances and try to find one that fits
|
||||
$instances = $grav['pages']->instances();
|
||||
if (isset($instances[$page_path])) {
|
||||
/** @var Page $target */
|
||||
$target = $instances[$page_path];
|
||||
$url_bits['path'] = $base_url . rtrim($target->route(), '/') . $filename;
|
||||
|
||||
return Uri::buildUrl($url_bits);
|
||||
}
|
||||
|
||||
@@ -584,8 +1020,8 @@ class Uri
|
||||
/**
|
||||
* Adds the nonce to a URL for a specific action
|
||||
*
|
||||
* @param string $url the url
|
||||
* @param string $action the action
|
||||
* @param string $url the url
|
||||
* @param string $action the action
|
||||
* @param string $nonceParamName the param name to use
|
||||
*
|
||||
* @return string the url with the nonce
|
||||
@@ -593,7 +1029,7 @@ class Uri
|
||||
public static function addNonce($url, $action, $nonceParamName = 'nonce')
|
||||
{
|
||||
$urlWithNonce = $url . '/' . $nonceParamName . Grav::instance()['config']->get('system.param_sep', ':') . Utils::getNonce($action);
|
||||
|
||||
return $urlWithNonce;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace Grav\Common\User;
|
||||
/**
|
||||
* User authentication
|
||||
*
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
abstract class Authentication
|
||||
@@ -12,7 +12,8 @@ abstract class Authentication
|
||||
/**
|
||||
* Create password hash from plaintext password.
|
||||
*
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $password Plaintext password.
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return string|bool
|
||||
*/
|
||||
@@ -34,8 +35,9 @@ abstract class Authentication
|
||||
/**
|
||||
* Verifies that a password matches a hash.
|
||||
*
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $hash Hash to verify against.
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $hash Hash to verify against.
|
||||
*
|
||||
* @return int Returns 0 if the check fails, 1 if password matches, 2 if hash needs to be updated.
|
||||
*/
|
||||
public static function verify($password, $hash)
|
||||
|
||||
@@ -10,10 +10,7 @@ use Grav\Common\Utils;
|
||||
/**
|
||||
* Group object
|
||||
*
|
||||
* @property mixed authenticated
|
||||
* @property mixed password
|
||||
* @property bool|string hashed_password
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class Group extends Data
|
||||
@@ -28,15 +25,18 @@ class Group extends Data
|
||||
private static function groups()
|
||||
{
|
||||
$groups = self::getGrav()['config']->get('groups');
|
||||
|
||||
return $groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a group exists
|
||||
*
|
||||
* @param string $groupname
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function group_exists($groupname)
|
||||
public static function groupExists($groupname)
|
||||
{
|
||||
return isset(self::groups()[$groupname]);
|
||||
}
|
||||
@@ -44,11 +44,13 @@ class Group extends Data
|
||||
/**
|
||||
* Get a group by name
|
||||
*
|
||||
* @param string $groupname
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
public static function load($groupname)
|
||||
{
|
||||
if (self::group_exists($groupname)) {
|
||||
if (self::groupExists($groupname)) {
|
||||
$content = self::groups()[$groupname];
|
||||
} else {
|
||||
$content = [];
|
||||
@@ -76,7 +78,7 @@ class Group extends Data
|
||||
|
||||
self::getGrav()['config']->set("groups.$this->groupname", []);
|
||||
|
||||
foreach($fields as $field) {
|
||||
foreach ($fields as $field) {
|
||||
if ($field['type'] == 'text') {
|
||||
$value = $field['name'];
|
||||
if (isset($this->items[$value])) {
|
||||
@@ -87,8 +89,10 @@ class Group extends Data
|
||||
$value = $field['name'];
|
||||
$arrayValues = Utils::resolve($this->items, $field['name']);
|
||||
|
||||
if ($arrayValues) foreach($arrayValues as $arrayIndex => $arrayValue) {
|
||||
self::getGrav()['config']->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue);
|
||||
if ($arrayValues) {
|
||||
foreach ($arrayValues as $arrayIndex => $arrayValue) {
|
||||
self::getGrav()['config']->set("groups.$this->groupname.$value.$arrayIndex", $arrayValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -104,7 +108,8 @@ class Group extends Data
|
||||
/**
|
||||
* Remove a group
|
||||
*
|
||||
* @param string $username
|
||||
* @param string $groupname
|
||||
*
|
||||
* @return bool True if the action was performed
|
||||
*/
|
||||
public static function remove($groupname)
|
||||
|
||||
@@ -10,10 +10,10 @@ use Grav\Common\Utils;
|
||||
/**
|
||||
* User object
|
||||
*
|
||||
* @property mixed authenticated
|
||||
* @property mixed password
|
||||
* @property mixed authenticated
|
||||
* @property mixed password
|
||||
* @property bool|string hashed_password
|
||||
* @author RocketTheme
|
||||
* @author RocketTheme
|
||||
* @license MIT
|
||||
*/
|
||||
class User extends Data
|
||||
@@ -26,6 +26,7 @@ class User extends Data
|
||||
* Always creates user object. To check if user exists, use $this->exists().
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return User
|
||||
*/
|
||||
public static function load($username)
|
||||
@@ -56,6 +57,7 @@ class User extends Data
|
||||
* Remove user account.
|
||||
*
|
||||
* @param string $username
|
||||
*
|
||||
* @return bool True if the action was performed
|
||||
*/
|
||||
public static function remove($username)
|
||||
@@ -73,7 +75,8 @@ class User extends Data
|
||||
*
|
||||
* If user password needs to be updated, new information will be saved.
|
||||
*
|
||||
* @param string $password Plaintext password.
|
||||
* @param string $password Plaintext password.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authenticate($password)
|
||||
@@ -88,8 +91,9 @@ class User extends Data
|
||||
// the result
|
||||
Authentication::verify(
|
||||
$password,
|
||||
self::getGrav()['config']->get('system.security.default_hash', '$2y$10$kwsyMVwM8/7j0K/6LHT.g.Fs49xOCTp2b8hh/S5.dPJuJcJB6T.UK')
|
||||
self::getGrav()['config']->get('system.security.default_hash')
|
||||
);
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Plain-text does match, we can update the hash and proceed
|
||||
@@ -113,7 +117,7 @@ class User extends Data
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
return (bool)$result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +143,8 @@ class User extends Data
|
||||
/**
|
||||
* Checks user authorization to the action.
|
||||
*
|
||||
* @param string $action
|
||||
* @param string $action
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize($action)
|
||||
@@ -156,21 +161,22 @@ class User extends Data
|
||||
|
||||
//Check group access level
|
||||
$groups = $this->get('groups');
|
||||
if ($groups) foreach($groups as $group) {
|
||||
$permission = self::getGrav()['config']->get("groups.{$group}.access.{$action}");
|
||||
if (Utils::isPositive($permission)) {
|
||||
$return = true;
|
||||
if ($groups) {
|
||||
foreach ((array)$groups as $group) {
|
||||
$permission = self::getGrav()['config']->get("groups.{$group}.access.{$action}");
|
||||
$return = Utils::isPositive($permission);
|
||||
if ($return === true) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Check user access level
|
||||
if (!$this->get('access')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Utils::resolve($this->get('access'), $action) !== null) {
|
||||
$permission = $this->get("access.{$action}");
|
||||
$return = Utils::isPositive($permission);
|
||||
if ($this->get('access')) {
|
||||
if (Utils::resolve($this->get('access'), $action) !== null) {
|
||||
$permission = $this->get("access.{$action}");
|
||||
$return = Utils::isPositive($permission);
|
||||
}
|
||||
}
|
||||
|
||||
return $return;
|
||||
@@ -181,6 +187,7 @@ class User extends Data
|
||||
* Ensures backwards compatibility
|
||||
*
|
||||
* @param string $action
|
||||
*
|
||||
* @deprecated use authorize()
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -18,6 +18,8 @@ abstract class Utils
|
||||
protected static $nonces = [];
|
||||
|
||||
/**
|
||||
* Check if the $haystack string starts with the substring $needle
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $needle
|
||||
*
|
||||
@@ -41,6 +43,8 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the $haystack string ends with the substring $needle
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $needle
|
||||
*
|
||||
@@ -64,6 +68,8 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the $haystack string contains the substring $needle
|
||||
*
|
||||
* @param string $haystack
|
||||
* @param string $needle
|
||||
*
|
||||
@@ -79,13 +85,15 @@ abstract class Utils
|
||||
*
|
||||
* @param $haystack
|
||||
* @param $needle
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function substrToString($haystack, $needle)
|
||||
{
|
||||
if (static::contains($haystack, $needle)) {
|
||||
return substr($haystack, 0, strpos($haystack,$needle));
|
||||
return substr($haystack, 0, strpos($haystack, $needle));
|
||||
}
|
||||
|
||||
return $haystack;
|
||||
}
|
||||
|
||||
@@ -103,6 +111,8 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Grav date formats allowed
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function dateFormats()
|
||||
@@ -120,6 +130,7 @@ abstract class Utils
|
||||
if ($default_format) {
|
||||
$date_formats = array_merge([$default_format => $default_format.' (e.g. '.$now->format($default_format).')'], $date_formats);
|
||||
}
|
||||
|
||||
return $date_formats;
|
||||
}
|
||||
|
||||
@@ -127,10 +138,11 @@ abstract class Utils
|
||||
* Truncate text by number of characters but can cut off words.
|
||||
*
|
||||
* @param string $string
|
||||
* @param int $limit Max number of characters.
|
||||
* @param bool $up_to_break truncate up to breakpoint after char count
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
* @param int $limit Max number of characters.
|
||||
* @param bool $up_to_break truncate up to breakpoint after char count
|
||||
* @param string $break Break point.
|
||||
* @param string $pad Appended padding to the end of the string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function truncate($string, $limit = 150, $up_to_break = false, $break = " ", $pad = "…")
|
||||
@@ -155,8 +167,9 @@ abstract class Utils
|
||||
/**
|
||||
* Truncate text by number of characters in a "word-safe" manor.
|
||||
*
|
||||
* @param $string
|
||||
* @param int $limit
|
||||
* @param string $string
|
||||
* @param int $limit
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function safeTruncate($string, $limit = 150)
|
||||
@@ -175,7 +188,7 @@ abstract class Utils
|
||||
*/
|
||||
public static function truncateHtml($text, $length = 100)
|
||||
{
|
||||
return Truncator::truncate($text, $length, array('length_in_chars' => true));
|
||||
return Truncator::truncate($text, $length, ['length_in_chars' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +201,7 @@ abstract class Utils
|
||||
*/
|
||||
public static function safeTruncateHtml($text, $length = 100)
|
||||
{
|
||||
return Truncator::truncate($text, $length, array('length_in_chars' => true, 'word_safe' => true));
|
||||
return Truncator::truncate($text, $length, ['length_in_chars' => true, 'word_safe' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -206,8 +219,8 @@ abstract class Utils
|
||||
/**
|
||||
* Provides the ability to download a file to the browser
|
||||
*
|
||||
* @param $file the full path to the file to be downloaded
|
||||
* @param bool $force_download as opposed to letting browser choose if to download or render
|
||||
* @param string $file the full path to the file to be downloaded
|
||||
* @param bool $force_download as opposed to letting browser choose if to download or render
|
||||
*/
|
||||
public static function download($file, $force_download = true)
|
||||
{
|
||||
@@ -223,7 +236,8 @@ abstract class Utils
|
||||
if (!Utils::isFunctionDisabled('set_time_limit') && !ini_get('safe_mode') && function_exists('set_time_limit')) {
|
||||
set_time_limit(0);
|
||||
}
|
||||
} catch (\Exception $e) {}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
ignore_user_abort(false);
|
||||
|
||||
@@ -264,7 +278,7 @@ abstract class Utils
|
||||
/**
|
||||
* Return the mimetype based on filename
|
||||
*
|
||||
* @param $extension Extension of file (eg .txt)
|
||||
* @param string $extension Extension of file (eg "txt")
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -283,7 +297,7 @@ abstract class Utils
|
||||
/**
|
||||
* Normalize path by processing relative `.` and `..` syntax and merging path
|
||||
*
|
||||
* @param $path
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -292,7 +306,7 @@ abstract class Utils
|
||||
$root = ($path[0] === '/') ? '/' : '';
|
||||
|
||||
$segments = explode('/', trim($path, '/'));
|
||||
$ret = array();
|
||||
$ret = [];
|
||||
foreach ($segments as $segment) {
|
||||
if (($segment == '.') || empty($segment)) {
|
||||
continue;
|
||||
@@ -308,7 +322,9 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $function
|
||||
* Check whether a function is disabled in the PHP settings
|
||||
*
|
||||
* @param string $function the name of the function to check
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -318,6 +334,8 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the formatted timezones list
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function timezones()
|
||||
@@ -333,7 +351,7 @@ abstract class Utils
|
||||
|
||||
asort($offsets);
|
||||
|
||||
$timezone_list = array();
|
||||
$timezone_list = [];
|
||||
foreach ($offsets as $timezone => $offset) {
|
||||
$offset_prefix = $offset < 0 ? '-' : '+';
|
||||
$offset_formatted = gmdate('H:i', abs($offset));
|
||||
@@ -344,41 +362,46 @@ abstract class Utils
|
||||
}
|
||||
|
||||
return $timezone_list;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $source
|
||||
* @param $fn
|
||||
* Recursively filter an array, filtering values by processing them through the $fn function argument
|
||||
*
|
||||
* @param array $source the Array to filter
|
||||
* @param callable $fn the function to pass through each array item
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayFilterRecursive(Array $source, $fn)
|
||||
{
|
||||
$result = array();
|
||||
foreach ($source as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$result = [];
|
||||
foreach ($source as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$result[$key] = static::arrayFilterRecursive($value, $fn);
|
||||
continue;
|
||||
}
|
||||
if ($fn($key, $value))
|
||||
{
|
||||
if ($fn($key, $value)) {
|
||||
$result[$key] = $value; // KEEP
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
* Checks if the passed path contains the language code prefix
|
||||
*
|
||||
* @param string $string The path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function pathPrefixedByLangCode($string)
|
||||
{
|
||||
if (strlen($string) <= 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$languages_enabled = self::getGrav()['config']->get('system.languages.supported', []);
|
||||
|
||||
if ($string[0] == '/' && $string[3] == '/' && in_array(substr($string, 1, 2), $languages_enabled)) {
|
||||
@@ -389,9 +412,12 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $date
|
||||
* Get the timestamp of a date
|
||||
*
|
||||
* @return int
|
||||
* @param string $date a String expressed in the system.pages.dateformat.default format, with fallback to a
|
||||
* strtotime argument
|
||||
*
|
||||
* @return int the timestamp
|
||||
*/
|
||||
public static function date2timestamp($date)
|
||||
{
|
||||
@@ -414,7 +440,13 @@ abstract class Utils
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value of an array using dot notation
|
||||
* Get value of an array element using dot notation
|
||||
*
|
||||
* @param array $array the Array to check
|
||||
* @param string $path the dot notation path to check
|
||||
* @param mixed $default a value to be returned if $path is not found in $array
|
||||
*
|
||||
* @return mixed the value found
|
||||
*/
|
||||
public static function resolve(array $array, $path, $default = null)
|
||||
{
|
||||
@@ -450,7 +482,7 @@ abstract class Utils
|
||||
* with reverse proxy setups.
|
||||
*
|
||||
* @param string $action
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
*
|
||||
* @return string the nonce string
|
||||
*/
|
||||
@@ -469,11 +501,10 @@ abstract class Utils
|
||||
$i++;
|
||||
}
|
||||
|
||||
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
}
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
//TODO: to be removed
|
||||
private static function generateNonceStringOldStyle($action, $plusOneTick = false)
|
||||
{
|
||||
if (isset(self::getGrav()['user'])) {
|
||||
@@ -490,13 +521,14 @@ abstract class Utils
|
||||
if ($plusOneTick) {
|
||||
$i++;
|
||||
}
|
||||
return ( $i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
|
||||
return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . self::getGrav()['config']->get('security.salt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the time-dependent variable for nonce creation.
|
||||
*
|
||||
* @todo now a tick lasts a day. Once the day is passed, the nonce is not valid any more. Find a better way
|
||||
* Now a tick lasts a day. Once the day is passed, the nonce is not valid any more. Find a better way
|
||||
* to ensure nonces issued near the end of the day do not expire in that small amount of time
|
||||
*
|
||||
* @return int the time part of the nonce. Changes once every 24 hours
|
||||
@@ -504,15 +536,16 @@ abstract class Utils
|
||||
private static function nonceTick()
|
||||
{
|
||||
$secondsInHalfADay = 60 * 60 * 12;
|
||||
return (int)ceil(time() / ( $secondsInHalfADay ));
|
||||
|
||||
return (int)ceil(time() / ($secondsInHalfADay));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hashed nonce tied to the passed action. Tied to the current user and time. The nonce for a given
|
||||
* action is the same for 12 hours.
|
||||
*
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
*
|
||||
* @return string the nonce
|
||||
*/
|
||||
@@ -529,7 +562,6 @@ abstract class Utils
|
||||
}
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
//TODO: to be removed
|
||||
public static function getNonceOldStyle($action, $plusOneTick = false)
|
||||
{
|
||||
// Don't regenerate this again if not needed
|
||||
@@ -545,7 +577,7 @@ abstract class Utils
|
||||
/**
|
||||
* Verify the passed nonce for the give action
|
||||
*
|
||||
* @param string $nonce the nonce to verify
|
||||
* @param string $nonce the nonce to verify
|
||||
* @param string $action the action to verify the nonce to
|
||||
*
|
||||
* @return boolean verified or not
|
||||
@@ -570,7 +602,6 @@ abstract class Utils
|
||||
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
//TODO: to be removed
|
||||
//Nonce generated 0-12 hours ago
|
||||
if ($nonce == self::getNonceOldStyle($action)) {
|
||||
return true;
|
||||
@@ -581,7 +612,6 @@ abstract class Utils
|
||||
if ($nonce == self::getNonceOldStyle($action, $plusOneTick)) {
|
||||
return true;
|
||||
}
|
||||
//End TODO: to be removed
|
||||
|
||||
//Invalid nonce
|
||||
return false;
|
||||
|
||||
@@ -24,6 +24,8 @@ class CleanCommand extends Command
|
||||
* @var array
|
||||
*/
|
||||
protected $paths_to_remove = [
|
||||
'codeception.yml',
|
||||
'tests/',
|
||||
'user/plugins/email/vendor/swiftmailer/swiftmailer/.travis.yml',
|
||||
'user/plugins/email/vendor/swiftmailer/swiftmailer/build.xml',
|
||||
'user/plugins/email/vendor/swiftmailer/swiftmailer/composer.json',
|
||||
|
||||
@@ -55,6 +55,7 @@ class SandboxCommand extends ConsoleCommand
|
||||
'/system' => '/system',
|
||||
'/vendor' => '/vendor',
|
||||
'/webserver-configs' => '/webserver-configs',
|
||||
'/codeception.yml' => '/codeception.yml',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,6 +30,9 @@ class ConsoleCommand extends Command
|
||||
/**
|
||||
*
|
||||
*/
|
||||
protected function serve() { }
|
||||
protected function serve()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ use Grav\Common\GPM\GPM;
|
||||
use Grav\Console\ConsoleCommand;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
|
||||
|
||||
/**
|
||||
* Class InfoCommand
|
||||
@@ -34,6 +35,12 @@ class InfoCommand extends ConsoleCommand
|
||||
InputOption::VALUE_NONE,
|
||||
'Force fetching the new data remotely'
|
||||
)
|
||||
->addOption(
|
||||
'all-yes',
|
||||
'y',
|
||||
InputOption::VALUE_NONE,
|
||||
'Assumes yes (or best approach) instead of prompting'
|
||||
)
|
||||
->addArgument(
|
||||
'package',
|
||||
InputArgument::REQUIRED,
|
||||
@@ -107,9 +114,62 @@ class InfoCommand extends ConsoleCommand
|
||||
}
|
||||
}
|
||||
|
||||
$type = rtrim($foundPackage->package_type, 's');
|
||||
$updatable = $this->gpm->{'is' . $type . 'Updatable'}($foundPackage->slug);
|
||||
$installed = $this->gpm->{'is' . $type . 'Installed'}($foundPackage->slug);
|
||||
|
||||
// display current version if installed and different
|
||||
if ($installed && $updatable) {
|
||||
$local = $this->gpm->{'getInstalled'. $type}($foundPackage->slug);
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln("Currently installed version: <magenta>" . $local->version . "</magenta>");
|
||||
$this->output->writeln('');
|
||||
}
|
||||
|
||||
// display changelog information
|
||||
$questionHelper = $this->getHelper('question');
|
||||
$skipPrompt = $this->input->getOption('all-yes');
|
||||
|
||||
if (!$skipPrompt) {
|
||||
$question = new ConfirmationQuestion("Would you like to read the changelog? [y|N] ",
|
||||
false);
|
||||
$answer = $questionHelper->ask($this->input, $this->output, $question);
|
||||
|
||||
if ($answer) {
|
||||
$changelog = $foundPackage->changelog;
|
||||
|
||||
$this->output->writeln("");
|
||||
foreach ($changelog as $version => $log) {
|
||||
$title = $version . ' [' . $log['date'] . ']';
|
||||
$content = preg_replace_callback("/\d\.\s\[\]\(#(.*)\)/", function ($match) {
|
||||
return "\n" . ucfirst($match[1]) . ":";
|
||||
}, $log['content']);
|
||||
|
||||
$this->output->writeln('<cyan>'.$title.'</cyan>');
|
||||
$this->output->writeln(str_repeat('-', strlen($title)));
|
||||
$this->output->writeln($content);
|
||||
$this->output->writeln("");
|
||||
|
||||
$question = new ConfirmationQuestion("Press [ENTER] to continue or [q] to quit ", true);
|
||||
if (!$questionHelper->ask($this->input, $this->output, $question)) {
|
||||
break;
|
||||
}
|
||||
$this->output->writeln("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->output->writeln('');
|
||||
$this->output->writeln("You can install this package by typing:");
|
||||
$this->output->writeln(" <green>" . $this->argv . " install</green> <cyan>" . $foundPackage->slug . "</cyan>");
|
||||
|
||||
if ($installed && $updatable) {
|
||||
$this->output->writeln("You can update this package by typing:");
|
||||
$this->output->writeln(" <green>" . $this->argv . " update</green> <cyan>" . $foundPackage->slug . "</cyan>");
|
||||
} else {
|
||||
$this->output->writeln("You can install this package by typing:");
|
||||
$this->output->writeln(" <green>" . $this->argv . " install</green> <cyan>" . $foundPackage->slug . "</cyan>");
|
||||
}
|
||||
|
||||
$this->output->writeln('');
|
||||
|
||||
}
|
||||
|
||||
55
tests/_bootstrap.php
Normal file
55
tests/_bootstrap.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
// This is global bootstrap for autoloading
|
||||
|
||||
namespace Grav;
|
||||
|
||||
use Codeception\Util\Fixtures;
|
||||
use Faker\Factory;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
ini_set('error_log', __DIR__ . '/error.log');
|
||||
|
||||
// Ensure vendor libraries exist
|
||||
$autoload = __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
if (!is_file($autoload)) {
|
||||
throw new \RuntimeException("Please run: <i>bin/grav install</i>");
|
||||
}
|
||||
|
||||
use Grav\Common\Grav;
|
||||
|
||||
// Register the auto-loader.
|
||||
$loader = require_once $autoload;
|
||||
|
||||
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
|
||||
throw new \RuntimeException(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req));
|
||||
}
|
||||
|
||||
// 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')) {
|
||||
throw new \RuntimeException("'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(['loader' => $loader]);
|
||||
|
||||
$grav['uri']->init();
|
||||
$grav['debugger']->init();
|
||||
$grav['assets']->init();
|
||||
|
||||
$grav['config']->set('system.cache.enabled', false);
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $grav['locator'];
|
||||
$locator->addPath('tests', '', 'tests', false);
|
||||
|
||||
// Set default $_SERVER value used for nonces
|
||||
empty( $_SERVER['HTTP_CLIENT_IP'] ) && $_SERVER['HTTP_CLIENT_IP'] = '127.0.0.1';
|
||||
|
||||
$fake = Factory::create();
|
||||
Fixtures::add('grav', $grav);
|
||||
Fixtures::add('fake', $fake);
|
||||
26
tests/_support/AcceptanceTester.php
Normal file
26
tests/_support/AcceptanceTester.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class AcceptanceTester extends \Codeception\Actor
|
||||
{
|
||||
use _generated\AcceptanceTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
||||
26
tests/_support/FunctionalTester.php
Normal file
26
tests/_support/FunctionalTester.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class FunctionalTester extends \Codeception\Actor
|
||||
{
|
||||
use _generated\FunctionalTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
||||
10
tests/_support/Helper/Acceptance.php
Normal file
10
tests/_support/Helper/Acceptance.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Helper;
|
||||
|
||||
// here you can define custom actions
|
||||
// all public methods declared in helper class will be available in $I
|
||||
|
||||
class Acceptance extends \Codeception\Module
|
||||
{
|
||||
|
||||
}
|
||||
10
tests/_support/Helper/Functional.php
Normal file
10
tests/_support/Helper/Functional.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
namespace Helper;
|
||||
|
||||
// here you can define custom actions
|
||||
// all public methods declared in helper class will be available in $I
|
||||
|
||||
class Functional extends \Codeception\Module
|
||||
{
|
||||
|
||||
}
|
||||
80
tests/_support/Helper/Unit.php
Normal file
80
tests/_support/Helper/Unit.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
namespace Helper;
|
||||
|
||||
use Codeception;
|
||||
// here you can define custom actions
|
||||
// all public methods declared in helper class will be available in $I
|
||||
|
||||
/**
|
||||
* Class Unit
|
||||
* @package Helper
|
||||
*/
|
||||
class Unit extends Codeception\Module
|
||||
{
|
||||
/**
|
||||
* HOOK: used after configuration is loaded
|
||||
*/
|
||||
public function _initialize() {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: on every Actor class initialization
|
||||
*/
|
||||
public function _cleanup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: before suite
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function _beforeSuite($settings = []) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: after suite
|
||||
**/
|
||||
public function _afterSuite() {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: before each step
|
||||
*
|
||||
* @param Codeception\Step $step*
|
||||
*/
|
||||
public function _beforeStep(Codeception\Step $step) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: after each step
|
||||
*
|
||||
* @param Codeception\Step $step
|
||||
*/
|
||||
public function _afterStep(Codeception\Step $step) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: before each suite
|
||||
*
|
||||
* @param Codeception\TestCase $test
|
||||
*/
|
||||
public function _before(Codeception\TestCase $test) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: before each suite
|
||||
*
|
||||
* @param Codeception\TestCase $test
|
||||
*/
|
||||
public function _after(Codeception\TestCase $test) {
|
||||
}
|
||||
|
||||
/**
|
||||
* HOOK: on fail
|
||||
*
|
||||
* @param Codeception\TestCase $test
|
||||
* @param $fail
|
||||
*/
|
||||
public function _failed(Codeception\TestCase $test, $fail) {
|
||||
}
|
||||
}
|
||||
26
tests/_support/UnitTester.php
Normal file
26
tests/_support/UnitTester.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
|
||||
/**
|
||||
* Inherited Methods
|
||||
* @method void wantToTest($text)
|
||||
* @method void wantTo($text)
|
||||
* @method void execute($callable)
|
||||
* @method void expectTo($prediction)
|
||||
* @method void expect($prediction)
|
||||
* @method void amGoingTo($argumentation)
|
||||
* @method void am($role)
|
||||
* @method void lookForwardTo($achieveValue)
|
||||
* @method void comment($description)
|
||||
* @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
|
||||
*
|
||||
* @SuppressWarnings(PHPMD)
|
||||
*/
|
||||
class UnitTester extends \Codeception\Actor
|
||||
{
|
||||
use _generated\UnitTesterActions;
|
||||
|
||||
/**
|
||||
* Define custom actions here
|
||||
*/
|
||||
}
|
||||
12
tests/acceptance.suite.yml
Normal file
12
tests/acceptance.suite.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
# Codeception Test Suite Configuration
|
||||
#
|
||||
# Suite for acceptance tests.
|
||||
# Perform tests in browser using the WebDriver or PhpBrowser.
|
||||
# If you need both WebDriver and PHPBrowser tests - create a separate suite.
|
||||
|
||||
class_name: AcceptanceTester
|
||||
modules:
|
||||
enabled:
|
||||
- PhpBrowser:
|
||||
url: http://localhost:8080/grav
|
||||
- \Helper\Acceptance
|
||||
2
tests/acceptance/_bootstrap.php
Normal file
2
tests/acceptance/_bootstrap.php
Normal file
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Here you can initialize variables that will be available to your tests
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Item 1-1-1
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Item 1-1-2
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Item 1-1-3
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Item 1-1
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Item 1-2-1
|
||||
---
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user