This commit is contained in:
2019-09-27 00:29:18 +02:00
parent 40af43681e
commit b857814072
470 changed files with 37562 additions and 10060 deletions
+1 -2
View File
@@ -13,6 +13,5 @@ indent_style = space
indent_size = 4 indent_size = 4
# 2 space indentation # 2 space indentation
[*.yaml, *.yml] [*.{yaml,.yml}]
indent_style = space
indent_size = 2 indent_size = 2
+8
View File
@@ -0,0 +1,8 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: grav
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: # Replace with a single custom sponsorship URL
+4 -1
View File
@@ -23,6 +23,8 @@ user/data/*
!user/data/.* !user/data/.*
user/plugins/* user/plugins/*
!user/plugins/.* !user/plugins/.*
user/themes/*
!user/themes/.*
user/localhost/config/security.yaml user/localhost/config/security.yaml
user/config/security.yaml user/config/security.yaml
@@ -36,8 +38,9 @@ Thumbs.db
# phpstorm # phpstorm
.idea/* .idea/*
# testing stuff
tests/_output/* tests/_output/*
tests/_support/_generated/* tests/_support/_generated/*
tests/cache/* tests/cache/*
tests/error.log tests/error.log
/system/templates/testing system/templates/testing/*
+1 -1
View File
@@ -9,7 +9,7 @@ RewriteEngine On
# along the lines of: RewriteBase /<your_sub_folder> # along the lines of: RewriteBase /<your_sub_folder>
## ##
RewriteBase / # RewriteBase /
## End - RewriteBase ## End - RewriteBase
+3 -11
View File
@@ -1,9 +1,8 @@
language: php language: php
php: php:
- '5.6'
- '7.0.21'
- '7.1' - '7.1'
- '7.2' - '7.2'
- '7.3'
branches: branches:
only: only:
- develop - develop
@@ -13,13 +12,6 @@ notifications:
email: email:
on_success: never on_success: never
on_failure: always on_failure: always
hipchat:
# hipchat_api@grav
rooms:
- secure: "bqO0wM1B7bJnQw2fuhquSXEqI9gw6WmFytIh9sEWXzbYTzTUP5t0PcKOd3FT2BNMRaDxPJLVl+vG/oqmqDUBkEmOGcG504IQjeNzZqnMz0tXQMIcCc22Las9tFfc4Jf6RVi/qGomFtHGE9Wgii+TAN4zqZaufbNjwd8SyjO0+W8="
template:
- '%{repository}#%{build_number} (%{branch}): Travis Job Finished [%{duration}] (<a href="%{build_url}">Details</a>)'
format: html
slack: slack:
secure: dowksPsxxCxGKT6nis5hUgkp6+ZDAhoqzQHF9rJnx4hx0iEygPhVBs7pKl9yL2jubYJoLs+EXwE7z1dYgDAEJh4BnfrCokCMLpFGcxVxQC/HeAUdSQ2/RtdBYR5PRT75ScaFpqM/SfXXZVtnwVXAw9Z+JC6BjQ9vmn23m51Jw4k= secure: dowksPsxxCxGKT6nis5hUgkp6+ZDAhoqzQHF9rJnx4hx0iEygPhVBs7pKl9yL2jubYJoLs+EXwE7z1dYgDAEJh4BnfrCokCMLpFGcxVxQC/HeAUdSQ2/RtdBYR5PRT75ScaFpqM/SfXXZVtnwVXAw9Z+JC6BjQ9vmn23m51Jw4k=
env: env:
@@ -53,7 +45,7 @@ before_install:
- if [ $TRAVIS_BRANCH == 'develop' ] || [ $TRAVIS_PULL_REQUEST != 'false' ]; then - if [ $TRAVIS_BRANCH == 'develop' ] || [ $TRAVIS_PULL_REQUEST != 'false' ]; then
composer install --dev --prefer-dist; composer install --dev --prefer-dist;
fi fi
- if [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "5.6" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then - if [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "7.1" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then
export 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); export 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);
eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=1.8 bash)"; eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=1.8 bash)";
go get github.com/aktau/github-release; go get github.com/aktau/github-release;
@@ -70,7 +62,7 @@ script:
vendor/bin/codecept run; vendor/bin/codecept run;
fi fi
- echo "Latest Release Tag - ${TRAVIS_TAG}" - echo "Latest Release Tag - ${TRAVIS_TAG}"
- if [ ! -z "$TRAVIS_TAG" ] && [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "5.6" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then - if [ ! -z "$TRAVIS_TAG" ] && [ $TRAVIS_BRANCH != 'develop' ] && [ $TRAVIS_PHP_VERSION == "7.1" ] && [ $TRAVIS_PULL_REQUEST == "false" ]; then
FILES="$RT_DEVTOOLS/grav-dist/*.zip"; FILES="$RT_DEVTOOLS/grav-dist/*.zip";
for file in ${FILES[@]}; do for file in ${FILES[@]}; do
NAME=${file##*/}; NAME=${file##*/};
+373 -1
View File
@@ -1,3 +1,375 @@
# v1.6.16
## 09/19/2019
1. [](#bugfix)
* Fixed Flex user creation if file storage is being used [#2444](https://github.com/getgrav/grav/issues/2444)
* Fixed `Badly encoded JSON data` warning when uploading files [#2663](https://github.com/getgrav/grav/issues/2663)
# v1.6.15
## 08/20/2019
1. [](#improved)
* Improved robots.txt [#2632](https://github.com/getgrav/grav/issues/2632)
1. [](#bugfix)
* Fixed broken markdown Twig tag [#2635](https://github.com/getgrav/grav/issues/2635)
* Force Symfony 4.2 in Grav 1.6 to remove a bunch of deprecated messages
# v1.6.14
## 08/18/2019
1. [](#bugfix)
* Actually include fix for `system\router.php` [#2627](https://github.com/getgrav/grav/issues/2627)
# v1.6.13
## 08/16/2019
1. [](#bugfix)
* Regression fix for `system\router.php` [#2627](https://github.com/getgrav/grav/issues/2627)
# v1.6.12
## 08/14/2019
1. [](#new)
* Added support for custom `FormFlash` save locations
* Added a new `Utils::arrayLower()` method for lowercasing arrays
* Support new GRAV_BASEDIR environment variable [#2541](https://github.com/getgrav/grav/pull/2541)
* Allow users to override plugin handler priorities [#2165](https://github.com/getgrav/grav/pull/2165)
1. [](#improved)
* Use new `Utils::getSupportedPageTypes()` to enforce `html,htm` at the front of the list [#2531](https://github.com/getgrav/grav/issues/2531)
* Updated vendor libraries
* Markdown filter is now page-aware so that it works with modular references [admin#1731](https://github.com/getgrav/grav-plugin-admin/issues/1731)
* Check of `GRAV_USER_INSTANCE` constant is already defined [#2621](https://github.com/getgrav/grav/pull/2621)
1. [](#bugfix)
* Fixed some potential issues when `$grav['user']` is not set
* Fixed error when calling `Media::add($name, null)`
* Fixed `url()` returning wrong path if using stream with grav root path in it, eg: `user-data://shop` when Grav is in `/shop`
* Fixed `url()` not returning a path to non-existing file (`user-data://shop` => `/user/data/shop`) if it is set to fail gracefully
* Fixed `url()` returning false on unknown streams, such as `ftp://domain.com`, they should be treated as external URL
* Fixed Flex User to have permissions to save and delete his own user
* Fixed new Flex User creation not being possible because of username could not be given
* Fixed fatal error 'Expiration date must be an integer, a DateInterval or null, "double" given' [#2529](https://github.com/getgrav/grav/issues/2529)
* Fixed non-existing Flex object having a bad media folder
* Fixed collections using `page@.self:` should allow modular pages if requested
* Fixed an error when trying to delete a file from non-existing Flex Object
* Fixed `FlexObject::exists()` failing sometimes just after the object has been saved
* Fixed CSV formatter not encoding strings with `"` and `,` properly
* Fixed var order in `Validation.php` [#2610](https://github.com/getgrav/grav/issues/2610)
# v1.6.11
## 06/21/2019
1. [](#new)
* Added `FormTrait::getAllFlashes()` method to get all the available form flash objects for the form
* Added creation and update timestamps to `FormFlash` objects
1. [](#improved)
* Added `FormFlashInterface`, changed constructor to take `$config` array
1. [](#bugfix)
* Fixed error in `ImageMedium::url()` if the image cache folder does not exist
* Fixed empty form flash name after file upload or form state update
* Fixed a bug in `Route::withParam()` method
* Fixed issue with `FormFlash` objects when there is no session initialized
# v1.6.10
## 06/14/2019
1. [](#improved)
* Added **page blueprints** to `YamlLinter` CLI and Admin reports
* Removed `Gitter` and `Slack` [#2502](https://github.com/getgrav/grav/issues/2502)
* Optimizations for Plugin/Theme loading
* Generalized markdown classes so they can be used outside of `Page` scope with a custom `Excerpts` class instance
* Change minimal port number to 0 (unix socket) [#2452](https://github.com/getgrav/grav/issues/2452)
1. [](#bugfix)
* Force question to install demo content in theme update [#2493](https://github.com/getgrav/grav/issues/2493)
* Fixed GPM errors from blueprints not being logged [#2505](https://github.com/getgrav/grav/issues/2505)
* Don't error when IP is invalid [#2507](https://github.com/getgrav/grav/issues/2507)
* Fixed regression with `bin/plugin` not listing the plugins available (1c725c0)
* Fixed bitwise operator in `TwigExtension::exifFunc()` [#2518](https://github.com/getgrav/grav/issues/2518)
* Fixed issue with lang prefix incorrectly identifying as admin [#2511](https://github.com/getgrav/grav/issues/2511)
* Fixed issue with `U0ils::pathPrefixedBYLanguageCode()` and trailing slash [#2510](https://github.com/getgrav/grav/issues/2511)
* Fixed regresssion issue of `Utils::Url()` not returning `false` on failure. Added new optional `fail_gracefully` 3rd attribute to return string that caused failure [#2524](https://github.com/getgrav/grav/issues/2524)
# v1.6.9
## 05/09/2019
1. [](#new)
* Added `Route::withoutParams()` methods
* Added `Pages::setCheckMethod()` method to override page configuration in Admin Plugin
* Added `Cache::clearCache('invalidate')` parameter for just invalidating the cache without deleting any cached files
* Made `UserCollectionInderface` to extend `Countable` to get the count of existing users
1. [](#improved)
* Flex admin: added default search options for flex objects
* Flex collection and object now fall back to the default template if template file doesn't exist
* Updated Vendor libraries including Twig 1.40.1
* Updated language files from `https://crowdin.com/project/grav-core`
1. [](#bugfix)
* Fixed `$grav['route']` from being modified when the route instance gets modified
* Fixed Assets options array mixed with standalone priority [#2477](https://github.com/getgrav/grav/issues/2477)
* Fix for `avatar_url` provided by 3rd party providers
* Fixed non standard `lang` code lengths in `Utils` and `Session` detection
* Fixed saving a new object in Flex `SimpleStorage`
* Fixed exception in `Flex::getDirectories()` if the first parameter is set
* Output correct "Last Updated" in `bin/gpm info` command
* Checkbox getting interpreted as string, so created new `Validation::filterCheckbox()`
* Fixed backwards compatibility to `select` field with `selectize.create` set to true [git-sync#141](https://github.com/trilbymedia/grav-plugin-git-sync/issues/141)
* Fixed `YamlFormatter::decode()` to always return array [#2494](https://github.com/getgrav/grav/pull/2494)
* Fixed empty `$grav['request']->getAttribute('route')->getExtension()`
# v1.6.8
## 04/23/2019
1. [](#new)
* Added `FlexCollection::filterBy()` method
1. [](#bugfix)
* Revert `Use Null Coalesce Operator` [#2466](https://github.com/getgrav/grav/pull/2466)
* Fixed `FormTrait::render()` not providing config variable
* Updated `bin/grav clean` to clear `cache/compiled` and `user/config/security.yaml`
# v1.6.7
## 04/22/2019
1. [](#new)
* Added a new `bin/grav yamllinter` CLI command to find YAML Linting issues [#2468](https://github.com/getgrav/grav/issues/2468#issuecomment-485151681)
1. [](#improved)
* Improve `FormTrait` backwards compatibility with existing forms
* Added a new `Utils::getSubnet()` function for IPv4/IPv6 parsing [#2465](https://github.com/getgrav/grav/pull/2465)
1. [](#bugfix)
* Remove disabled fields from the form schema
* Fix issue when excluding `inlineJs` and `inlineCss` from Assets pipeline [#2468](https://github.com/getgrav/grav/issues/2468)
* Fix for manually set position on external URLs [#2470](https://github.com/getgrav/grav/issues/2470)
# v1.6.6
## 04/17/2019
1. [](#new)
* `FormInterface` now implements `RenderInterface`
* Added new `FormInterface::getTask()` method which reads the task from `form.task` in the blueprint
1. [](#improved)
* Updated vendor libraries to latest
1. [](#bugfix)
* Rollback `redirect_default_route` logic as it has issues with multi-lang [#2459](https://github.com/getgrav/grav/issues/2459)
* Fix potential issue with `|contains` Twig filter on PHP 7.3
* Fixed bug in text field filtering: return empty string if value isn't a string or number [#2460](https://github.com/getgrav/grav/issues/2460)
* Force Asset `priority` to be an integer and not throw error if invalid string passed [#2461](https://github.com/getgrav/grav/issues/2461)
* Fixed bug in text field filtering: return empty string if value isn't a string or number
* Fixed `FlexForm` missing getter methods for defining form variables
# v1.6.5
## 04/15/2019
1. [](#bugfix)
* Backwards compatiblity with old `Uri::__toString()` output
# v1.6.4
## 04/15/2019
1. [](#bugfix)
* Improved `redirect_default_route` logic as well as `Uri::toArray()` to take into account `root_path` and `extension`
* Rework logic to pull out excluded files from pipeline more reliably [#2445](https://github.com/getgrav/grav/issues/2445)
* Better logic in `Utils::normalizePath` to handle externals properly [#2216](https://github.com/getgrav/grav/issues/2216)
* Fixed to force all `Page::taxonomy` to be treated as strings [#2446](https://github.com/getgrav/grav/issues/2446)
* Fixed issue with `Grav['user']` not being available [form#332](https://github.com/getgrav/grav-plugin-form/issues/332)
* Updated rounding logic for `Utils::parseSize()` [#2394](https://github.com/getgrav/grav/issues/2394)
* Fixed Flex simple storage not being properly initialized if used with caching
# v1.6.3
## 04/12/2019
1. [](#new)
* Added `Blueprint::addDynamicHandler()` method to allow custom dynamic handlers, for example `custom-options@: getCustomOptions`
1. [](#bugfix)
* Missed a `CacheCommand` reference in `bin/grav` [#2442](https://github.com/getgrav/grav/issues/2442)
* Fixed issue with `Utils::normalizePath` messing with external URLs [#2216](https://github.com/getgrav/grav/issues/2216)
* Fix for `vUndefined` versions when upgrading
# v1.6.2
## 04/11/2019
1. [](#bugfix)
* Revert renaming of `ClearCacheCommand` to ensure CLI GPM upgrades go smoothly
# v1.6.1
## 04/11/2019
1. [](#improved)
* Improved CSS for the bottom filter bar of DebugBar
1. [](#bugfix)
* Fixed issue with `@import` not being added to top of pipelined css [#2440](https://github.com/getgrav/grav/issues/2440)
# v1.6.0
## 04/11/2019
1. [](#new)
* Set minimum requirements to [PHP 7.1.3](https://getgrav.org/blog/raising-php-requirements-2018)
* New `Scheduler` functionality for periodic jobs
* New `Backup` functionality with multiple backup profiles and scheduler integration
* Refactored `Assets Manager` to be more powerful and flexible
* Updated Doctrine Collections to 1.6
* Updated Doctrine Cache to 1.8
* Updated Symfony Components to 4.2
* Added new Cache purge functionality old cache manually via CLI/Admin as well as scheduler integration
* Added new `{% throw 404 'Not Found' %}` twig tag (with custom code/message)
* Added `Grav\Framework\File` classes for handling YAML, Markdown, JSON, INI and PHP serialized files
* Added `Grav\Framework\Collection\AbstractIndexCollection` class
* Added `Grav\Framework\Object\ObjectIndex` class
* Added `Grav\Framework\Flex` classes
* Added support for hiding form fields in blueprints by using dynamic property like `security@: admin.foobar`, `scope@: object` or `scope-ignore@: object` to any field
* New experimental **FlexObjects** powered `Users` for increased performance and capability (**disabled** by default)
* Added PSR-7 and PSR-15 classes
* Added `Grav\Framework\DI\Container` class
* Added `Grav\Framework\RequestHandler\RequestHandler` class
* Added `Page::httpResponseCode()` and `Page::httpHeaders()` methods
* Added `Grav\Framework\Form\Interfaces\FormInterface`
* Added `Grav\Framework\Form\Interfaces\FormFactoryInterface`
* Added `Grav\Framework\Form\FormTrait`
* Added `Page::forms()` method to get normalized list of all form headers defined in the page
* Added `onPageAction`, `onPageTask`, `onPageAction.{$action}` and `onPageTask.{$task}` events
* Added `Blueprint::processForm()` method to filter form inputs
* Move `processMarkdown()` method from `TwigExtension` to more general `Utils` class
* Added support to include extra files into `Media` (such as uploaded files)
* Added form preview support for `FlexObject`, including a way to render newly uploaded files before saving them
* Added `FlexObject::getChanges()` to determine what fields change during an update
* Added `arrayDiffMultidimensional`, `arrayIsAssociative`, `arrayCombine` Util functions
* New `$grav['users']` service to allow custom user classes implementing `UserInterface`
* Added `LogViewer` helper class and CLI command: `bin/grav logviewer`
* Added `select()` and `unselect()` methods to `CollectionInterface` and its base classes
* Added `orderBy()` and `limit()` methods to `ObjectCollectionInterface` and its base classes
* Added `user-data://` which is a writable stream (`user://data` is not and should be avoided)
* Added support for `/action:{$action}` (like task but used without nonce when only receiving data)
* Added `onAction.{$action}` event
* Added `Grav\Framework\Form\FormFlash` class to contain AJAX uploaded files in more reliable way
* Added `Grav\Framework\Form\FormFlashFile` class which implements `UploadedFileInterface` from PSR-7
* Added `Grav\Framework\Filesystem\Filesystem` class with methods to manipulate stream URLs
* Added new `$grav['filesystem']` service using an instance of the new `Filesystem` object
* Added `{% render object layout: 'default' with { variable: true } %}` for Flex objects and collections
* Added `$grav->setup()` to simplify CLI and custom access points
* Added `CsvFormatter` and `CsvFile` classes
* Added new system config option to `pages.hide_empty_folders` if a folder has no valid `.md` file available. Default behavior is `false` for compatibility.
* Added new system config option for `languages.pages_fallback_only` forcing only 'fallback' to find page content through supported languages, default behavior is to display any language found if active language is missing
* Added `Utils::arrayFlattenDotNotation()` and `Utils::arrayUnflattenDotNotation()` helper methods
1. [](#improved)
* Add the page to onMarkdownInitialized event [#2412](https://github.com/getgrav/grav/issues/2412)
* Doctrine filecache is now namespaced with prefix to support purging
* Register all page types into `blueprint://pages` stream
* Removed `apc` and `xcache` support, made `apc` alias of `apcu`
* Support admin and regular translations via the `|t` twig filter and `t()` twig function
* Improved Grav Core installer/updater to run installer script
* Updated vendor libraries including Symfony `4.2.3`
* Renamed old `User` class to `Grav\Common\User\DataUser\User` with multiple improvements and small fixes
* `User` class now acts as a compatibility layer to older versions of Grav
* Deprecated `new User()`, `User::load()`, `User::find()` and `User::delete()` in favor of `$grav['users']` service
* `Media` constructor has now support to not to initialize the media objects
* Cleanly handle session corruption due to changing Flex object types
* Added `FlexObjectInterface::getDefaultValue()` and `FormInterface::getDefaultValue()`
* Added new `onPageContent()` event for every call to `Page::content()`
* Added phpstan: PHP Static Analysis Tool [#2393](https://github.com/getgrav/grav/pull/2393)
* Added `composer test-plugins` to test plugin issues with the current version of Grav
* Added `Flex::getObjects()` and `Flex::getMixedCollection()` methods for co-mingled collections
* Added support to use single Flex key parameter in `Flex::getObject()` method
* Added `FlexObjectInterface::search()` and `FlexCollectionInterface::search()` methods
* Override `system.media.upload_limit` with PHP's `post_max_size` or `upload_max_filesize`
* Class `Grav\Common\Page\Medium\AbstractMedia` now use array traits instead of extending `Grav\Common\Getters`
* Implemented `Grav\Framework\Psr7` classes as `Nyholm/psr7` decorators
* Added a new `cache-clear` scheduled job to go along with `cache-purge`
* Renamed `Grav\Framework\File\Formatter\FormatterInterface` to `Grav\Framework\File\Interfaces\FileFormatterInterface`
* Improved `File::save()` to use a temporary file if file isn't locked
* Improved `|t` filter to better support admin `|tu` style filter if in admin
* Update all classes to rely on `PageInterface` instead of `Page` class
* Better error checking in `bin/plugin` for existence and enabled
* Removed `media.upload_limit` references
* Twig `nicenumber`: do not use 0 + string casting hack
* Converted Twig tags to use namespaced Twig classes
* Site shows error on page rather than hard-crash when page has invalid frontmatter [#2343](https://github.com/getgrav/grav/issues/2343)
* Added `languages.default_lang` option to override the default lang (usually first supported language)
* Added `Content-Type: application/json` body support for PSR-7 `ServerRequest`
* Remove PHP time limit in `ZipArchive`
* DebugBar: Resolve twig templates in deprecated backtraces in order to help locating Twig issues
* Added `$grav['cache']->getSimpleCache()` method for getting PSR-16 compatible cache
* MediaTrait: Use PSR-16 cache
* Improved `Utils::normalizePath()` to support non-protocol URLs
* Added ability to reset `Page::metadata` to allow rebuilding from automatically generated values
* Added back missing `page.types` field in system content configuration [admin#1612](https://github.com/getgrav/grav-plugin-admin/issues/1612)
* Console commands: add method for invalidating cache
* Updated languages
* Improved `$page->forms()` call, added `$page->addForms()`
* Updated languages from crowdin
* Fixed `ImageMedium` constructor warning when file does not exist
* Improved `Grav\Common\User` class; added `$user->update()` method
* Added trim support for text input fields `validate: trim: true`
* Improved `Grav\Framework\File\Formatter` classes to have abstract parent class and some useful methods
* Support negotiated content types set via the Request `Accept:` header
* Support negotiated language types set via the Request `Accept-Language:` header
* Cleaned up and sorted the Service `idMap`
* Updated `Grav` container object to implement PSR-11 `ContainerInterface`
* Updated Grav `Processor` classes to implement PSR-15 `MiddlewareInterface`
* Make `Data` class to extend `JsonSerializable`
* Modified debugger icon to use retina space-dude version
* Added missing `Video::preload()` method
* Set session name based on `security.salt` rather than `GRAV_ROOT` [#2242](https://github.com/getgrav/grav/issues/2242)
* Added option to configure list of `xss_invalid_protocols` in `Security` config [#2250](https://github.com/getgrav/grav/issues/2250)
* Smarter `security.salt` checking now we use `security.yaml` for other options
* Added apcu autoloader optimization
* Additional helper methods in `Language`, `Languages`, and `LanguageCodes` classes
* Call `onFatalException` event also on internal PHP errors
* Built-in PHP Webserver: log requests before handling them
* Added support for syslog and syslog facility logging (default: 'file')
* Improved usability of `System` configuration blueprint with side-tabs
1. [](#bugfix)
* Fixed issue with `Truncator::truncateWords` and `Truncator::truncateLetters` when string not wrapped in tags [#2432](https://github.com/getgrav/grav/issues/2432)
* Fixed `Undefined method closure::fields()` when getting avatar for user, thanks @Romarain [#2422](https://github.com/getgrav/grav/issues/2422)
* Fixed cached images not being updated when source image is modified
* Fixed deleting last list item in the form
* Fixed issue with `Utils::url()` method would append extra `base_url` if URL already included it
* Fixed `mkdir(...)` race condition
* Fixed `Obtaining write lock failed on file...`
* Fixed potential undefined property in `onPageNotFound` event handling
* Fixed some potential issues/bugs found by phpstan
* Fixed regression in GPM packages casted to Array (ref, getgrav/grav-plugin-admin@e3fc4ce)
* Fixed session_start(): Setting option 'session.name' failed [#2408](https://github.com/getgrav/grav/issues/2408)
* Fixed validation for select field type with selectize
* Fixed validation for boolean toggles
* Fixed non-namespaced exceptions in scheduler
* Fixed trailing slash redirect in multlang environment [#2350](https://github.com/getgrav/grav/issues/2350)
* Fixed some issues related to Medium objects losing query string attributes
* Broke out Medium timestamp so it's not cleared on `reset()`s
* Fixed issue with `redirect_trailing_slash` losing query string [#2269](https://github.com/getgrav/grav/issues/2269)
* Fixed failed login if user attempts to log in with upper case non-english letters
* Removed extra authenticated/authorized fields when saving existing user from a form
* Fixed `Grav\Framework\Route::__toString()` returning relative URL, not relative route
* Fixed handling of `append_url_extension` inside of `Page::templateFormat()` [#2264](https://github.com/getgrav/grav/issues/2264)
* Fixed a broken language string [#2261](https://github.com/getgrav/grav/issues/2261)
* Fixed clearing cache having no effect on Doctrine cache
* Fixed `Medium::relativePath()` for streams
* Fixed `Object` serialization breaking if overriding `jsonSerialize()` method
* Fixed `YamlFormatter::decode()` when calling `init_set()` with integer
* Fixed session throwing error in CLI if initialized
* Fixed `Uri::hasStandardPort()` to support reverse proxy configurations [#1786](https://github.com/getgrav/grav/issues/1786)
* Use `append_url_extension` from page header to set template format if set [#2604](https://github.com/getgrav/grav/pull/2064)
* Fixed some bugs in Grav environment selection logic
* Use login provider User avatar if set
* Fixed `Folder::doDelete($folder, false)` removing symlink when it should not
* Fixed asset manager to not add empty assets when they don't exist in the filesystem
* Update `script` and `style` Twig tags to use the new `Assets` classes
* Fixed asset pipeline to rewrite remote URLs as well as local [#2216](https://github.com/getgrav/grav/issues/2216)
# v1.5.10
## 03/21/2019
1. [](#new)
* Added new `deferred` Twig extension
# v1.5.9
## 03/20/2019
1. [](#new)
* Added new `onPageContent()` event for every call to `Page::content()`
1. [](#improved)
* Fixed phpdoc generation
* Updated vendor libraries
* Force Toolbox v1.4.2
1. [](#bugfix)
* EXIF fix for streams
* Fix for User avatar not working due to uppercase or spaces in email [#2403](https://github.com/getgrav/grav/pull/2403)
# v1.5.8 # v1.5.8
## 02/07/2019 ## 02/07/2019
@@ -16,7 +388,7 @@
* Updated vendor libraries * Updated vendor libraries
1. [](#bugfix) 1. [](#bugfix)
* Support spaces with filenames in responsive images [#2300](https://github.com/getgrav/grav/pull/2300) * Support spaces with filenames in responsive images [#2300](https://github.com/getgrav/grav/pull/2300)
# v1.5.6 # v1.5.6
## 12/14/2018 ## 12/14/2018
+3 -2
View File
@@ -29,7 +29,7 @@ The issue tracker is the preferred channel for [bug reports](#bugs),
requests](#pull-requests), but please respect the following restrictions: requests](#pull-requests), but please respect the following restrictions:
* Please **do not** use the issue tracker for support requests. Use * Please **do not** use the issue tracker for support requests. Use
[the Forum](http://getgrav.org/forum) or [the Gitter chat](https://gitter.im/getgrav/grav). [the Forum](http://getgrav.org/forum) or [the Chat](https://chat.getgrav.org/).
<a name="bugs"></a> <a name="bugs"></a>
@@ -110,7 +110,8 @@ Good pull requests - patches, improvements, new features - are a fantastic
help. They should remain focused in scope and avoid containing unrelated help. They should remain focused in scope and avoid containing unrelated
commits. commits.
**Please ask first** in [Slack](https://getgrav.org/slack) or in the Forum before embarking on any significant pull request (e.g. **Please ask first** in [the Forum](http://getgrav.org/forum) or [the Chat](https://chat.getgrav.org/)
before embarking on any significant pull request (e.g.
implementing features, refactoring code..), implementing features, refactoring code..),
otherwise you risk spending a lot of time working on something that the otherwise you risk spending a lot of time working on something that the
project's developers might not want to merge into the project. project's developers might not want to merge into the project.
+14 -10
View File
@@ -1,24 +1,27 @@
# ![](https://avatars1.githubusercontent.com/u/8237355?v=2&s=50) Grav # ![](https://avatars1.githubusercontent.com/u/8237355?v=2&s=50) Grav
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad/mini.png)](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad) [![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org) [![Build Status](https://travis-ci.org/getgrav/grav.svg?branch=develop)](https://travis-ci.org/getgrav/grav) [![OpenCollective](https://opencollective.com/grav/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/grav/sponsors/badge.svg)](#sponsors) [![PHPStan](https://img.shields.io/badge/PHPStan-enabled-brightgreen.svg?style=flat)](https://github.com/phpstan/phpstan)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad/mini.png)](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad)
[![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org)
[![Build Status](https://travis-ci.org/getgrav/grav.svg?branch=develop)](https://travis-ci.org/getgrav/grav) [![OpenCollective](https://opencollective.com/grav/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/grav/sponsors/badge.svg)](#sponsors)
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself. Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include: The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface * [Twig Templating](https://twig.sensiolabs.org/): for powerful control of the user interface
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation * [Markdown](https://en.wikipedia.org/wiki/Markdown): for easy content creation
* [YAML](http://yaml.org): for simple configuration * [YAML](https://yaml.org): for simple configuration
* [Parsedown](http://parsedown.org/): for fast Markdown and Markdown Extra support * [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support
* [Doctrine Cache](http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance * [Doctrine Cache](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability * [Pimple Dependency Injection Container](https://pimple.sensiolabs.org/): for extensibility and maintainability
* [Symfony Event Dispatcher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling * [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface * [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation * [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
# Requirements # Requirements
- PHP 5.6.4 or higher. Check the [required modules list](https://learn.getgrav.org/basics/requirements#php-requirements) - PHP 7.1.3 or higher. Check the [required modules list](https://learn.getgrav.org/basics/requirements#php-requirements)
- Check the [Apache](https://learn.getgrav.org/basics/requirements#apache-requirements) or [IIS](https://learn.getgrav.org/basics/requirements#iis-requirements) requirements - Check the [Apache](https://learn.getgrav.org/basics/requirements#apache-requirements) or [IIS](https://learn.getgrav.org/basics/requirements#iis-requirements) requirements
# QuickStart # QuickStart
@@ -103,6 +106,7 @@ If you discover a possible security issue related to Grav or one of its plugins,
* Dive into more [advanced](https://learn.getgrav.org/advanced) functions * Dive into more [advanced](https://learn.getgrav.org/advanced) functions
* Learn about the [Grav CLI](https://learn.getgrav.org/cli-console/grav-cli) * Learn about the [Grav CLI](https://learn.getgrav.org/cli-console/grav-cli)
* Review examples in the [Grav Cookbook](https://learn.getgrav.org/cookbook) * Review examples in the [Grav Cookbook](https://learn.getgrav.org/cookbook)
* More [Awesome Grav Stuff](https://github.com/getgrav/awesome-grav)
# Backers # Backers
Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)] Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)]
BIN
View File
Binary file not shown.
+15 -16
View File
@@ -1,26 +1,24 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
define('GRAV_CLI', true);
if (!file_exists(__DIR__ . '/../vendor')){
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
use Grav\Common\Composer; use Grav\Common\Composer;
use Grav\Common\Config\Setup; use Symfony\Component\Console\Application;
use Grav\Common\Grav;
if (!file_exists(__DIR__ . '/../vendor')){ \define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
// Before we can even start, we need to run composer first // Before we can even start, we need to run composer first
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
$composer = Composer::getComposerExecutor(); $composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n"; echo "Preparing to install vendor dependencies...\n\n";
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install'); echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n"; echo "\n\n";
} }
use Symfony\Component\Console\Application; $autoload = require __DIR__ . '/../vendor/autoload.php';
use Grav\Common\Grav;
$autoload = require_once(__DIR__ . '/../vendor/autoload.php');
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) { if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req)); exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
@@ -30,7 +28,7 @@ if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
} }
if (!file_exists(ROOT_DIR . 'index.php')) { if (!file_exists(GRAV_ROOT . '/index.php')) {
exit('FATAL: Must be run from ROOT directory of Grav!'); exit('FATAL: Must be run from ROOT directory of Grav!');
} }
@@ -48,15 +46,16 @@ $climate->arguments->add([
] ]
]); ]);
$climate->arguments->parse(); $climate->arguments->parse();
$environment = $climate->arguments->get('environment');
// Set up environment based on params. // Set up environment based on params.
Setup::$environment = $environment; $environment = $climate->arguments->get('environment');
$grav = Grav::instance(array('loader' => $autoload)); $grav = Grav::instance(array('loader' => $autoload));
$grav['uri']->init(); $grav->setup($environment);
$grav['config']->init(); $grav['config']->init();
$grav['streams']; $grav['uri']->init();
$grav['users'];
$app = new Application('Grav Package Manager', GRAV_VERSION); $app = new Application('Grav Package Manager', GRAV_VERSION);
$app->addCommands(array( $app->addCommands(array(
+31 -10
View File
@@ -1,34 +1,52 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
define('GRAV_CLI', true);
if (!file_exists(__DIR__ . '/../vendor')){
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
use Grav\Common\Composer; use Grav\Common\Composer;
use Grav\Common\Grav;
use League\CLImate\CLImate;
use Symfony\Component\Console\Application;
if (!file_exists(__DIR__ . '/../vendor')){ \define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
// Before we can even start, we need to run composer first // Before we can even start, we need to run composer first
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
$composer = Composer::getComposerExecutor(); $composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n"; echo "Preparing to install vendor dependencies...\n\n";
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install'); echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n"; echo "\n\n";
} }
use Symfony\Component\Console\Application; $autoload = require __DIR__ . '/../vendor/autoload.php';
require_once __DIR__ . '/../vendor/autoload.php';
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) { if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req)); exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
} }
$climate = new League\CLImate\CLImate;
$climate->arguments->add([
'environment' => [
'prefix' => 'e',
'longPrefix' => 'env',
'description' => 'Configuration Environment',
'defaultValue' => 'localhost'
]
]);
$climate->arguments->parse();
// Set up environment based on params.
$environment = $climate->arguments->get('environment');
$grav = Grav::instance(array('loader' => $autoload));
$grav->setup($environment);
if (!ini_get('date.timezone')) { if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
} }
if (!file_exists(ROOT_DIR . 'index.php')) { if (!file_exists(GRAV_ROOT . '/index.php')) {
exit('FATAL: Must be run from ROOT directory of Grav!'); exit('FATAL: Must be run from ROOT directory of Grav!');
} }
@@ -41,6 +59,9 @@ $app->addCommands(array(
new \Grav\Console\Cli\ClearCacheCommand(), new \Grav\Console\Cli\ClearCacheCommand(),
new \Grav\Console\Cli\BackupCommand(), new \Grav\Console\Cli\BackupCommand(),
new \Grav\Console\Cli\NewProjectCommand(), new \Grav\Console\Cli\NewProjectCommand(),
new \Grav\Console\Cli\SchedulerCommand(),
new \Grav\Console\Cli\SecurityCommand(), new \Grav\Console\Cli\SecurityCommand(),
new \Grav\Console\Cli\LogViewerCommand(),
new \Grav\Console\Cli\YamlLinterCommand(),
)); ));
$app->run(); $app->run();
+41 -28
View File
@@ -1,30 +1,28 @@
#!/usr/bin/env php #!/usr/bin/env php
<?php <?php
define('GRAV_CLI', true);
if (!file_exists(__DIR__ . '/../vendor')) {
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
}
use Grav\Common\Composer; use Grav\Common\Composer;
if (!file_exists(__DIR__ . '/../vendor')) {
// Before we can even start, we need to run composer first
$composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n";
echo system($composer . ' --working-dir="' . __DIR__ . '/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n";
}
use Symfony\Component\Console\Application; use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Formatter\OutputFormatterStyle;
use Grav\Common\Grav; use Grav\Common\Grav;
use Grav\Common\Config\Setup;
use Grav\Common\Filesystem\Folder; use Grav\Common\Filesystem\Folder;
$autoload = require_once(__DIR__ . '/../vendor/autoload.php'); \define('GRAV_CLI', true);
\define('GRAV_REQUEST_TIME', microtime(true));
if (!file_exists(__DIR__ . '/../vendor/autoload.php')){
// Before we can even start, we need to run composer first
require_once __DIR__ . '/../system/src/Grav/Common/Composer.php';
$composer = Composer::getComposerExecutor();
echo "Preparing to install vendor dependencies...\n\n";
echo system($composer.' --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install');
echo "\n\n";
}
$autoload = require __DIR__ . '/../vendor/autoload.php';
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) { if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req)); exit(sprintf("You are running PHP %s, but Grav needs at least PHP %s to run.\n", $ver, $req));
@@ -34,7 +32,7 @@ if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
} }
if (!file_exists(ROOT_DIR . 'index.php')) { if (!file_exists(GRAV_ROOT . '/index.php')) {
exit('FATAL: Must be run from ROOT directory of Grav!'); exit('FATAL: Must be run from ROOT directory of Grav!');
} }
@@ -48,19 +46,18 @@ $climate->arguments->add([
] ]
]); ]);
$climate->arguments->parse(); $climate->arguments->parse();
$environment = $climate->arguments->get('environment'); $environment = $climate->arguments->get('environment');
// Set up environment based on params.
Setup::$environment = $environment;
$grav = Grav::instance(array('loader' => $autoload)); $grav = Grav::instance(array('loader' => $autoload));
$grav['uri']->init(); $grav->setup($environment);
$grav['config']->init(); $grav['config']->init();
$grav['streams']; $grav['uri']->init();
$grav['users'];
$grav['plugins']->init(); $grav['plugins']->init();
$grav['themes']->init(); $grav['themes']->init();
$app = new Application('Grav Plugins Commands', GRAV_VERSION); $app = new Application('Grav Plugins Commands', GRAV_VERSION);
$pattern = '([A-Z]\w+Command\.php)'; $pattern = '([A-Z]\w+Command\.php)';
@@ -75,6 +72,7 @@ $argv = array_merge([$bin], $argv);
$input = new ArgvInput($argv); $input = new ArgvInput($argv);
/** @var \Grav\Common\Data\Data $plugin */
$plugin = $grav['plugins']->get($name); $plugin = $grav['plugins']->get($name);
$output = new ConsoleOutput(); $output = new ConsoleOutput();
@@ -83,13 +81,14 @@ $output->getFormatter()->setStyle('white', new OutputFormatterStyle('white', nul
if (!$name) { if (!$name) {
$output->writeln(''); $output->writeln('');
$output->writeln("<red>Usage:</red>"); $output->writeln('<red>Usage:</red>');
$output->writeln(" {$bin} [slug] [command] [arguments]"); $output->writeln(" {$bin} [slug] [command] [arguments]");
$output->writeln(''); $output->writeln('');
$output->writeln("<red>Example:</red>"); $output->writeln('<red>Example:</red>');
$output->writeln(" {$bin} error log -l 1 --trace"); $output->writeln(" {$bin} error log -l 1 --trace");
$list = Folder::all('plugins://', ['compare' => 'Pathname', 'pattern' => '/\/cli\/' . $pattern . '$/usm', 'levels' => 2]); $list = Folder::all('plugins://', ['compare' => 'Pathname', 'pattern' => '/\/cli\/' . $pattern . '$/usm', 'levels' => 2]);
$total = 0;
if (count($list)) { if (count($list)) {
$available = []; $available = [];
$output->writeln(''); $output->writeln('');
@@ -98,17 +97,31 @@ if (!$name) {
$split = explode('/', $entry); $split = explode('/', $entry);
$entry = array_shift($split); $entry = array_shift($split);
$index = str_pad($index++ + 1, 2, '0', STR_PAD_LEFT); $index = str_pad($index++ + 1, 2, '0', STR_PAD_LEFT);
$total = str_pad($total++ + 1, 2, '0', STR_PAD_LEFT);
if (in_array($entry, $available)) { if (\in_array($entry, $available, true)) {
$total--;
continue; continue;
} }
$available[] = $entry; $available[] = $entry;
$output->writeln(' ' . $index . ". <red>" . str_pad($entry, 15) . "</red> <white>${bin} ${entry} list</white>"); $commands_count = $index - $total + 1;
$output->writeln(' ' . $total . '. <red>' . str_pad($entry, 15) . "</red> <white>{$bin} {$entry} list</white>");
} }
} }
exit; exit;
} else {
if (is_null($plugin)) {
$output->writeln('');
$output->writeln("<red>$name plugin not found</red>");
die;
}
if (!$plugin->enabled) {
$output->writeln('');
$output->writeln("<red>$name not enabled</red>");
die;
}
} }
if ($plugin === null) { if ($plugin === null) {
+59 -30
View File
@@ -6,47 +6,71 @@
"homepage": "https://getgrav.org", "homepage": "https://getgrav.org",
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": ">=5.6.4", "php": ">=7.1.3",
"twig/twig": "~1.24", "ext-json": "*",
"erusev/parsedown": "1.6.4",
"erusev/parsedown-extra": "~0.7",
"symfony/yaml": "~3.4",
"symfony/console": "~3.4",
"symfony/event-dispatcher": "~3.4",
"symfony/var-dumper": "~3.4",
"symfony/polyfill-iconv": "~1.0",
"doctrine/cache": "^1.6",
"doctrine/collections": "^1.4",
"psr/simple-cache": "^1.0",
"psr/http-message": "^1.0",
"guzzlehttp/psr7": "^1.4",
"filp/whoops": "~2.0",
"matthiasmullie/minify": "^1.3",
"monolog/monolog": "~1.0",
"gregwar/image": "2.*",
"donatj/phpuseragentparser": "~0.3",
"pimple/pimple": "~3.2",
"rockettheme/toolbox": "~1.4",
"maximebf/debugbar": "~1.10",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-zip": "*", "ext-zip": "*",
"ext-json": "*", "ext-dom": "*",
"league/climate": "^3.2", "symfony/polyfill-iconv": "^1.9",
"symfony/polyfill-php72": "^1.9",
"symfony/polyfill-php73": "^1.9",
"psr/simple-cache": "^1.0",
"psr/http-message": "^1.0",
"psr/http-server-middleware": "^1.0",
"kodus/psr7-server": "*",
"nyholm/psr7": "^1.0",
"twig/twig": "~1.40",
"erusev/parsedown": "1.6.4",
"erusev/parsedown-extra": "~0.7",
"symfony/yaml": "~4.2.0",
"symfony/console": "~4.2.0",
"symfony/event-dispatcher": "~4.2.0",
"symfony/var-dumper": "~4.2.0",
"symfony/process": "~4.2.0",
"doctrine/cache": "^1.8",
"doctrine/collections": "^1.5",
"guzzlehttp/psr7": "^1.4",
"filp/whoops": "~2.2",
"matthiasmullie/minify": "^1.3",
"monolog/monolog": "~1.0",
"gregwar/image": "2.*",
"donatj/phpuseragentparser": "~0.10",
"pimple/pimple": "~3.2",
"rockettheme/toolbox": "~1.4",
"maximebf/debugbar": "~1.15",
"league/climate": "^3.4",
"antoligy/dom-string-iterators": "^1.0", "antoligy/dom-string-iterators": "^1.0",
"miljar/php-exif": "^0.6.3", "miljar/php-exif": "^0.6.4",
"composer/ca-bundle": "^1.0" "composer/ca-bundle": "^1.0",
"dragonmantank/cron-expression": "^1.2",
"phive/twig-extensions-deferred": "^1.0",
"willdurand/negotiation": "^2.3"
}, },
"require-dev": { "require-dev": {
"codeception/codeception": "^2.1", "codeception/codeception": "^2.4",
"phpunit/php-code-coverage": "~2.0", "phpstan/phpstan": "^0.11",
"fzaninotto/faker": "^1.5", "phpstan/phpstan-deprecation-rules": "^0.11.0",
"phpunit/php-code-coverage": "~6.0",
"fzaninotto/faker": "^1.8",
"victorjonsson/markdowndocs": "dev-master" "victorjonsson/markdowndocs": "dev-master"
}, },
"suggest": {
"ext-zend-opcache": "Recommended for better performance",
"ext-intl": "Recommended for multi-language sites",
"ext-memcache": "Needed to support Memcache servers",
"ext-memcached": "Needed to support Memcached servers",
"ext-redis": "Needed to support Redis servers"
},
"config": { "config": {
"apcu-autoloader": true,
"platform": { "platform": {
"php": "5.6.4" "php": "7.1.3"
} }
}, },
"repositories": [ "repositories": [
@@ -65,7 +89,12 @@
"exclude": ["VERSION"] "exclude": ["VERSION"]
}, },
"scripts": { "scripts": {
"api-16": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.16.md",
"api-15": "vendor/bin/phpdoc-md generate system/src > user/pages/14.api/default.md",
"post-create-project-cmd": "bin/grav install", "post-create-project-cmd": "bin/grav install",
"phpstan": "vendor/bin/phpstan analyse -l 2 -c ./tests/phpstan/phpstan.neon system/src --memory-limit=256M",
"phpstan-framework": "vendor/bin/phpstan analyse -l 5 -c ./tests/phpstan/phpstan.neon system/src/Grav/Framework --memory-limit=256M",
"test-plugins": "vendor/bin/phpstan analyse -l 0 -c ./tests/phpstan/plugins.neon user/plugins --memory-limit=256M",
"test": "vendor/bin/codecept run unit", "test": "vendor/bin/codecept run unit",
"test-windows": "vendor\\bin\\codecept run unit" "test-windows": "vendor\\bin\\codecept run unit"
}, },
Generated
+2324 -416
View File
File diff suppressed because it is too large Load Diff
-8
View File
@@ -1,8 +0,0 @@
#!/bin/sh
chgrp www-data .
chgrp -R www-data *
sh -c "find . -type f | xargs chmod 664"
sh -c "find ./bin -type f | xargs chmod 775"
sh -c "find . -type d | xargs chmod 775"
sh -c "find . -type d | xargs chmod +s"
sh -c "umask 0002"
+19 -17
View File
@@ -9,35 +9,34 @@
namespace Grav; namespace Grav;
define('GRAV_PHP_MIN', '5.6.4'); \define('GRAV_REQUEST_TIME', microtime(true));
\define('GRAV_PHP_MIN', '7.1.3');
// Ensure vendor libraries exist
$autoload = __DIR__ . '/vendor/autoload.php';
if (!is_file($autoload)) {
die("Please run: <i>bin/grav install</i>");
}
if (PHP_SAPI === 'cli-server') {
if (!isset($_SERVER['PHP_CLI_ROUTER'])) {
die("PHP webserver requires a router to run Grav, please use: <pre>php -S {$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']} system/router.php</pre>");
}
}
use Grav\Common\Grav;
use RocketTheme\Toolbox\Event\Event;
if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) { if (version_compare($ver = PHP_VERSION, $req = GRAV_PHP_MIN, '<')) {
die(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req)); die(sprintf('You are running PHP %s, but Grav needs at least <strong>PHP %s</strong> to run.', $ver, $req));
} }
if (PHP_SAPI === 'cli-server' && !isset($_SERVER['PHP_CLI_ROUTER'])) {
die("PHP webserver requires a router to run Grav, please use: <pre>php -S {$_SERVER['SERVER_NAME']}:{$_SERVER['SERVER_PORT']} system/router.php</pre>");
}
// Ensure vendor libraries exist
$autoload = __DIR__ . '/vendor/autoload.php';
if (!is_file($autoload)) {
die('Please run: <i>bin/grav install</i>');
}
// Register the auto-loader. // Register the auto-loader.
$loader = require $autoload; $loader = require $autoload;
use Grav\Common\Grav;
use RocketTheme\Toolbox\Event\Event;
// Set timezone to default, falls back to system if php.ini not set // Set timezone to default, falls back to system if php.ini not set
date_default_timezone_set(@date_default_timezone_get()); date_default_timezone_set(@date_default_timezone_get());
// Set internal encoding if mbstring loaded // Set internal encoding if mbstring loaded
if (!extension_loaded('mbstring')) { if (!\extension_loaded('mbstring')) {
die("'mbstring' extension is not loaded. This is required for Grav to run correctly"); die("'mbstring' extension is not loaded. This is required for Grav to run correctly");
} }
mb_internal_encoding('UTF-8'); mb_internal_encoding('UTF-8');
@@ -52,6 +51,9 @@ $grav = Grav::instance(
// Process the page // Process the page
try { try {
$grav->process(); $grav->process();
} catch (\Error $e) {
$grav->fireEvent('onFatalException', new Event(array('exception' => $e)));
throw $e;
} catch (\Exception $e) { } catch (\Exception $e) {
$grav->fireEvent('onFatalException', new Event(array('exception' => $e))); $grav->fireEvent('onFatalException', new Event(array('exception' => $e)));
throw $e; throw $e;
+4
View File
@@ -0,0 +1,4 @@
{
"version": 2,
"builds": [{ "src": "*.php", "use": "@now/php" }]
}
+1
View File
@@ -10,3 +10,4 @@ Disallow: /user/
Allow: /user/pages/ Allow: /user/pages/
Allow: /user/themes/ Allow: /user/themes/
Allow: /user/images/ Allow: /user/images/
Allow: /
+16
View File
@@ -30,9 +30,25 @@ div.phpdebugbar {
} }
.phpdebugbar .phpdebugbar-widgets-toolbar { .phpdebugbar .phpdebugbar-widgets-toolbar {
border-top: 1px solid #ddd;
padding-left: 5px; padding-left: 5px;
padding-right: 2px;
padding-top: 2px;
background-color: #fafafa !important;
width: auto !important;
left: 0;
right: 0;
} }
.phpdebugbar .phpdebugbar-widgets-toolbar input {
background: transparent !important;
}
.phpdebugbar .phpdebugbar-widgets-toolbar .phpdebugbar-widgets-filter {
}
.phpdebugbar input[type=text] { .phpdebugbar input[type=text] {
padding: 0; padding: 0;
display: inline; display: inline;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 548 B

After

Width:  |  Height:  |  Size: 4.1 KiB

+125
View File
@@ -0,0 +1,125 @@
title: PLUGIN_ADMIN.BACKUPS
form:
validation: loose
fields:
history_title:
type: section
title: PLUGIN_ADMIN.BACKUPS_HISTORY
underline: true
history:
type: backupshistory
config_title:
type: section
title: PLUGIN_ADMIN.BACKUPS_PURGE_CONFIG
underline: true
purge.trigger:
type: select
label: PLUGIN_ADMIN.BACKUPS_STORAGE_PURGE_TRIGGER
size: medium
default: space
options:
space: Maximum Backup Space
number: Maximum Number of Backups
time: maximum Retention Time
validate:
required: true
purge.max_backups_count:
type: number
label: PLUGIN_ADMIN.BACKUPS_MAX_COUNT
default: 25
size: x-small
help: PLUGIN_ADMIN.BACKUPS_MAX_COUNT
validate:
min: 0
type: number
required: true
message: Must be a number 0 or greater
purge.max_backups_space:
type: number
label: PLUGIN_ADMIN.BACKUPS_MAX_SPACE
append: in GB
size: x-small
default: 5
validate:
min: 1
type: number
required: true
message: Space must be 1GB or greater
purge.max_backups_time:
type: number
label: PLUGIN_ADMIN.BACKUPS_MAX_RETENTION_TIME
append: PLUGIN_ADMIN.BACKUPS_MAX_RETENTION_TIME_APPEND
size: x-small
default: 365
validate:
min: 7
type: number
required: true
message: Rentenion days must be 7 or greater
profiles_title:
type: section
title: PLUGIN_ADMIN.BACKUPS_PROFILES
underline: true
profiles:
type: list
style: vertical
label:
classes: backups-list compact
sort: false
fields:
.name:
type: text
label: PLUGIN_ADMIN.NAME
placeholder: PLUGIN_ADMIN.BACKUPS_PROFILE_NAME
validate:
max: 20
message: 'Name must be less than 20 characters'
required: true
.root:
type: text
label: PLUGIN_ADMIN.BACKUPS_PROFILE_ROOT_FOLDER
help: PLUGIN_ADMIN.BACKUPS_PROFILE_ROOT_FOLDER_HELP
placeholder: '/'
default: '/'
validate:
required: true
.exclude_paths:
type: textarea
label: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_PATHS
rows: 5
placeholder: "/backup\r/cache\r/images\r/logs\r/tmp"
help: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_PATHS_HELP
.exclude_files:
type: textarea
label: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_FILES
rows: 5
placeholder: ".DS_Store\r.git\r.svn\r.hg\r.idea\r.vscode\rnode_modules"
help: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_FILES_HELP
.schedule:
type: toggle
label: PLUGIN_ADMIN.BACKUPS_PROFILE_SCHEDULE
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
.schedule_at:
type: cron
label: PLUGIN_ADMIN.BACKUPS_PROFILE_SCHEDULE_AT
default: '* 3 * * *'
validate:
required: true
+76
View File
@@ -0,0 +1,76 @@
title: PLUGIN_ADMIN.SCHEDULER
form:
validation: loose
fields:
status_title:
type: section
title: PLUGIN_ADMIN.SCHEDULER_STATUS
underline: true
status:
type: cronstatus
validate:
type: commalist
jobs_title:
type: section
title: PLUGIN_ADMIN.SCHEDULER_JOBS
underline: true
custom_jobs:
type: list
style: vertical
label:
classes: cron-job-list compact
key: id
fields:
.id:
type: key
label: ID
placeholder: 'process-name'
validate:
required: true
pattern: '[a-zа-я0-9_\-]+'
max: 20
message: 'ID must be lowercase with dashes/underscores only and less than 20 characters'
.command:
type: text
label: PLUGIN_ADMIN.COMMAND
placeholder: 'cd ~;ls -lah;'
validate:
required: true
.args:
type: text
label: PLUGIN_ADMIN.EXTRA_ARGUMENTS
.at:
type: cron
label: PLUGIN_ADMIN.SCHEDULER_RUNAT
help: PLUGIN_ADMIN.SCHEDULER_RUNAT_HELP
placeholder: '* * * * *'
validate:
required: true
.output:
type: text
label: PLUGIN_ADMIN.SCHEDULER_OUTPUT
help: PLUGIN_ADMIN.SCHEDULER_OUTPUT_HELP
placeholder: 'logs/ls-cron.out'
.output_mode:
type: select
label: PLUGIN_ADMIN.SCHEDULER_OUTPUT_TYPE
help: PLUGIN_ADMIN.SCHEDULER_OUTPUT_TYPE_HELP
default: append
options:
append: Append
overwrite: Overwrite
.email:
type: text
label: PLUGIN_ADMIN.SCHEDULER_EMAIL
help: PLUGIN_ADMIN.SCHEDULER_EMAIL_HELP
placeholder: 'notifications@yoursite.com'
+8
View File
@@ -41,6 +41,14 @@ form:
validate: validate:
type: bool type: bool
xss_invalid_protocols:
type: selectize
size: large
label: PLUGIN_ADMIN.XSS_INVALID_PROTOCOLS_LIST
classes: fancy
validate:
type: commalist
xss_enabled.moz_binding: xss_enabled.moz_binding:
type: toggle type: toggle
label: PLUGIN_ADMIN.XSS_MOZ_BINDINGS label: PLUGIN_ADMIN.XSS_MOZ_BINDINGS
+1 -1
View File
@@ -65,7 +65,7 @@ form:
summary.size: summary.size:
type: text type: text
size: x-small size: small
append: PLUGIN_ADMIN.CHARACTERS append: PLUGIN_ADMIN.CHARACTERS
label: PLUGIN_ADMIN.SUMMARY_SIZE label: PLUGIN_ADMIN.SUMMARY_SIZE
help: PLUGIN_ADMIN.SUMMARY_SIZE_HELP help: PLUGIN_ADMIN.SUMMARY_SIZE_HELP
File diff suppressed because it is too large Load Diff
+103 -101
View File
@@ -4,122 +4,124 @@ form:
fields: fields:
info: info:
type: userinfo type: userinfo
size: large size: large
avatar: avatar:
type: file type: file
size: large size: large
destination: 'user://accounts/avatars' destination: 'user://accounts/avatars'
multiple: false multiple: false
random_name: true random_name: true
content: content:
type: section type: section
title: PLUGIN_ADMIN.ACCOUNT title: PLUGIN_ADMIN.ACCOUNT
underline: true underline: true
username: username:
type: text type: text
size: large size: large
label: PLUGIN_ADMIN.USERNAME label: PLUGIN_ADMIN.USERNAME
disabled: true disabled: true
readonly: true readonly: true
email: email:
type: email type: email
size: large size: large
label: PLUGIN_ADMIN.EMAIL label: PLUGIN_ADMIN.EMAIL
validate: validate:
type: email type: email
message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE message: PLUGIN_ADMIN.EMAIL_VALIDATION_MESSAGE
required: true required: true
password: password:
type: password type: password
size: large size: large
label: PLUGIN_ADMIN.PASSWORD label: PLUGIN_ADMIN.PASSWORD
autocomplete: new-password autocomplete: new-password
validate: validate:
required: false required: false
message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE message: PLUGIN_ADMIN.PASSWORD_VALIDATION_MESSAGE
config-pattern@: system.pwd_regex config-pattern@: system.pwd_regex
fullname: fullname:
type: text type: text
size: large size: large
label: PLUGIN_ADMIN.FULL_NAME label: PLUGIN_ADMIN.FULL_NAME
validate: validate:
required: true required: true
title: title:
type: text type: text
size: large size: large
label: PLUGIN_ADMIN.TITLE label: PLUGIN_ADMIN.TITLE
language: language:
type: select type: select
label: PLUGIN_ADMIN.LANGUAGE label: PLUGIN_ADMIN.LANGUAGE
size: medium size: medium
classes: fancy classes: fancy
data-options@: '\Grav\Plugin\Admin\Admin::adminLanguages' data-options@: '\Grav\Plugin\Admin\Admin::adminLanguages'
default: 'en' default: 'en'
help: PLUGIN_ADMIN.LANGUAGE_HELP help: PLUGIN_ADMIN.LANGUAGE_HELP
twofa_check: twofa_check:
type: conditional type: conditional
condition: config.plugins.admin.twofa_enabled condition: config.plugins.admin.twofa_enabled
fields: fields:
twofa: twofa:
title: PLUGIN_ADMIN.2FA_TITLE title: PLUGIN_ADMIN.2FA_TITLE
type: section type: section
underline: true underline: true
twofa_enabled: twofa_enabled:
type: toggle type: toggle
label: PLUGIN_ADMIN.2FA_ENABLED label: PLUGIN_ADMIN.2FA_ENABLED
classes: twofa-toggle classes: twofa-toggle
highlight: 1 highlight: 1
default: 0 default: 0
options: options:
1: PLUGIN_ADMIN.YES 1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO 0: PLUGIN_ADMIN.NO
validate: validate:
type: bool type: bool
twofa_secret: twofa_secret:
type: 2fa_secret type: 2fa_secret
outerclasses: 'twofa-secret' outerclasses: 'twofa-secret'
markdown: true markdown: true
label: PLUGIN_ADMIN.2FA_SECRET label: PLUGIN_ADMIN.2FA_SECRET
sublabel: PLUGIN_ADMIN.2FA_SECRET_HELP sublabel: PLUGIN_ADMIN.2FA_SECRET_HELP
security: security:
title: PLUGIN_ADMIN.ACCESS_LEVELS security@: admin.super
type: section title: PLUGIN_ADMIN.ACCESS_LEVELS
security: admin.super type: section
underline: true underline: true
fields: fields:
groups: groups:
type: select security@: admin.super
multiple: true type: select
size: large multiple: true
label: PLUGIN_ADMIN.GROUPS size: large
data-options@: '\Grav\Common\User\Group::groupNames' label: PLUGIN_ADMIN.GROUPS
classes: fancy data-options@: '\Grav\Common\User\Group::groupNames'
help: PLUGIN_ADMIN.GROUPS_HELP classes: fancy
validate: help: PLUGIN_ADMIN.GROUPS_HELP
type: commalist validate:
type: commalist
access: access:
type: permissions security@: admin.super
label: PLUGIN_ADMIN.PERMISSIONS type: permissions
ignore_empty: true label: PLUGIN_ADMIN.PERMISSIONS
validate: ignore_empty: true
type: array validate:
type: array
+2
View File
@@ -12,5 +12,7 @@ form:
type: text type: text
label: PLUGIN_ADMIN.USERNAME label: PLUGIN_ADMIN.USERNAME
help: PLUGIN_ADMIN.USERNAME_HELP help: PLUGIN_ADMIN.USERNAME_HELP
unset-disabled@: true
unset-readonly@: true
validate: validate:
required: true required: true
+39
View File
@@ -0,0 +1,39 @@
title: User Accounts
description: User Accounts
type: flex-objects
extends@: 'user/account'
config:
admin:
list:
fields:
username:
link: edit
search: true
email:
search: true
fullname:
search: true
options:
per_page: 20
order:
by: username
dir: asc
menu:
list:
route: '/accounts'
title: Accounts
icon: fa-users
authorize: ['admin.users', 'admin.accounts', 'admin.super']
form:
fields:
username:
flex-disabled@: exists
disabled: false
flex-readonly@: exists
readonly: false
validate:
required: true
+15
View File
@@ -0,0 +1,15 @@
purge:
trigger: space
max_backups_count: 25
max_backups_space: 5
max_backups_time: 365
profiles:
-
name: 'Default Site Backup'
root: '/'
schedule: false
schedule_at: '0 3 * * *'
exclude_paths: "/backup\r\n/cache\r\n/images\r\n/logs\r\n/tmp"
exclude_files: ".DS_Store\r\n.git\r\n.svn\r\n.hg\r\n.idea\r\n.vscode\r\nnode_modules"
+7
View File
@@ -5,6 +5,13 @@ xss_enabled:
moz_binding: true moz_binding: true
html_inline_styles: true html_inline_styles: true
dangerous_tags: true dangerous_tags: true
xss_invalid_protocols:
- javascript
- livescript
- vbscript
- mocha
- feed
- data
xss_dangerous_tags: xss_dangerous_tags:
- applet - applet
- meta - meta
+5 -5
View File
@@ -17,17 +17,17 @@ summary:
delimiter: === # The summary delimiter delimiter: === # The summary delimiter
redirects: redirects:
# '/redirect-test': '/' # Redirect test goes to home page # '/redirect-test': '/' # Redirect test goes to home page
# '/old/(.*)': '/new/$1' # Would redirect /old/my-page to /new/my-page # '/old/(.*)': '/new/$1' # Would redirect /old/my-page to /new/my-page
routes: routes:
# '/something/else': '/blog/sample-3' # Alias for /blog/sample-3 # '/something/else': '/blog/sample-3' # Alias for /blog/sample-3
# '/new/(.*)': '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route # '/new/(.*)': '/blog/$1' # Regex any /new/my-page URL to /blog/my-page Route
blog: blog:
route: '/blog' # Custom value added (accessible via system.blog.route) route: '/blog' # Custom value added (accessible via system.blog.route)
#menu: # Sample Menu Example #menu: # Menu Example
# - text: Source # - text: Source
# icon: github # icon: github
# url: https://github.com/getgrav/grav # url: https://github.com/getgrav/grav
+1 -1
View File
@@ -1,6 +1,6 @@
schemes: schemes:
image: image:
type: ReadOnlyStream type: Stream
paths: paths:
- user://images - user://images
- system://images - system://images
+19 -2
View File
@@ -13,7 +13,9 @@ intl_enabled: true # Special logic for PHP Interna
languages: languages:
supported: [] # List of languages supported. eg: [en, fr, de] supported: [] # List of languages supported. eg: [en, fr, de]
default_lang: # Default is the first supported language. Must be one of the supported languages
include_default_lang: true # Include the default lang prefix in all URLs include_default_lang: true # Include the default lang prefix in all URLs
pages_fallback_only: false # Only fallback to find page content through supported languages
translations: true # Enable translations by default translations: true # Enable translations by default
translations_fallback: true # Fallback through supported translations if active lang doesn't exist translations_fallback: true # Fallback through supported translations if active lang doesn't exist
session_store_active: false # Store active language in session session_store_active: false # Store active language in session
@@ -52,7 +54,7 @@ pages:
special_chars: # List of special characters to automatically convert to entities special_chars: # List of special characters to automatically convert to entities
'>': 'gt' '>': 'gt'
'<': 'lt' '<': 'lt'
types: [txt,xml,html,htm,json,rss,atom] # list of valid page types types: [html,htm,xml,txt,json,rss,atom] # list of valid page types
append_url_extension: '' # Append page's extension in Page urls (e.g. '.html' results in /path/page.html) append_url_extension: '' # Append page's extension in Page urls (e.g. '.html' results in /path/page.html)
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days) expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
cache_control: # Can be blank for no setting, or a valid `cache-control` text value cache_control: # Can be blank for no setting, or a valid `cache-control` text value
@@ -65,6 +67,7 @@ pages:
ignore_files: [.DS_Store] # Files to ignore in Pages ignore_files: [.DS_Store] # Files to ignore in Pages
ignore_folders: [.git, .idea] # Folders to ignore in Pages ignore_folders: [.git, .idea] # Folders to ignore in Pages
ignore_hidden: true # Ignore all Hidden files and folders ignore_hidden: true # Ignore all Hidden files and folders
hide_empty_folders: false # If folder has no .md file, should it be hidden
url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections url_taxonomy_filters: true # Enable auto-magic URL-based taxonomy filters for page collections
frontmatter: frontmatter:
process_twig: false # Should the frontmatter be processed to replace Twig variables? process_twig: false # Should the frontmatter be processed to replace Twig variables?
@@ -74,8 +77,11 @@ cache:
enabled: true # Set to true to enable caching enabled: true # Set to true to enable caching
check: check:
method: file # Method to check for updates in pages: file|folder|hash|none method: file # Method to check for updates in pages: file|folder|hash|none
driver: auto # One of: auto|file|apc|xcache|memcache|wincache driver: auto # One of: auto|file|apcu|memcache|wincache
prefix: 'g' # Cache prefix string (prevents cache conflicts) prefix: 'g' # Cache prefix string (prevents cache conflicts)
purge_at: '0 4 * * *' # How often to purge old file cache (using new scheduler)
clear_at: '0 3 * * *' # How often to clear cache (using new scheduler)
clear_job_type: 'standard' # Type to clear when processing the scheduled clear job `standard`|`all`
clear_images_by_default: true # By default grav will include processed images in cache clear, this can be disabled clear_images_by_default: true # By default grav will include processed images in cache clear, this can be disabled
cli_compatibility: false # Ensures only non-volatile drivers are used (file, redis, memcache, etc.) cli_compatibility: false # Ensures only non-volatile drivers are used (file, redis, memcache, etc.)
lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite) lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite)
@@ -112,6 +118,11 @@ errors:
display: 0 # Display either (1) Full backtrace | (0) Simple Error | (-1) System Error display: 0 # Display either (1) Full backtrace | (0) Simple Error | (-1) System Error
log: true # Log errors to /logs folder log: true # Log errors to /logs folder
log:
handler: file # Log handler. Currently supported: file | syslog
syslog:
facility: local6 # Syslog facilities output
debugger: debugger:
enabled: false # Enable Grav debugger and following settings enabled: false # Enable Grav debugger and following settings
shutdown: shutdown:
@@ -123,6 +134,7 @@ images:
cache_perms: '0755' # MUST BE IN QUOTES!! Default cache folder perms. Usually '0755' or '0775' cache_perms: '0755' # MUST BE IN QUOTES!! Default cache folder perms. Usually '0755' or '0775'
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
auto_fix_orientation: false # Automatically fix the image orientation based on the Exif data auto_fix_orientation: false # Automatically fix the image orientation based on the Exif data
seofriendly: false # SEO-friendly processed image names
media: media:
enable_media_timestamp: false # Enable media timestamps enable_media_timestamp: false # Enable media timestamps
@@ -135,6 +147,7 @@ session:
initialize: true # Initialize session from Grav (if false, plugin needs to start the session) initialize: true # Initialize session from Grav (if false, plugin needs to start the session)
timeout: 1800 # Timeout in seconds 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 name: grav-site # Name prefix of the session cookie. Use alphanumeric, dashes or underscores only. Do not use dots in the session name
uniqueness: path # Should sessions be `path` based or `security.salt` based
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 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.
split: true # Sessions should be independent between site and plugins (such as admin) split: true # Sessions should be independent between site and plugins (such as admin)
@@ -147,6 +160,10 @@ gpm:
verify_peer: true # Sometimes on some systems (Windows most commonly) GPM is unable to connect because the SSL certificate cannot be verified. Disabling this setting might help. verify_peer: true # Sometimes on some systems (Windows most commonly) GPM is unable to connect because the SSL certificate cannot be verified. Disabling this setting might help.
official_gpm_only: true # By default GPM direct-install will only allow URLs via the official GPM proxy to ensure security official_gpm_only: true # By default GPM direct-install will only allow URLs via the official GPM proxy to ensure security
accounts:
type: data # Account type: data or flex
storage: file # Flex storage type: file or folder
strict_mode: strict_mode:
yaml_compat: true # Grav 1.5+: Enables YAML backwards compatibility yaml_compat: true # Grav 1.5+: Enables YAML backwards compatibility
twig_compat: true # Grav 1.5+: Enables deprecated Twig autoescape setting (autoescape: false) twig_compat: true # Grav 1.5+: Enables deprecated Twig autoescape setting (autoescape: false)
+4 -4
View File
@@ -1,19 +1,19 @@
<?php <?php
/** /**
* @package Grav.Core * @package Grav\Core
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
// Some standard defines // Some standard defines
define('GRAV', true); define('GRAV', true);
define('GRAV_VERSION', '1.5.8'); define('GRAV_VERSION', '1.6.16');
define('GRAV_TESTING', false); define('GRAV_TESTING', false);
define('DS', '/'); define('DS', '/');
if (!defined('GRAV_PHP_MIN')) { if (!defined('GRAV_PHP_MIN')) {
define('GRAV_PHP_MIN', '5.6.4'); define('GRAV_PHP_MIN', '7.1.3');
} }
// Directories and Paths // Directories and Paths
+17
View File
@@ -0,0 +1,17 @@
<?php
/**
* @package Grav\Core
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
if (!defined('GRAV_ROOT')) {
die();
}
use Grav\Installer\Install;
require_once __DIR__ . '/src/Grav/Installer/Install.php';
return Install::instance();
+62 -74
View File
@@ -1,75 +1,63 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\nالعنوان: %1$s\n---\n# خطأ: مادة أمامية غير صحيحة\n\nمسار: '%2$s'\n\n**%3$s**\n\n, , ,\n\n%4$s\n, , ,"
العنوان: %1$s NICETIME:
--- NO_DATE_PROVIDED: لم يتم تقديم التاريخ
# خطأ: مادة أمامية غير صحيحة BAD_DATE: تاريخ خاطئ
AGO: من قبل
مسار: '%2$s' FROM_NOW: من الآن
SECOND: ثانية
**%3$s** MINUTE: دقيقة
HOUR: ساعة
, , , DAY: يوم
WEEK: أسبوع
%4$s MONTH: شهر
, , , YEAR: سنة
NICETIME: DECADE: عقد
NO_DATE_PROVIDED: لم يتم تقديم التاريخ SEC: ثانية
BAD_DATE: تاريخ خاطئ MIN: دقيقة
AGO: من قبل HR: ساعة
FROM_NOW: من الآن WK: أسبوع
SECOND: ثانية MO: شهر
MINUTE: دقيقة YR: سنة
HOUR: ساعة DEC: عقد
DAY: يوم SECOND_PLURAL: ثواني
WEEK: أسبوع MINUTE_PLURAL: '‮دقائق'
MONTH: شهر HOUR_PLURAL: ساعات
YEAR: سنة DAY_PLURAL: أيام
DECADE: عقد WEEK_PLURAL: أسابيع
SEC: ثانية MONTH_PLURAL: أشهر
MIN: دقيقة YEAR_PLURAL: سنوات
HR: ساعة DECADE_PLURAL: عقود
WK: أسبوع SEC_PLURAL: ثواني
MO: شهر MIN_PLURAL: دقائق
YR: سنة HR_PLURAL: ساعات
DEC: عقد WK_PLURAL: أسابيع
SECOND_PLURAL: ثواني MO_PLURAL: أشهر
MINUTE_PLURAL: ‮دقائق YR_PLURAL: سنوات
HOUR_PLURAL: ساعات DEC_PLURAL: عقود
DAY_PLURAL: أيام FORM:
WEEK_PLURAL: أسابيع VALIDATION_FAIL: <b>فشل التحقق من صحة:</b>
MONTH_PLURAL: أشهر INVALID_INPUT: إدخال غير صحيح في
YEAR_PLURAL: سنوات MISSING_REQUIRED_FIELD: 'حقل مطلوب مفقود:'
DECADE_PLURAL: عقود MONTHS_OF_THE_YEAR:
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:
- شباط - 'الاثنين'
- آذار/ مارس - 'الثلاثاء'
- نيسان - 'الأربعاء'
- أيار - 'الخميس'
- حزيران - 'الجمعة'
- تموز - 'السبت'
- آب - 'الأحد'
- أيلول
- تشرين الأول
- تشرين الثاني
- كانون الأول
DAYS_OF_THE_WEEK:
- الاثنين
- الثلاثاء
- الأربعاء
- الخميس
- الجمعة
- السبت
- الأحد
+62
View File
@@ -0,0 +1,62 @@
---
GRAV:
NICETIME:
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:
- 'понеделник'
- 'вторник'
- 'сряда'
- 'четвъртък'
- 'петък'
- 'събота'
- 'неделя'
+61 -74
View File
@@ -1,75 +1,62 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# S'ha produït un error: Frontmatter invàlid\n\nRuta: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s NICETIME:
--- NO_DATE_PROVIDED: No s'ha proporcionat data
BAD_DATE: Data invàlida
# S'ha produït un error: Frontmatter invàlid AGO: abans
FROM_NOW: des d'ara
Ruta: `%2$s` SECOND: segon
MINUTE: minut
**%3$s** HOUR: hora
DAY: dia
``` WEEK: setmana
%4$s MONTH: mes
``` YEAR: any
NICETIME: DECADE: dècada
NO_DATE_PROVIDED: "No s'ha proporcionat data" SEC: s
BAD_DATE: Data invàlida HR: h
AGO: abans WK: setm.
FROM_NOW: "des d'ara" MO: m.
SECOND: segon YR: a.
MINUTE: minut DEC: dèc.
HOUR: hora SECOND_PLURAL: segons
DAY: dia MINUTE_PLURAL: minuts
WEEK: setmana HOUR_PLURAL: hores
MONTH: mes DAY_PLURAL: dies
YEAR: any WEEK_PLURAL: setmanes
DECADE: dècada MONTH_PLURAL: mesos
SEC: s YEAR_PLURAL: anys
MIN: min DECADE_PLURAL: dècades
HR: h SEC_PLURAL: s
WK: setm. MIN_PLURAL: min
MO: m. HR_PLURAL: h
YR: a. WK_PLURAL: setm.
DEC: dèc. MO_PLURAL: mesos
SECOND_PLURAL: segons YR_PLURAL: anys
MINUTE_PLURAL: minuts DEC_PLURAL: dèc.
HOUR_PLURAL: hores FORM:
DAY_PLURAL: dies VALIDATION_FAIL: <b>Ha fallat la validació:</b>
WEEK_PLURAL: setmanes INVALID_INPUT: Entrada no vàlida a
MONTH_PLURAL: mesos MISSING_REQUIRED_FIELD: 'Falta camp obligatori:'
YEAR_PLURAL: anys MONTHS_OF_THE_YEAR:
DECADE_PLURAL: dècades - 'Gener'
SEC_PLURAL: s - 'Febrer'
MIN_PLURAL: min - 'Març'
HR_PLURAL: h - 'Abril'
WK_PLURAL: setm. - 'Maig'
MO_PLURAL: mesos - 'Juny'
YR_PLURAL: anys - 'Juliol'
DEC_PLURAL: dèc. - 'Agost'
FORM: - 'Setembre'
VALIDATION_FAIL: '<b>Ha fallat la validació:</b>' - 'Octubre'
INVALID_INPUT: Entrada no vàlida a - 'Novembre'
MISSING_REQUIRED_FIELD: 'Falta camp obligatori:' - 'Desembre'
MONTHS_OF_THE_YEAR: DAYS_OF_THE_WEEK:
- Gener - 'Dilluns'
- Febrer - 'Dimarts'
- Març - 'Dimecres'
- Abril - 'Dijous'
- Maig - 'Divendres'
- Juny - 'Dissabte'
- Juliol - 'Diumenge'
- Agost
- Setembre
- Octubre
- Novembre
- Desembre
DAYS_OF_THE_WEEK:
- Dilluns
- Dimarts
- Dimecres
- Dijous
- Divendres
- Dissabte
- Diumenge
+143 -80
View File
@@ -1,81 +1,144 @@
--- ---
INFLECTOR_UNCOUNTABLE: GRAV:
- vybavení FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Chyba: Chybný frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
- informace INFLECTOR_PLURALS:
- rýže '/(quiz)$/i': '\1zes'
- peníze '/^(ox)$/i': '\1en'
- druhy '/([m|l])ouse$/i': '\1ice'
- série '/(matr|vert|ind)ix|ex$/i': '\1ices'
- ryba '/(x|ch|ss|sh)$/i': '\1es'
- ovce '/([^aeiouy]|qu)ies$/i': '\1y'
INFLECTOR_IRREGULAR: '/([^aeiouy]|qu)y$/i': '\1ies'
person: lidé '/(hive)$/i': '\1s'
man: muži '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
child: děti '/sis$/i': 'ses'
sex: pohlaví '/([ti])um$/i': '\1a'
move: pohyby '/(buffal|tomat)o$/i': '\1oes'
INFLECTOR_ORDINALS: '/(bu)s$/i': '\1ses'
default: '.' '/(alias|status)/i': '\1es'
first: '.' '/(octop|vir)us$/i': '\1i'
second: '.' '/(ax|test)is$/i': '\1es'
third: '.' '/s$/i': 's'
NICETIME: '/$/': 's'
NO_DATE_PROVIDED: Datum nebylo vloženo INFLECTOR_SINGULAR:
BAD_DATE: Chybné datum '/(quiz)zes$/i': '\1'
AGO: zpět '/(matr)ices$/i': '\1ix'
FROM_NOW: od teď '/(vert|ind)ices$/i': '\1ex'
SECOND: sekunda '/^(ox)en/i': '\1'
MINUTE: minuta '/(alias|status)es$/i': '\1'
HOUR: hodina '/([octop|vir])i$/i': '\1us'
DAY: den '/(cris|ax|test)es$/i': '\1is'
WEEK: týden '/(shoe)s$/i': '\1'
MONTH: měsíc '/(o)es$/i': '\1'
YEAR: rok '/(bus)es$/i': '\1'
DECADE: dekáda '/([m|l])ice$/i': '\1ouse'
SEC: sek '/(x|ch|ss|sh)es$/i': '\1'
MIN: min '/(m)ovies$/i': '\1ovie'
HR: hod '/(s)eries$/i': '\1eries'
WK: t '/([^aeiouy]|qu)ies$/i': '\1y'
MO: m '/([lr])ves$/i': '\1f'
YR: r '/(tive)s$/i': '\1'
DEC: dek '/(hive)s$/i': '\1'
SECOND_PLURAL: sekundy '/([^f])ves$/i': '\1fe'
MINUTE_PLURAL: minuty '/(^analy)ses$/i': '\1sis'
HOUR_PLURAL: hodiny '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
DAY_PLURAL: dny '/([ti])a$/i': '\1um'
WEEK_PLURAL: týdny '/(n)ews$/i': '\1ews'
MONTH_PLURAL: měsíce INFLECTOR_UNCOUNTABLE:
YEAR_PLURAL: roky - 'vybavení'
DECADE_PLURAL: dekády - 'informace'
SEC_PLURAL: sek - 'rýže'
MIN_PLURAL: min - 'peníze'
HR_PLURAL: hod - 'druhy'
WK_PLURAL: t - 'série'
MO_PLURAL: m - 'ryba'
YR_PLURAL: r - 'ovce'
DEC_PLURAL: dek INFLECTOR_IRREGULAR:
FORM: 'person': 'lidé'
VALIDATION_FAIL: '<b>Ověření se nezdařilo:</b>' 'man': 'muži'
INVALID_INPUT: Neplatný vstup v 'child': 'děti'
MISSING_REQUIRED_FIELD: 'Chybí požadované pole:' 'sex': 'pohlaví'
MONTHS_OF_THE_YEAR: 'move': 'pohyby'
- ledna INFLECTOR_ORDINALS:
- února 'default': '.'
- března 'first': '.'
- dubna 'second': '.'
- května 'third': '.'
- června NICETIME:
- července NO_DATE_PROVIDED: Datum nebylo vloženo
- srpna BAD_DATE: Chybné datum
- září AGO: zpět
- října FROM_NOW: od teď
- listopadu JUST_NOW: právě teď
- prosince SECOND: sekunda
DAYS_OF_THE_WEEK: MINUTE: minuta
- Pondělí HOUR: hodina
- Úterý DAY: den
- Středa WEEK: týden
- Čtvrtek MONTH: měsíc
- Pátek YEAR: rok
- Sobota DECADE: dekáda
- Neděle 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>
INVALID_INPUT: Neplatný vstup v
MISSING_REQUIRED_FIELD: 'Chybí požadované pole:'
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'
CRON:
EVERY: každý
EVERY_HOUR: každou hodinu
EVERY_MINUTE: každou minutu
EVERY_DAY_OF_WEEK: každý den v týdnu
EVERY_DAY_OF_MONTH: každý den v měsíci
EVERY_MONTH: každý měsíc
TEXT_PERIOD: Every <b />
TEXT_MINS: ' at <b /> minute(s) past the hour'
TEXT_TIME: ' at <b />:<b />'
TEXT_DOW: ' on <b />'
TEXT_MONTH: ' of <b />'
TEXT_DOM: ' on <b />'
ERROR1: Tag %s není podporován!
ERROR2: Chybný počet prvků
ERROR3: jquery_element musí být nastaven v nastaveních pro jqCron
ERROR4: Nerozpoznaný výraz
+61 -74
View File
@@ -1,75 +1,62 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\nTitel: %1$s\n---\n\n# Fejl: Ugyldigt frontmatter\n\nSti: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
Titel: %1$s NICETIME:
--- NO_DATE_PROVIDED: Ingen dato angivet
BAD_DATE: Ugyldig dato
# Fejl: Ugyldigt frontmatter AGO: siden
FROM_NOW: fra nu
Sti: `%2$s` SECOND: sekund
MINUTE: minut
**%3$s** HOUR: time
DAY: dag
``` WEEK: uge
%4$s MONTH: måned
``` YEAR: år
NICETIME: DECADE: årti
NO_DATE_PROVIDED: Ingen dato angivet SEC: sek
BAD_DATE: Ugyldig dato HR: t
AGO: siden WK: u
FROM_NOW: fra nu MO: md
SECOND: sekund YR: år
MINUTE: minut DEC: årti
HOUR: time SECOND_PLURAL: sekunder
DAY: dag MINUTE_PLURAL: minutter
WEEK: uge HOUR_PLURAL: timer
MONTH: måned DAY_PLURAL: dage
YEAR: år WEEK_PLURAL: uger
DECADE: årti MONTH_PLURAL: måneder
SEC: sek YEAR_PLURAL: år
MIN: min DECADE_PLURAL: årtier
HR: t SEC_PLURAL: sek
WK: u MIN_PLURAL: min
MO: md HR_PLURAL: timer
YR: år WK_PLURAL: uger
DEC: årti MO_PLURAL: mdr
SECOND_PLURAL: sekunder YR_PLURAL: år
MINUTE_PLURAL: minutter DEC_PLURAL: årtier
HOUR_PLURAL: timer FORM:
DAY_PLURAL: dage VALIDATION_FAIL: <b>Validering mislykkedes:</b>
WEEK_PLURAL: uger INVALID_INPUT: Ugyldigt input i
MONTH_PLURAL: måneder MISSING_REQUIRED_FIELD: 'Mangler obligatorisk felt:'
YEAR_PLURAL: år MONTHS_OF_THE_YEAR:
DECADE_PLURAL: årtier - 'januar'
SEC_PLURAL: sek - 'februar'
MIN_PLURAL: min - 'mars'
HR_PLURAL: timer - 'april'
WK_PLURAL: uger - 'mai'
MO_PLURAL: mdr - 'juni'
YR_PLURAL: år - 'juli'
DEC_PLURAL: årtier - 'august'
FORM: - 'september'
VALIDATION_FAIL: '<b>Validering mislykkedes:</b>' - 'oktober'
INVALID_INPUT: Ugyldigt input i - 'november'
MISSING_REQUIRED_FIELD: 'Mangler obligatorisk felt:' - 'desember'
MONTHS_OF_THE_YEAR: DAYS_OF_THE_WEEK:
- Januar - 'mandag'
- Februar - 'tirsdag'
- Marts - 'onsdag'
- April - 'torsdag'
- Maj - 'fredag'
- Juni - 'lørdag'
- Juli - 'søndag'
- August
- September
- Oktober
- November
- December
DAYS_OF_THE_WEEK:
- Mandag
- Tirsdag
- Onsdag
- Torsdag
- Fredag
- Lørdag
- Søndag
+143 -88
View File
@@ -1,89 +1,144 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n# Fehler: Frontmatter enthält Fehler\n\nPfad: `%2$s`\n\n**%3$s ** \n\n```\n%4$s\n```"
title: %1$s INFLECTOR_PLURALS:
--- '/(quiz)$/i': '\1zes'
# Fehler: Frontmatter enthält Fehler '/^(ox)$/i': '\1en'
'/([m|l])ouse$/i': '\1ice'
Pfad: `%2$s` '/(matr|vert|ind)ix|ex$/i': '\1ice'
'/(x|ch|ss|sh)$/i': '\1es'
**%3$s ** '/([^aeiouy]|qu)ies$/i': '\1y'
'/([^aeiouy]|qu)y$/i': '\1ies'
``` '/(hive)$/i': '\1s'
%4$s '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
``` '/sis$/i': 'ses'
INFLECTOR_UNCOUNTABLE: '/([ti])um$/i': '\1a'
1: Informationen '/(buffal|tomat)o$/i': '\1oes'
2: Reis '/(bu)s$/i': '\1ses'
3: Geld '/(alias|status)/i': '\1es'
INFLECTOR_IRREGULAR: '/(octop|vir)us$/i': '\1i'
person: Personen '/(ax|test)is$/i': '\1es'
man: Menschen '/s$/i': 's'
child: Kinder '/$/': 's'
sex: Geschlecht INFLECTOR_SINGULAR:
move: Züge '/(quiz)zes$/i': '\1'
INFLECTOR_ORDINALS: '/(matr)ices$/i': '\1ix'
default: '.' '/(vert|ind)ices$/i': '\1ex'
first: '.' '/^(ox)en/i': '\1'
second: '.' '/(alias|status)es$/i': '\1'
third: '.' '/([octop|vir])i$/i': '\1us'
NICETIME: '/(cris|ax|test)es$/i': '\1ies'
NO_DATE_PROVIDED: Kein Datum angegeben '/(shoe)s$/i': '\1'
BAD_DATE: Falsches Datum '/(o)es$/i': '\1'
AGO: her '/(bus)es$/i': '\1'
FROM_NOW: ab jetzt '/([m|l])ice$/i': '\1ouse'
SECOND: Sekunde '/(x|ch|ss|sh)es$/i': '\1'
MINUTE: Minute '/(m)ovies$/i': '\1ovie'
HOUR: Stunde '/(s)eries$/i': '\1eries'
DAY: Tag '/([^aeiouy]|qu)ies$/i': '\1y'
WEEK: Woche '/([lr])ves$/i': '\1f'
MONTH: Monat '/(tive)s$/i': '\1'
YEAR: Jahr '/(hive)s$/i': '\1'
DECADE: Jahrzehnt '/([^f])ves$/i': '\1fe'
SEC: Sek. '/(^analy)ses$/i': '\1sis'
MIN: Min. '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2ves'
HR: Std. '/([ti])a$/i': '\1um'
WK: Wo. '/(n)ews$/i': '\1ews'
MO: Mo. INFLECTOR_UNCOUNTABLE:
YR: J. - 'Ausstattung'
DEC: Dek. - 'Informationen'
SECOND_PLURAL: Sekunden - 'Reis'
MINUTE_PLURAL: Minuten - 'Geld'
HOUR_PLURAL: Stunden - 'Arten'
DAY_PLURAL: Tage - 'Serie'
WEEK_PLURAL: Wochen - 'Fisch'
MONTH_PLURAL: Monate - 'Schaf'
YEAR_PLURAL: Jahre INFLECTOR_IRREGULAR:
DECADE_PLURAL: Jahrzehnte 'person': 'Personen'
SEC_PLURAL: Sekunden 'man': 'Menschen'
MIN_PLURAL: Minuten 'child': 'Kinder'
HR_PLURAL: Stunden 'sex': 'Geschlecht'
WK_PLURAL: Wochen 'move': 'Züge'
MO_PLURAL: Monate INFLECTOR_ORDINALS:
YR_PLURAL: Jahre 'default': '.'
DEC_PLURAL: Jahrzehnten 'first': '.'
FORM: 'second': '.'
VALIDATION_FAIL: '<b>Überprüfung fehlgeschlagen:</b>' 'third': '.'
INVALID_INPUT: Ungültige Eingabe in NICETIME:
MISSING_REQUIRED_FIELD: 'Erforderliches Feld fehlt:' NO_DATE_PROVIDED: Kein Datum angegeben
MONTHS_OF_THE_YEAR: BAD_DATE: Falsches Datum
- Januar AGO: her
- Februar FROM_NOW: ab jetzt
- März JUST_NOW: jetzt gerade
- April SECOND: Sekunde
- Mai MINUTE: Minute
- Juni HOUR: Stunde
- Juli DAY: Tag
- August WEEK: Woche
- September MONTH: Monat
- Oktober YEAR: Jahr
- November DECADE: Jahrzehnt
- Dezember SEC: Sek.
DAYS_OF_THE_WEEK: MIN: Min.
- Montag HR: Std.
- Dienstag WK: Wo.
- Mittwoch MO: Mo.
- Donnerstag YR: J.
- Freitag DEC: Dez
- Samstag SECOND_PLURAL: Sekunden
- Sonntag MINUTE_PLURAL: Minuten
HOUR_PLURAL: Stunden
DAY_PLURAL: Tage
WEEK_PLURAL: Wochen
MONTH_PLURAL: Monate
YEAR_PLURAL: Jahre
DECADE_PLURAL: Jahrzehnte
SEC_PLURAL: Sekunden
MIN_PLURAL: Minuten
HR_PLURAL: Stunden
WK_PLURAL: Wochen
MO_PLURAL: Monate
YR_PLURAL: Jahre
DEC_PLURAL: Jahrzehnten
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'
- 'September'
- 'Oktober'
- 'November'
- 'Dezember'
DAYS_OF_THE_WEEK:
- 'Montag'
- 'Dienstag'
- 'Mittwoch'
- 'Donnerstag'
- 'Freitag'
- 'Samstag'
- 'Sonntag'
CRON:
EVERY: jede
EVERY_HOUR: jede Stunde
EVERY_MINUTE: Jede Minute
EVERY_DAY_OF_WEEK: jeden Tag der Woche
EVERY_DAY_OF_MONTH: jeden Tag des Monats
EVERY_MONTH: jeden Monat
TEXT_PERIOD: Alle <b />
TEXT_MINS: ' bei <b /> Minuten nach der vollen Stunde (n)'
TEXT_TIME: ' bei <b />:<b />'
TEXT_DOW: ' auf <b />'
TEXT_MONTH: ' von <b />'
TEXT_DOM: ' auf <b />'
ERROR1: Der Tag %s wird nicht unterstützt!
ERROR2: Ungültige Anzahl von Elementen
ERROR3: jquery_element sollte in den jqCron Einstellungen gesetzt werden
ERROR4: Unbekannter Ausdruck
+62 -21
View File
@@ -1,22 +1,63 @@
--- ---
MONTHS_OF_THE_YEAR: GRAV:
- Ιανουάριος FRONTMATTER_ERROR_PAGE: "---\nΤίτλος: %1$s\n---\n\n# Σφάλμα: Μη έγκυρη διαδρομή Frontmatter\n\nΔιαδρομή: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
- Φεβρουάριος NICETIME:
- Μάρτιος NO_DATE_PROVIDED: Δεν δόθηκε καμία ημερομηνία
- Απρίλιος BAD_DATE: Εσφαλμένη ημερομηνία
- Μάιος AGO: πρίν
- Ιούνιος FROM_NOW: από τώρα
- Ιούλιος SECOND: δευτερόλεπτο
- Αύγουστος MINUTE: λεπτό
- Σεπτέμβριος HOUR: ώρα
- Οκτώβριος DAY: ημέρα
- Νοέμβριος WEEK: εβδομάδα
- Δεκέμβριος MONTH: μήνας
DAYS_OF_THE_WEEK: 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:
- 'Δευτέρα'
- 'Τρίτη'
- 'Τετάρτη'
- 'Πέμπτη'
- 'Παρασκευή'
- 'Σάββατο'
- 'Κυριακή'
+120 -99
View File
@@ -1,99 +1,120 @@
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```" ---
INFLECTOR_PLURALS: GRAV:
'/(quiz)$/i': '\1zes' FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
'/^(ox)$/i': '\1en' INFLECTOR_PLURALS:
'/([m|l])ouse$/i': '\1ice' '/(quiz)$/i': '\1zes'
'/(matr|vert|ind)ix|ex$/i': '\1ices' '/^(ox)$/i': '\1en'
'/(x|ch|ss|sh)$/i': '\1es' '/([m|l])ouse$/i': '\1ice'
'/([^aeiouy]|qu)ies$/i': '\1y' '/(matr|vert|ind)ix|ex$/i': '\1ices'
'/([^aeiouy]|qu)y$/i': '\1ies' '/(x|ch|ss|sh)$/i': '\1es'
'/(hive)$/i': '\1s' '/([^aeiouy]|qu)ies$/i': '\1y'
'/(?:([^f])fe|([lr])f)$/i': '\1\2ves' '/([^aeiouy]|qu)y$/i': '\1ies'
'/sis$/i': 'ses' '/(hive)$/i': '\1s'
'/([ti])um$/i': '\1a' '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
'/(buffal|tomat)o$/i': '\1oes' '/sis$/i': 'ses'
'/(bu)s$/i': '\1ses' '/([ti])um$/i': '\1a'
'/(alias|status)/i': '\1es' '/(buffal|tomat)o$/i': '\1oes'
'/(octop|vir)us$/i': '\1i' '/(bu)s$/i': '\1ses'
'/(ax|test)is$/i': '\1es' '/(alias|status)/i': '\1es'
'/s$/i': 's' '/(octop|vir)us$/i': '\1i'
'/$/': 's' '/(ax|test)is$/i': '\1es'
INFLECTOR_SINGULAR: '/s$/i': 's'
'/(quiz)zes$/i': '\1' '/$/': 's'
'/(matr)ices$/i': '\1ix' INFLECTOR_SINGULAR:
'/(vert|ind)ices$/i': '\1ex' '/(quiz)zes$/i': '\1'
'/^(ox)en/i': '\1' '/(matr)ices$/i': '\1ix'
'/(alias|status)es$/i': '\1' '/(vert|ind)ices$/i': '\1ex'
'/([octop|vir])i$/i': '\1us' '/^(ox)en/i': '\1'
'/(cris|ax|test)es$/i': '\1is' '/(alias|status)es$/i': '\1'
'/(shoe)s$/i': '\1' '/([octop|vir])i$/i': '\1us'
'/(o)es$/i': '\1' '/(cris|ax|test)es$/i': '\1is'
'/(bus)es$/i': '\1' '/(shoe)s$/i': '\1'
'/([m|l])ice$/i': '\1ouse' '/(o)es$/i': '\1'
'/(x|ch|ss|sh)es$/i': '\1' '/(bus)es$/i': '\1'
'/(m)ovies$/i': '\1ovie' '/([m|l])ice$/i': '\1ouse'
'/(s)eries$/i': '\1eries' '/(x|ch|ss|sh)es$/i': '\1'
'/([^aeiouy]|qu)ies$/i': '\1y' '/(m)ovies$/i': '\1ovie'
'/([lr])ves$/i': '\1f' '/(s)eries$/i': '\1eries'
'/(tive)s$/i': '\1' '/([^aeiouy]|qu)ies$/i': '\1y'
'/(hive)s$/i': '\1' '/([lr])ves$/i': '\1f'
'/([^f])ves$/i': '\1fe' '/(tive)s$/i': '\1'
'/(^analy)ses$/i': '\1sis' '/(hive)s$/i': '\1'
'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis' '/([^f])ves$/i': '\1fe'
'/([ti])a$/i': '\1um' '/(^analy)ses$/i': '\1sis'
'/(n)ews$/i': '\1ews' '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
'/s$/i': '' '/([ti])a$/i': '\1um'
INFLECTOR_UNCOUNTABLE: ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep'] '/(n)ews$/i': '\1ews'
INFLECTOR_IRREGULAR: '/s$/i': ''
'person': 'people' INFLECTOR_UNCOUNTABLE: ['equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep']
'man': 'men' INFLECTOR_IRREGULAR:
'child': 'children' 'person': 'people'
'sex': 'sexes' 'man': 'men'
'move': 'moves' 'child': 'children'
INFLECTOR_ORDINALS: 'sex': 'sexes'
'default': 'th' 'move': 'moves'
'first': 'st' INFLECTOR_ORDINALS:
'second': 'nd' 'default': 'th'
'third': 'rd' 'first': 'st'
NICETIME: 'second': 'nd'
NO_DATE_PROVIDED: No date provided 'third': 'rd'
BAD_DATE: Bad date NICETIME:
AGO: ago NO_DATE_PROVIDED: No date provided
FROM_NOW: from now BAD_DATE: Bad date
JUST_NOW: just now AGO: ago
SECOND: second FROM_NOW: from now
MINUTE: minute JUST_NOW: just now
HOUR: hour SECOND: second
DAY: day MINUTE: minute
WEEK: week HOUR: hour
MONTH: month DAY: day
YEAR: year WEEK: week
DECADE: decade MONTH: month
SEC: sec YEAR: year
MIN: min DECADE: decade
HR: hr SEC: sec
WK: wk MIN: min
MO: mo HR: hr
YR: yr WK: wk
DEC: dec MO: mo
SECOND_PLURAL: seconds YR: yr
MINUTE_PLURAL: minutes DEC: dec
HOUR_PLURAL: hours SECOND_PLURAL: seconds
DAY_PLURAL: days MINUTE_PLURAL: minutes
WEEK_PLURAL: weeks HOUR_PLURAL: hours
MONTH_PLURAL: months DAY_PLURAL: days
YEAR_PLURAL: years WEEK_PLURAL: weeks
DECADE_PLURAL: decades MONTH_PLURAL: months
SEC_PLURAL: secs YEAR_PLURAL: years
MIN_PLURAL: mins DECADE_PLURAL: decades
HR_PLURAL: hrs SEC_PLURAL: secs
WK_PLURAL: wks MIN_PLURAL: mins
MO_PLURAL: mos HR_PLURAL: hrs
YR_PLURAL: yrs WK_PLURAL: wks
DEC_PLURAL: decs MO_PLURAL: mos
FORM: YR_PLURAL: yrs
VALIDATION_FAIL: <b>Validation failed:</b> DEC_PLURAL: decs
INVALID_INPUT: Invalid input in FORM:
MISSING_REQUIRED_FIELD: Missing required field: VALIDATION_FAIL: <b>Validation failed:</b>
MONTHS_OF_THE_YEAR: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] INVALID_INPUT: Invalid input in
DAYS_OF_THE_WEEK: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] MISSING_REQUIRED_FIELD: Missing required field:
MONTHS_OF_THE_YEAR: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
DAYS_OF_THE_WEEK: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
YES: "Yes"
NO: "No"
CRON:
EVERY: every
EVERY_HOUR: every hour
EVERY_MINUTE: every minute
EVERY_DAY_OF_WEEK: every day of the week
EVERY_DAY_OF_MONTH: every day of the month
EVERY_MONTH: every month
TEXT_PERIOD: Every <b />
TEXT_MINS: ' at <b /> minute(s) past the hour'
TEXT_TIME: ' at <b />:<b />'
TEXT_DOW: ' on <b />'
TEXT_MONTH: ' of <b />'
TEXT_DOM: ' on <b />'
ERROR1: The tag %s is not supported!
ERROR2: Bad number of elements
ERROR3: The jquery_element should be set into jqCron settings
ERROR4: Unrecognized expression
+94 -89
View File
@@ -1,90 +1,95 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntítulo: %1$s\n---\n\n# Error: Frontmatter no válido\n\nRuta: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s INFLECTOR_UNCOUNTABLE:
--- - 'equipo'
- 'información'
# Error: Frontmatter Inválido - 'rice'
- 'dinero'
Ruta: `%2$s` - 'species'
- 'series'
**%3$s** - 'pescado'
- 'oveja'
``` INFLECTOR_IRREGULAR:
%4$s 'man': 'hombres'
``` 'child': 'niños'
INFLECTOR_UNCOUNTABLE: 'sex': 'sexos'
0: equipo INFLECTOR_ORDINALS:
1: información 'first': 'ro'
3: dinero 'second': 'do'
5: series 'third': 'ro'
6: pescado NICETIME:
7: oveja NO_DATE_PROVIDED: No se proporcionó fecha
INFLECTOR_IRREGULAR: BAD_DATE: Fecha errónea
man: hombres AGO: antes
child: niños FROM_NOW: desde ahora
sex: sexos JUST_NOW: hace un momento
INFLECTOR_ORDINALS: SECOND: segundo
first: ro MINUTE: minuto
second: do HOUR: hora
third: ro DAY: día
NICETIME: WEEK: semana
NO_DATE_PROVIDED: No se proporcionó fecha MONTH: mes
BAD_DATE: Fecha erronea YEAR: año
AGO: antes DECADE: década
FROM_NOW: desde ahora SEC: seg
SECOND: segundo HR: h
MINUTE: minuto WK: sem
HOUR: hora MO: mes
DAY: día YR: año
WEEK: semana SECOND_PLURAL: segundos
MONTH: mes MINUTE_PLURAL: minutos
YEAR: año HOUR_PLURAL: horas
DECADE: década DAY_PLURAL: días
SEC: seg WEEK_PLURAL: semanas
MIN: min MONTH_PLURAL: meses
HR: h YEAR_PLURAL: años
WK: sem DECADE_PLURAL: décadas
MO: mes SEC_PLURAL: segs
YR: año HR_PLURAL: hs
DEC: dec WK_PLURAL: sem
SECOND_PLURAL: segundos MO_PLURAL: mes
MINUTE_PLURAL: minutos YR_PLURAL: años
HOUR_PLURAL: horas DEC_PLURAL: décadas
DAY_PLURAL: días FORM:
WEEK_PLURAL: semanas VALIDATION_FAIL: '<b>Falló la validación: </b>'
MONTH_PLURAL: meses INVALID_INPUT: 'Dato inválido en: '
YEAR_PLURAL: años MISSING_REQUIRED_FIELD: 'Falta el campo requerido: '
DECADE_PLURAL: décadas MONTHS_OF_THE_YEAR:
SEC_PLURAL: segs - 'Enero'
MIN_PLURAL: mins - 'Febrero'
HR_PLURAL: hs - 'Marzo'
WK_PLURAL: sem - 'Abril'
MO_PLURAL: mes - 'Mayo'
YR_PLURAL: años - 'Junio'
DEC_PLURAL: décadas - 'Julio'
FORM: - 'Agosto'
VALIDATION_FAIL: '<b>Falló la validación. </b>' - 'Septiembre'
INVALID_INPUT: 'Dato inválido en: ' - 'Octubre'
MISSING_REQUIRED_FIELD: 'Falta el campo requerido: ' - 'Noviembre'
MONTHS_OF_THE_YEAR: - 'Diciembre'
- Enero DAYS_OF_THE_WEEK:
- Febrero - 'Lunes'
- Marzo - 'Martes'
- Abril - 'Miércoles'
- Mayo - 'Jueves'
- Junio - 'Viernes'
- Julio - 'Sábado'
- Agosto - 'Domingo'
- Septiembre CRON:
- Octubre EVERY: cada
- Noviembre EVERY_HOUR: cada hora
- Diciembre EVERY_MINUTE: cada minuto
DAYS_OF_THE_WEEK: EVERY_DAY_OF_WEEK: cada día de la semana
- Lunes EVERY_DAY_OF_MONTH: cada día del mes
- Martes EVERY_MONTH: cada mes
- Miércoles TEXT_PERIOD: Cada <b />
- Jueves TEXT_MINS: ' a <b /> minuto(s) despues de la hora'
- Viernes TEXT_TIME: ' a <b />:<b />'
- Sábado TEXT_DOW: ' en <b />'
- Domingo TEXT_MONTH: ' de<b />'
TEXT_DOM: ' en<b />'
ERROR1: La etiqueta %s no está soportada!
ERROR2: El número de elementos es erroneo
ERROR3: El jquery_element debería establecerse en la configuración del jqCron
ERROR4: Expresión no reconocida
+85
View File
@@ -0,0 +1,85 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\npealkiri: %1$s\n---\n\n# Viga: vigane Frontmatter'i\n\nasukoht: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
INFLECTOR_UNCOUNTABLE:
- 'equipment'
- 'informatsioon'
- 'rice'
- 'money'
- 'species'
- 'series'
- 'kala'
- 'lammas'
INFLECTOR_IRREGULAR:
'person': 'inimesed'
'man': 'mees'
'child': 'lapsed'
INFLECTOR_ORDINALS:
'default': '.'
'first': '.'
'second': '.'
'third': '.'
NICETIME:
NO_DATE_PROVIDED: Kuupäev määramata
BAD_DATE: Vigane kuupäev
AGO: tagasi
FROM_NOW: praegusest
JUST_NOW: just nüüd
SECOND: sekund
MINUTE: minut
HOUR: tundi
DAY: päev
WEEK: nädal
MONTH: kuu
YEAR: aasta
DECADE: 10 aastat
SEC: sek
HR: t
WK: näd
MO: k.
YR: a.
DEC: dekaad
SECOND_PLURAL: sekundit
MINUTE_PLURAL: minutit
HOUR_PLURAL: tundi
DAY_PLURAL: päeva
WEEK_PLURAL: nädalat
MONTH_PLURAL: kuud
YEAR_PLURAL: aastat
DECADE_PLURAL: dekaadi
SEC_PLURAL: sekundit
MIN_PLURAL: min
HR_PLURAL: t
WK_PLURAL: näd
MO_PLURAL: kuud
YR_PLURAL: aastat
DEC_PLURAL: dek.
FORM:
VALIDATION_FAIL: <b>Kinnitamine nurjus:</b>
INVALID_INPUT: 'Vigane sisend:'
MISSING_REQUIRED_FIELD: 'Nõutud väli puudub:'
MONTHS_OF_THE_YEAR:
- 'jaanuar'
- 'veebruar'
- 'märts'
- 'aprill'
- 'mai'
- 'juuni'
- 'juuli'
- 'august'
- 'september'
- 'oktoober'
- 'november'
- 'detsember'
DAYS_OF_THE_WEEK:
- 'esmaspäev'
- 'teisipäev'
- 'kolmapäev'
- 'neljapäev'
- 'reede'
- 'laupäev'
- 'pühapäev'
CRON:
EVERY: iga
EVERY_MONTH: iga kuu
TEXT_PERIOD: Iga <b />
+62
View File
@@ -0,0 +1,62 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "--- title: %1$s --- # Errorea: Baliogabeko Frontmatter Bidea: `%2$s` **%3$s** ``` %4$s ```"
NICETIME:
NO_DATE_PROVIDED: Ez da datarik ezarri
BAD_DATE: Okerreko data
AGO: ' duela'
FROM_NOW: oraindik aurrera
SECOND: segundo
MINUTE: minutu
HOUR: ordua
DAY: egun
WEEK: astea
MONTH: hilabetea
YEAR: urtea
DECADE: hamarkada
SEC: seg
HR: h
WK: ast
MO: hil
YR: urt
DEC: ham
SECOND_PLURAL: segundo
MINUTE_PLURAL: minutu
HOUR_PLURAL: ordu
DAY_PLURAL: egun
WEEK_PLURAL: aste
MONTH_PLURAL: hilabete
YEAR_PLURAL: urte
DECADE_PLURAL: hamarkada
SEC_PLURAL: segundo
MIN_PLURAL: minutu
HR_PLURAL: h
WK_PLURAL: ast
MO_PLURAL: hil
YR_PLURAL: urt
DEC_PLURAL: ham
FORM:
VALIDATION_FAIL: <b>Balidazioak huts egin du</b>
INVALID_INPUT: Baliogabeko sarrera
MISSING_REQUIRED_FIELD: 'Derrigorrezko eremua bete gabe:'
MONTHS_OF_THE_YEAR:
- 'Urtarrila'
- 'Otsaila'
- 'Martxoa'
- 'Apirila'
- 'Maiatza'
- 'Ekaina'
- 'Uztaila'
- 'Abuztua'
- 'Iraila'
- 'Urria'
- 'Azaroa'
- 'Abendua'
DAYS_OF_THE_WEEK:
- 'Astelehena'
- 'Asteartea'
- 'Azteazkena'
- 'Osteguna'
- 'Ostirala'
- 'Larunbata'
- 'Igandea'
+62
View File
@@ -0,0 +1,62 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\nعنوان: %1$s\n---\n\n# خطا: Frontmatter غلط\n\nمسیر: %2$s\n\n**%3$s**\n\n```\n%4$s\n```"
NICETIME:
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: هفته
YR_PLURAL: سال
DEC_PLURAL: دهه
FORM:
VALIDATION_FAIL: <b>سنجش اعتبار ناموفق بود</b>
INVALID_INPUT: ورودی نامعتبر در
MISSING_REQUIRED_FIELD: 'قسمت ضروری جا افتاده:'
MONTHS_OF_THE_YEAR:
- 'ژانویه'
- 'فوریه'
- 'مارس'
- 'آوریل'
- 'می'
- 'ژوئن'
- 'ژوئیه'
- 'اوت'
- 'سپتامبر'
- 'اکتبر'
- 'نوامبر'
- 'دسامبر'
DAYS_OF_THE_WEEK:
- 'دوشنبه'
- 'سه‌ شنبه'
- 'چهارشنبه'
- 'پنج شنبه'
- 'جمعه'
- 'شنبه'
- 'یک‌شنبه'
+133 -59
View File
@@ -1,60 +1,134 @@
--- ---
NICETIME: GRAV:
NO_DATE_PROVIDED: Päivämäärää ei annettu FRONTMATTER_ERROR_PAGE: "---\notsikko: %1$s\n---\n\n# Virhe: Virheellinen Frontmatter\n\nPolku: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
BAD_DATE: Virheellinen päivämäärä INFLECTOR_PLURALS:
AGO: sitten '/(quiz)$/i': '\1zes'
FROM_NOW: tästä lähtien '/^(ox)$/i': '\1en'
SECOND: sekunti '/([m|l])ouse$/i': '\1ice'
MINUTE: minuutti '/(matr|vert|ind)ix|ex$/i': '\1ices'
HOUR: tunti '/(x|ch|ss|sh)$/i': '\1es'
DAY: päivä '/([^aeiouy]|qu)ies$/i': '\1y'
WEEK: viikko '/([^aeiouy]|qu)y$/i': '\1ies'
MONTH: kuukausi '/(hive)$/i': '\1s'
YEAR: vuosi '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
DECADE: vuosikymmen '/sis$/i': 'ses'
SEC: sek '/([ti])um$/i': '\1a'
MIN: min '/(buffal|tomat)o$/i': '\1oes'
HR: h '/(bu)s$/i': '\1ses'
WK: vk '/(alias|status)/i': '\1es'
MO: kk '/(octop|vir)us$/i': '\1i'
YR: v '/(ax|test)is$/i': '\1es'
DEC: vuosikymmen '/s$/i': 's'
SECOND_PLURAL: sekuntia '/$/': 's'
MINUTE_PLURAL: minuuttia INFLECTOR_SINGULAR:
HOUR_PLURAL: tuntia '/(quiz)zes$/i': '\1'
DAY_PLURAL: päivää '/(matr)ices$/i': '\1ix'
WEEK_PLURAL: viikkoa '/(vert|ind)ices$/i': '\1ex'
MONTH_PLURAL: kuukautta '/^(ox)en/i': '\1'
YEAR_PLURAL: vuotta '/(alias|status)es$/i': '\1'
DECADE_PLURAL: vuosikymmentä '/([octop|vir])i$/i': '\1us'
SEC_PLURAL: sek '/(cris|ax|test)es$/i': '\1is'
MIN_PLURAL: min '/(shoe)s$/i': '\1'
HR_PLURAL: h '/(o)es$/i': '\1'
WK_PLURAL: v '/(bus)es$/i': '\1'
MO_PLURAL: kk '/([m|l])ice$/i': '\1ouse'
YR_PLURAL: v '/(x|ch|ss|sh)es$/i': '\1'
DEC_PLURAL: vuosikymmentä '/(m)ovies$/i': '\1ovie'
FORM: '/(s)eries$/i': '\1eries'
VALIDATION_FAIL: '<b>Vahvistus epäonnistui:</b>' '/([^aeiouy]|qu)ies$/i': '\1y'
MISSING_REQUIRED_FIELD: 'Puuttuva pakollinen kenttä:' '/([lr])ves$/i': '\1f'
MONTHS_OF_THE_YEAR: '/(tive)s$/i': '\1'
- Tammikuu '/(hive)s$/i': '\1'
- Helmikuu '/([^f])ves$/i': '\1fe'
- Maaliskuu '/(^analy)ses$/i': '\1sis'
- Huhtikuu '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
- Toukokuu '/([ti])a$/i': '\1um'
- Kesäkuuta '/(n)ews$/i': '\1ews'
- Heinäkuu INFLECTOR_UNCOUNTABLE:
- Elokuu - 'equipment'
- Syyskuu - 'information'
- Lokakuu - 'riisi'
- Marraskuu - 'raha'
- Joulukuu - 'lajit'
DAYS_OF_THE_WEEK: - 'series'
- Maanantai - 'kala'
- Tiistai - 'lammas'
- Keskiviikko INFLECTOR_IRREGULAR:
- Torstai 'person': 'ihmiset'
- Perjantai 'man': 'miehet'
- Lauantai 'child': 'lapset'
- Sunnuntai 'sex': 'sukupuoli'
INFLECTOR_ORDINALS:
'default': '.'
'first': '.'
'second': '.'
'third': '.'
NICETIME:
NO_DATE_PROVIDED: Päivämäärää ei annettu
BAD_DATE: Virheellinen päivämäärä
AGO: sitten
FROM_NOW: tästä lähtien
JUST_NOW: juuri nyt
SECOND: sekuntti
MINUTE: minuutti
HOUR: tunti
DAY: päivä
WEEK: viikko
MONTH: kuukausi
YEAR: vuosi
DECADE: vuosikymmen
SEC: sek
MIN: min
HR: h
WK: vk
MO: kk
YR: v
DEC: vuosikymmen
SECOND_PLURAL: sekuntia
MINUTE_PLURAL: minuuttia
HOUR_PLURAL: tuntia
DAY_PLURAL: päivää
WEEK_PLURAL: viikkoa
MONTH_PLURAL: kuukautta
YEAR_PLURAL: vuotta
DECADE_PLURAL: vuosikymmentä
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: h
WK_PLURAL: v
MO_PLURAL: kk
YR_PLURAL: v
DEC_PLURAL: vuosikymmentä
FORM:
VALIDATION_FAIL: <b>Vahvistus epäonnistui:</b>
INVALID_INPUT: Syöte ei kelpaa
MISSING_REQUIRED_FIELD: 'Puuttuva pakollinen kenttä:'
MONTHS_OF_THE_YEAR:
- 'Tammikuu'
- 'Helmikuu'
- 'Maaliskuu'
- 'Huhtikuu'
- 'Toukokuu'
- 'Kesäkuuta'
- 'Heinäkuu'
- 'Elokuu'
- 'Syyskuu'
- 'Lokakuu'
- 'Marraskuu'
- 'Joulukuu'
DAYS_OF_THE_WEEK:
- 'Maanantai'
- 'Tiistai'
- 'Keskiviikko'
- 'Torstai'
- 'Perjantai'
- 'Lauantai'
- 'Sunnuntai'
CRON:
EVERY: joka
EVERY_HOUR: joka tunti
EVERY_MINUTE: joka minuutti
EVERY_DAY_OF_WEEK: viikon jokaisena päivänä
EVERY_DAY_OF_MONTH: kuukauden jokaisena päivänä
EVERY_MONTH: joka kuukausi
TEXT_PERIOD: Joka <b />
+122 -137
View File
@@ -1,138 +1,123 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntitre: %1$s\n---\n\n# Erreur : Frontmatter invalide\n\nChemin: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s INFLECTOR_PLURALS:
--- '/(quiz)$/i': '\1zes'
'/^(ox)$/i': '\1en'
# Erreur : Frontmatter invalide '/([m|l])ouse$/i': '\1ice'
'/(matr|vert|ind)ix|ex$/i': '\1ices'
Path: `%2$s` '/(x|ch|ss|sh)$/i': '\1es'
'/([^aeiouy]|qu)ies$/i': '\1y'
**%3$s** '/([^aeiouy]|qu)y$/i': '\1ies'
'/(hive)$/i': '\1s'
``` '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
%4$s '/sis$/i': 'ses'
``` '/([ti])um$/i': '\1a'
INFLECTOR_PLURALS: '/(buffal|tomat)o$/i': '\1es'
/(quiz)$/i: '\1zes' '/(bu)s$/i': 'Bus'
/^(ox)$/i: '\1en' '/(alias|status)/i': 'alias|status'
"/([m|l])ouse$/i": '\1ice' '/(ax|test)is$/i': '\1s'
/(matr|vert|ind)ix|ex$/i: '\1ices' '/s$/i': 's'
/(x|ch|ss|sh)$/i: '\1es' '/$/': 's'
"/([^aeiouy]|qu)ies$/i": '\1y' INFLECTOR_SINGULAR:
"/([^aeiouy]|qu)y$/i": '\1ies' '/(quiz)zes$/i': '\1'
/(hive)$/i: '\1s' '/(alias|status)es$/i': '\1'
"/(?:([^f])fe|([lr])f)$/i": '\1\2ves' '/([octop|vir])i$/i': '\1us'
/sis$/i: ses INFLECTOR_UNCOUNTABLE:
"/([ti])um$/i": '\1a' - 'équipement'
/(buffal|tomat)o$/i: '\1oes' - 'information'
/(bu)s$/i: '\1ses' - 'riz'
/(alias|status)/i: '\1es' - 'argent'
/(octop|vir)us$/i: '\1i' - 'espèces'
/(ax|test)is$/i: '\1es' - 'séries'
/s$/i: s - 'poisson'
/$/: s - 'mouton'
INFLECTOR_SINGULAR: INFLECTOR_IRREGULAR:
/(quiz)zes$/i: '\1' 'person': 'personnes'
/(matr)ices$/i: '\1ix' 'man': 'hommes'
/(vert|ind)ices$/i: '\1ex' 'child': 'enfants'
/^(ox)en/i: '\1' 'sex': 'sexes'
/(alias|status)es$/i: '\1' 'move': 'déplacements'
"/([octop|vir])i$/i": '\1us' INFLECTOR_ORDINALS:
/(cris|ax|test)es$/i: '\1is' 'default': 'ème'
/(shoe)s$/i: '\1' 'first': 'er'
/(o)es$/i: '\1' 'second': 'ème'
/(bus)es$/i: '\1' 'third': 'ème'
"/([m|l])ice$/i": '\1ouse' NICETIME:
/(x|ch|ss|sh)es$/i: '\1' NO_DATE_PROVIDED: Aucune date fournie
/(m)ovies$/i: '\1ovie' BAD_DATE: Date erronée
/(s)eries$/i: '\1eries' AGO: plus tôt
"/([^aeiouy]|qu)ies$/i": '\1y' FROM_NOW: à partir de maintenant
"/([lr])ves$/i": '\1f' JUST_NOW: à l'instant
/(tive)s$/i: '\1' SECOND: seconde
/(hive)s$/i: '\1' MINUTE: minute
"/([^f])ves$/i": '\1fe' HOUR: heure
/(^analy)ses$/i: '\1sis' DAY: jour
/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i: '\1\2sis' WEEK: semaine
"/([ti])a$/i": '\1um' MONTH: mois
/(n)ews$/i: '\1ews' YEAR: année
INFLECTOR_UNCOUNTABLE: DECADE: décennie
- équipement SEC: s
- informations MIN: m
- riz HR: h
- argent WK: sem
- espèces MO: m
- séries YR: an
- poisson DEC: déc
- mouton SECOND_PLURAL: secondes
INFLECTOR_IRREGULAR: MINUTE_PLURAL: minutes
person: personnes HOUR_PLURAL: heures
man: hommes DAY_PLURAL: jours
child: enfants WEEK_PLURAL: semaines
sex: sexes MONTH_PLURAL: mois
move: déplacements YEAR_PLURAL: années
INFLECTOR_ORDINALS: DECADE_PLURAL: décennies
default: ème SEC_PLURAL: s
first: er MIN_PLURAL: m
second: ème HR_PLURAL: h
third: ème WK_PLURAL: sem
NICETIME: MO_PLURAL: mois
NO_DATE_PROVIDED: Aucune date fournie YR_PLURAL: a
BAD_DATE: Date erronée DEC_PLURAL: décs
AGO: plus tôt FORM:
FROM_NOW: à partir de maintenant VALIDATION_FAIL: <b>La validation a échoué :</b>
SECOND: seconde INVALID_INPUT: Saisie non valide
MINUTE: minute MISSING_REQUIRED_FIELD: 'Champ obligatoire manquant :'
HOUR: heure MONTHS_OF_THE_YEAR:
DAY: jour - 'Janvier'
WEEK: semaine - 'Février'
MONTH: mois - 'Mars'
YEAR: année - 'Avril'
DECADE: décennie - 'Mai'
SEC: s - 'Juin'
MIN: m - 'Juillet'
HR: h - 'Août'
WK: sem - 'Septembre'
MO: m - 'Octobre'
YR: an - 'Novembre'
DEC: déc - 'Décembre'
SECOND_PLURAL: secondes DAYS_OF_THE_WEEK:
MINUTE_PLURAL: minutes - 'Lundi'
HOUR_PLURAL: heures - 'Mardi'
DAY_PLURAL: jours - 'Mercredi'
WEEK_PLURAL: semaines - 'Jeudi'
MONTH_PLURAL: mois - 'Vendredi'
YEAR_PLURAL: années - 'Samedi'
DECADE_PLURAL: décennies - 'Dimanche'
SEC_PLURAL: s CRON:
MIN_PLURAL: m EVERY: chaque
HR_PLURAL: h EVERY_HOUR: toutes les heures
WK_PLURAL: sem EVERY_MINUTE: chaque minute
MO_PLURAL: mois EVERY_DAY_OF_WEEK: tous les jours de la semaine
YR_PLURAL: a EVERY_DAY_OF_MONTH: tous les jours du mois
DEC_PLURAL: décs EVERY_MONTH: chaque mois
FORM: TEXT_PERIOD: Chaque<b/>
VALIDATION_FAIL: '<b>La validation a échoué :</b>' TEXT_MINS: ' à <b /> minute(s) après l''heure'
INVALID_INPUT: Saisie non valide TEXT_TIME: ' à<b/>:<b/>'
MISSING_REQUIRED_FIELD: 'Champ obligatoire manquant :' TEXT_DOW: ' sur <b/>'
MONTHS_OF_THE_YEAR: TEXT_MONTH: ' de <b />'
- Janvier TEXT_DOM: ' sur <b/>'
- Février ERROR1: La balise %s n'est pas supportée!
- Mars ERROR2: Nombre invalide d'éléments
- Avril ERROR3: L'élément jquery_element doit être défini dans les paramètres jqCron
- Mai ERROR4: Expression non reconnue
- Juin
- Juillet
- Août
- Septembre
- Octobre
- Novembre
- Décembre
DAYS_OF_THE_WEEK:
- Lundi
- Mardi
- Mercredi
- Jeudi
- Vendredi
- Samedi
- Dimanche
+63
View File
@@ -0,0 +1,63 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\nכותרת: %1$s\n---\n# שגיאה: Fronmatter לא חוקי\nנתיב: `%2$s`\n**%3$s**\n```\n%4$s\n```"
NICETIME:
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:
- 'שני'
- 'שלישי'
- 'רביעי'
- 'חמישי'
- 'שישי'
- 'שבת'
- 'ראשון'
+75 -74
View File
@@ -1,75 +1,76 @@
--- ---
INFLECTOR_UNCOUNTABLE: GRAV:
- oprema INFLECTOR_UNCOUNTABLE:
- informacije - 'oprema'
- riža - 'informacije'
- novac - 'riža'
- vrsta - 'novac'
- serija - 'vrsta'
- riba - 'serija'
- ovca - 'riba'
INFLECTOR_IRREGULAR: - 'ovca'
person: osobe INFLECTOR_IRREGULAR:
man: ljudi 'person': 'osobe'
child: djeca 'man': 'ljudi'
sex: spolovi 'child': 'djeca'
move: Pomakni 'sex': 'spolovi'
NICETIME: 'move': 'Pomakni'
NO_DATE_PROVIDED: Datum nije upisan NICETIME:
BAD_DATE: Pogrešan datum NO_DATE_PROVIDED: Datum nije upisan
AGO: prije BAD_DATE: Pogrešan datum
FROM_NOW: od sada AGO: prije
SECOND: sekunda FROM_NOW: od sada
MINUTE: minuta SECOND: sekunda
HOUR: sat MINUTE: minuta
DAY: dan HOUR: sat
WEEK: tjedan DAY: dan
MONTH: mjesec WEEK: tjedan
YEAR: godina MONTH: mjesec
DECADE: desetljeće YEAR: godina
SEC: sek DECADE: desetljeće
HR: sat SEC: sek
WK: t HR: sat
MO: m WK: t
YR: g MO: m
DEC: des YR: g
SECOND_PLURAL: sekundi DEC: des
MINUTE_PLURAL: minuta SECOND_PLURAL: sekundi
HOUR_PLURAL: sati MINUTE_PLURAL: minuta
DAY_PLURAL: dan HOUR_PLURAL: sati
WEEK_PLURAL: tjedana DAY_PLURAL: dan
MONTH_PLURAL: mjeseci WEEK_PLURAL: tjedana
YEAR_PLURAL: godina MONTH_PLURAL: mjeseci
DECADE_PLURAL: desetljeća YEAR_PLURAL: godina
SEC_PLURAL: sek DECADE_PLURAL: desetljeća
MIN_PLURAL: min SEC_PLURAL: sek
HR_PLURAL: sat MIN_PLURAL: min
WK_PLURAL: t HR_PLURAL: sat
MO_PLURAL: m WK_PLURAL: t
YR_PLURAL: g MO_PLURAL: m
DEC_PLURAL: des YR_PLURAL: g
FORM: DEC_PLURAL: des
VALIDATION_FAIL: '<b>Validacija nije uspjela:</b>' FORM:
INVALID_INPUT: Pogrešan unos u VALIDATION_FAIL: <b>Validacija nije uspjela:</b>
MISSING_REQUIRED_FIELD: 'Nedostaje obavezno polje:' INVALID_INPUT: Pogrešan unos u
MONTHS_OF_THE_YEAR: MISSING_REQUIRED_FIELD: 'Nedostaje obavezno polje:'
- Siječanj MONTHS_OF_THE_YEAR:
- Veljača - 'Siječanj'
- Ožujak - 'Veljača'
- Travanj - 'Ožujak'
- Svibanj - 'Travanj'
- Lipanj - 'Svibanj'
- Srpanj - 'Lipanj'
- Kolovoz - 'Srpanj'
- Rujan - 'Kolovoz'
- Listopad - 'Rujan'
- Studeni - 'Listopad'
- Prosinac - 'Studeni'
DAYS_OF_THE_WEEK: - 'Prosinac'
- Ponedjeljak DAYS_OF_THE_WEEK:
- Utorak - 'Ponedjeljak'
- Srijeda - 'Utorak'
- Četvrtak - 'Srijeda'
- Petak - 'Četvrtak'
- Subota - 'Petak'
- Nedjelja - 'Subota'
- 'Nedjelja'
+96 -137
View File
@@ -1,138 +1,97 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- 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```"
cím: %1$s INFLECTOR_UNCOUNTABLE:
--- - 'felszerelés'
- 'információ'
# Hiba: Érvénytelen Frontmatter - 'rizs'
- 'pénz'
Elérési út: `%2$s` - 'fajok'
- 'sorozat'
**%3$s** - 'hal'
- 'juh'
``` INFLECTOR_IRREGULAR:
%4$s 'person': 'személyek'
``` 'man': 'férfiak'
INFLECTOR_PLURALS: 'child': 'gyerekek'
/(quiz)$/i: '\1zes' 'sex': 'nemek'
/^(ox)$/i: '\1en' 'move': 'lépések'
"/([m|l])ouse$/i": '\1ice' INFLECTOR_ORDINALS:
/(matr|vert|ind)ix|ex$/i: '\1ices' 'default': '.'
/(x|ch|ss|sh)$/i: '\1es' 'first': '.'
"/([^aeiouy]|qu)ies$/i": '\1y' 'second': '.'
"/([^aeiouy]|qu)y$/i": '\1ies' 'third': '.'
/(hive)$/i: '\1s' NICETIME:
"/(?:([^f])fe|([lr])f)$/i": '\1\2ves' NO_DATE_PROVIDED: Nincs dátum megadva
/sis$/i: ses BAD_DATE: Hibás dátum
"/([ti])um$/i": '\1a' AGO: elteltével
/(buffal|tomat)o$/i: '\1oes' FROM_NOW: mostantól
/(bu)s$/i: '\1ses' JUST_NOW: épp most
/(alias|status)/i: '\1es' SECOND: másodperc
/(octop|vir)us$/i: '\1i' MINUTE: perc
/(ax|test)is$/i: '\1es' HOUR: óra
/s$/i: s DAY: nap
/$/: s WEEK: hét
INFLECTOR_SINGULAR: MONTH: hónap
/(quiz)zes$/i: '\1' YEAR: év
/(matr)ices$/i: '\1ix' DECADE: évtized
/(vert|ind)ices$/i: '\1ex' SEC: mp
/^(ox)en/i: '\1' MIN: p
/(alias|status)es$/i: '\1' HR: ó
"/([octop|vir])i$/i": '\1us' WK: hét
/(cris|ax|test)es$/i: '\1is' MO:
/(shoe)s$/i: '\1' YR: év
/(o)es$/i: '\1' DEC: évt
/(bus)es$/i: '\1' SECOND_PLURAL: másodperc
"/([m|l])ice$/i": '\1ouse' MINUTE_PLURAL: perc
/(x|ch|ss|sh)es$/i: '\1' HOUR_PLURAL: óra
/(m)ovies$/i: '\1ovie' DAY_PLURAL: nap
/(s)eries$/i: '\1eries' WEEK_PLURAL: hét
"/([^aeiouy]|qu)ies$/i": '\1y' MONTH_PLURAL: hónap
"/([lr])ves$/i": '\1f' YEAR_PLURAL: év
/(tive)s$/i: '\1' DECADE_PLURAL: évtized
/(hive)s$/i: '\1' SEC_PLURAL: mp
"/([^f])ves$/i": '\1fe' MIN_PLURAL: perc
/(^analy)ses$/i: '\1sis' HR_PLURAL: ó
/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i: '\1\2sis' WK_PLURAL: hét
"/([ti])a$/i": '\1um' MO_PLURAL:
/(n)ews$/i: '\1ews' YR_PLURAL: év
INFLECTOR_UNCOUNTABLE: DEC_PLURAL: évt
- felszerelés FORM:
- információ VALIDATION_FAIL: <b>Érvényesítés nem sikerült:</b>
- rizs INVALID_INPUT: 'A megadott érték érvénytelen:'
- pénz MISSING_REQUIRED_FIELD: 'Ez a kötelező mező nincs kitöltve:'
- fajok MONTHS_OF_THE_YEAR:
- sorozat - 'január'
- hal - 'február'
- juh - 'március'
INFLECTOR_IRREGULAR: - 'április'
person: személyek - 'május'
man: férfiak - 'június'
child: gyerekek - 'július'
sex: nemek - 'augusztus'
move: lépések - 'szeptember'
INFLECTOR_ORDINALS: - 'október'
default: '.' - 'november'
first: '.' - 'december'
second: '.' DAYS_OF_THE_WEEK:
third: '.' - 'hétfő'
NICETIME: - 'kedd'
NO_DATE_PROVIDED: Nincs dátum megadva - 'szerda'
BAD_DATE: Hibás dátum - 'csütörtök'
AGO: elteltével - 'péntek'
FROM_NOW: mostantól - 'szombat'
SECOND: másodperc - 'vasárnap'
MINUTE: perc CRON:
HOUR: óra EVERY: minden
DAY: nap EVERY_HOUR: óránként
WEEK: t EVERY_MINUTE: percenként
MONTH: hónap EVERY_DAY_OF_WEEK: a hét minden napján
YEAR: év EVERY_DAY_OF_MONTH: a hónap minden napján
DECADE: évtized EVERY_MONTH: minden hónapban
SEC: mp TEXT_PERIOD: Minden <b />
MIN: p TEXT_MINS: '<b /> perccel az óra elteltével'
HR: ó ERROR1: A %s címke nem engedélyezett!
WK: hét ERROR2: Hibás elemszám
MO: ERROR3: A jquery_element-et a jqCron beállítsokban kell meghatározni
YR: év ERROR4: Ismeretlen kifejezés
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:
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:'
MONTHS_OF_THE_YEAR:
- január
- február
- március
- április
- május
- június
- július
- augusztus
- szeptember
- október
- november
- december
DAYS_OF_THE_WEEK:
- hétfő
- kedd
- szerda
- csütörtök
- péntek
- szombat
- vasárnap
+95
View File
@@ -0,0 +1,95 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Frontmatter tidak valid\n\nLokasi: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
INFLECTOR_UNCOUNTABLE:
- 'peralatan'
- 'informasi'
- 'nasi'
- 'uang'
- 'spesies'
- 'rangkaian'
- 'ikan'
- 'domba'
INFLECTOR_IRREGULAR:
'person': 'orang-orang'
'man': 'laki-laki'
'child': 'anak-anak'
'sex': 'jenis kelamin'
'move': 'pindahkan'
NICETIME:
NO_DATE_PROVIDED: Tanggal tidak tersedia
BAD_DATE: Format tanggal salah
AGO: yang lalu
FROM_NOW: dari saat ini
JUST_NOW: baru saja
SECOND: detik
MINUTE: menit
HOUR: jam
DAY: hari
WEEK: pekan
MONTH: bulan
YEAR: tahun
DECADE: dekade
SEC: dtk
MIN: mnt
HR: j
WK: mng
MO: bln
YR: thn
DEC: desimal
SECOND_PLURAL: detik
MINUTE_PLURAL: menit
HOUR_PLURAL: jam
DAY_PLURAL: hari
WEEK_PLURAL: pekan
MONTH_PLURAL: bulan
YEAR_PLURAL: tahun
DECADE_PLURAL: dekade
SEC_PLURAL: dtk
MIN_PLURAL: mnt
HR_PLURAL: j
WK_PLURAL: mgg
MO_PLURAL: bln
YR_PLURAL: thn
DEC_PLURAL: dekade
FORM:
VALIDATION_FAIL: <b>Validasi gagal:</b>
INVALID_INPUT: Input tidak valid di
MISSING_REQUIRED_FIELD: 'Data yang diperlukan belum terisi:'
MONTHS_OF_THE_YEAR:
- 'Januari'
- 'Februari'
- 'Maret'
- 'April'
- 'Mei'
- 'Juni'
- 'Juli'
- 'Agustus'
- 'September'
- 'Oktober'
- 'November'
- 'Desember'
DAYS_OF_THE_WEEK:
- 'Senin'
- 'Selasa'
- 'Rabu'
- 'Kamis'
- 'Jumat'
- 'Sabtu'
- 'Minggu'
CRON:
EVERY: Setiap
EVERY_HOUR: Setiap jam
EVERY_MINUTE: Setiap menit
EVERY_DAY_OF_WEEK: Setiap hari selama seminggu
EVERY_DAY_OF_MONTH: pada tanggal setiap bulannya
EVERY_MONTH: setiap bulan
TEXT_PERIOD: Setiap <b />
TEXT_TIME: ' pada <b />:<b />'
TEXT_DOW: ' pada <b />'
TEXT_MONTH: ' pada <b />'
TEXT_DOM: ' pada <b />'
ERROR1: Tag %s tidak didukung!
ERROR2: Jumlah elemen tidak valid
ERROR3: jquery_element harus ditetapkan ke pengaturan jqCron
ERROR4: Ekspresi tidak dikenali
+80
View File
@@ -0,0 +1,80 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\ntitill: %1$s\n---\n\n# Villa: Ógilt efni á forsíðu\n\nSlóð: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
INFLECTOR_UNCOUNTABLE:
- 'equipment'
- 'upplýsingar'
- 'rice'
- 'money'
- 'species'
- 'series'
- 'fish'
- 'sheep'
NICETIME:
NO_DATE_PROVIDED: Engin dagsetning gefin
BAD_DATE: Röng dagsetning
AGO: síðan
JUST_NOW: í þessu
SECOND: sekúndu
MINUTE: mínútu
HOUR: klukkustund
DAY: degi
WEEK: viku
MONTH: mánuði
YEAR: ári
DECADE: áratug
SEC: sek
MIN: mín
HR: klst
WK: vk
MO: mán
YR: ár
DEC: árat
SECOND_PLURAL: sekúndum
MINUTE_PLURAL: mínútum
HOUR_PLURAL: klukkustundum
DAY_PLURAL: dögum
WEEK_PLURAL: vikum
MONTH_PLURAL: mánuðum
YEAR_PLURAL: árum
DECADE_PLURAL: áratugum
SEC_PLURAL: sek
MIN_PLURAL: mín
HR_PLURAL: klst
WK_PLURAL: vik
MO_PLURAL: mán
YR_PLURAL: árum
DEC_PLURAL: árat
FORM:
VALIDATION_FAIL: <b>Sannvottun mistókst:</b>
INVALID_INPUT: Ógilt inntak í
MISSING_REQUIRED_FIELD: 'Vantar nauðsynlegan reit:'
MONTHS_OF_THE_YEAR:
- 'janúar'
- 'Febrúar'
- 'Mars'
- 'Apríl'
- 'Maí'
- 'Júní'
- 'Júlí'
- 'Ágúst'
- 'September'
- 'Október'
- 'Nóvember'
- 'Desember'
DAYS_OF_THE_WEEK:
- 'Mánudagur'
- 'Þriðjudagur'
- 'Miðvikudagur'
- 'Fimmtudagur'
- 'Föstudagur'
- 'Laugardagur'
- 'Sunnudagur'
CRON:
TEXT_TIME: ' á <b />:<b />'
TEXT_DOW: ' á <b />'
TEXT_MONTH: ' af <b />'
TEXT_DOM: ' á <b />'
ERROR1: Merkið %s er ekki stutt!
ERROR3: Það ætti að setja jquery_element inn í stillingar jqCron
ERROR4: Óþekkt segð
+100 -61
View File
@@ -1,62 +1,101 @@
--- ---
FRONTMATTER_ERROR_PAGE: "---Titolo: %1$s---# Errore: Frontmatter non valido: '%2$s' * *%3$s * * ' '%4$s ' '" GRAV:
NICETIME: FRONTMATTER_ERROR_PAGE: "---Titolo: %1$s---# Errore: Frontmatter non valido: '%2$s' * *%3$s * * ' '%4$s ' '"
NO_DATE_PROVIDED: Nessuna data fornita INFLECTOR_UNCOUNTABLE:
BAD_DATE: Data non valida - 'dotazione'
AGO: fa - 'informazione'
FROM_NOW: da adesso - 'riso'
SECOND: secondo - 'denaro'
MINUTE: minuto - 'specie'
HOUR: ora - 'serie'
DAY: giorno - 'pesce'
WEEK: settimana - 'pecora'
MONTH: mese INFLECTOR_IRREGULAR:
YEAR: anno 'person': 'persone'
DECADE: decennio 'man': 'uomini'
SEC: sec 'child': 'bambino'
MIN: min 'sex': 'sessi'
HR: ora 'move': 'sposta'
WK: settimana INFLECTOR_ORDINALS:
MO: mese 'default': '°'
YR: anno 'first': '°'
DEC: decennio 'second': 'o'
SECOND_PLURAL: secondi 'third': 'o'
MINUTE_PLURAL: minuti NICETIME:
HOUR_PLURAL: ore NO_DATE_PROVIDED: Nessuna data fornita
DAY_PLURAL: giorni BAD_DATE: Data non valida
WEEK_PLURAL: settimane AGO: fa
MONTH_PLURAL: mesi FROM_NOW: da adesso
YEAR_PLURAL: anni JUST_NOW: ora
DECADE_PLURAL: decadi SECOND: secondo
SEC_PLURAL: secondi MINUTE: minuto
MIN_PLURAL: minuti HOUR: ora
HR_PLURAL: ore DAY: giorno
WK_PLURAL: settimane WEEK: settimana
MO_PLURAL: mesi MONTH: mese
YR_PLURAL: anni YEAR: anno
DEC_PLURAL: decenni DECADE: decennio
FORM: SEC: sec
VALIDATION_FAIL: '<b>Validazione fallita:</b>' MIN: min
INVALID_INPUT: Input non valido in HR: ora
MISSING_REQUIRED_FIELD: 'Campo richiesto mancante:' WK: settimana
MONTHS_OF_THE_YEAR: MO: mese
- Gennaio YR: anno
- Febbraio DEC: decennio
- Marzo SECOND_PLURAL: secondi
- Aprile MINUTE_PLURAL: minuti
- Maggio HOUR_PLURAL: ore
- Giugno DAY_PLURAL: giorni
- Luglio WEEK_PLURAL: settimane
- Agosto MONTH_PLURAL: mesi
- Settembre YEAR_PLURAL: anni
- Ottobre DECADE_PLURAL: decadi
- Novembre SEC_PLURAL: secondi
- Dicembre MIN_PLURAL: minuti
DAYS_OF_THE_WEEK: HR_PLURAL: ore
- Lunedì WK_PLURAL: settimane
- Martedì MO_PLURAL: mesi
- Mercoledì YR_PLURAL: anni
- Giovedì DEC_PLURAL: decenni
- Venerdì FORM:
- Sabato VALIDATION_FAIL: <b>Validazione fallita:</b>
- Domenica INVALID_INPUT: Input non valido 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:
- 'Lunedì'
- 'Martedì'
- 'Mercoledì'
- 'Giovedì'
- 'Venerdì'
- 'Sabato'
- 'Domenica'
CRON:
EVERY: ogni
EVERY_HOUR: ogni ora
EVERY_MINUTE: ogni minuto
EVERY_DAY_OF_WEEK: ogni giorno della settimana
EVERY_DAY_OF_MONTH: ogni giorno del mese
EVERY_MONTH: ogni mese
TEXT_PERIOD: Ogni <b />
TEXT_MINS: ' a <b /> minuto(i) dall''inizio dell''ora'
TEXT_TIME: ' alle <b />:<b />'
TEXT_DOW: ' su <b />'
TEXT_MONTH: ' di <b />'
TEXT_DOM: ' di <b />'
ERROR1: Il tag %s non è supportato!
ERROR2: Numero di elementi non valido
ERROR3: Il jquery_element deve essere impostato nelle impostazioni di jqCron
ERROR4: Espressione non riconosciuta
+27 -18
View File
@@ -1,24 +1,15 @@
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```" ---
INFLECTOR_PLURALS: [] GRAV:
INFLECTOR_IRREGULAR:
INFLECTOR_SINGULAR: []
INFLECTOR_UNCOUNTABLE: []
INFLECTOR_IRREGULAR:
'person': 'みんな' 'person': 'みんな'
'man': '人' 'man': '人'
'child': '子供' 'child': '子供'
'sex': '性別' 'sex': '性別'
'move': '移動' 'move': '移動'
NICETIME:
INFLECTOR_ORDINALS: []
NICETIME:
NO_DATE_PROVIDED: 日付が設定されていません NO_DATE_PROVIDED: 日付が設定されていません
BAD_DATE: 不正な日付 BAD_DATE: 不正な日付
AGO: AGO:
FROM_NOW: from now
SECOND: SECOND:
MINUTE: MINUTE:
HOUR: HOUR:
@@ -33,7 +24,6 @@ NICETIME:
WK: WK:
MO: MO:
YR: YR:
DEC: dec
SECOND_PLURAL: SECOND_PLURAL:
MINUTE_PLURAL: MINUTE_PLURAL:
HOUR_PLURAL: HOUR_PLURAL:
@@ -49,9 +39,28 @@ NICETIME:
MO_PLURAL: MO_PLURAL:
YR_PLURAL: YR_PLURAL:
DEC_PLURAL: 10年 DEC_PLURAL: 10年
FORM: FORM:
VALIDATION_FAIL: <b>バリデーション失敗 :</b> VALIDATION_FAIL: <b>バリデーション失敗 :</b>
INVALID_INPUT: 不正な入力: INVALID_INPUT: 不正な入力:
MISSING_REQUIRED_FIELD: 必須項目が入力されていません: MISSING_REQUIRED_FIELD: '必須項目が入力されていません:'
MONTHS_OF_THE_YEAR: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'] MONTHS_OF_THE_YEAR:
DAYS_OF_THE_WEEK: ['月', '火', '水', '木', '金', '土', '日'] - '1月'
- '2月'
- '3月'
- '4月'
- '5月'
- '6月'
- '7月'
- '8月'
- '9月'
- '10月'
- '11月'
- '12月'
DAYS_OF_THE_WEEK:
- '月'
- '火'
- '水'
- '木'
- '金'
- '土'
- '日'
+63
View File
@@ -0,0 +1,63 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# 오류: 무효의 Frontmatter\n\n경로: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
NICETIME:
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:
- '월요일'
- '화요일'
- '수요일'
- '목요일'
- '금요일'
- '토요일'
- '일요일'
+77 -68
View File
@@ -1,69 +1,78 @@
--- ---
INFLECTOR_UNCOUNTABLE: GRAV:
2: ryžiai FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Klaida: klaidinga įžanginė konfigūracija\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n %4$s\n```"
3: pinigai INFLECTOR_UNCOUNTABLE:
4: prieskoniai - 'equipment'
5: serijos - 'information'
6: žuvis - 'ryžiai'
7: avis - 'pinigai'
INFLECTOR_IRREGULAR: - 'prieskoniai'
person: žmonės - 'serijos'
man: žmogus - 'žuvis'
child: vaikai - 'avis'
sex: lytys INFLECTOR_IRREGULAR:
move: juda 'person': 'žmonės'
NICETIME: 'man': 'žmogus'
NO_DATE_PROVIDED: Nenurodyta data 'child': 'vaikai'
BAD_DATE: Neteisinga data 'sex': 'lytys'
AGO: prieš 'move': 'juda'
FROM_NOW: nuo dabar NICETIME:
SECOND: sekundė NO_DATE_PROVIDED: Nenurodyta data
MINUTE: minutė BAD_DATE: Neteisinga data
HOUR: valanda AGO: prieš
DAY: diena FROM_NOW: nuo dabar
WEEK: savaitė SECOND: sekundė
MONTH: mėnuo MINUTE: minu
YEAR: metai HOUR: valanda
DECADE: dešimtmetis DAY: diena
SEC: sek WEEK: savaitė
MIN: min MONTH: mėnuo
HR: val YEAR: metai
WK: sav DECADE: dešimtmetis
MO: mėn SEC: sek.
YR: m MIN: min.
MINUTE_PLURAL: minutės HR: val.
HOUR_PLURAL: valandos WK: sav.
DAY_PLURAL: dienos MO: mėn.
WEEK_PLURAL: savaitės YR: m.
MONTH_PLURAL: mėnesiai DEC: dešimtmetis
YEAR_PLURAL: metai SECOND_PLURAL: sekundės
DECADE_PLURAL: dešimtmečiai MINUTE_PLURAL: minutės
SEC_PLURAL: sek HOUR_PLURAL: valandos
MIN_PLURAL: min DAY_PLURAL: dienos
HR_PLURAL: val WEEK_PLURAL: savaitės
WK_PLURAL: sav MONTH_PLURAL: mėnesiai
MO_PLURAL: mėn YEAR_PLURAL: metai
YR_PLURAL: m DECADE_PLURAL: dešimtmečiai
FORM: SEC_PLURAL: sek.
MISSING_REQUIRED_FIELD: 'Būtina užpildyti laukelį:' MIN_PLURAL: min.
MONTHS_OF_THE_YEAR: HR_PLURAL: val.
- Sausis WK_PLURAL: sav.
- Vasaris MO_PLURAL: mėn.
- Kovas YR_PLURAL: m.
- Balandis DEC_PLURAL: dešimtmečiai
- Gegužė FORM:
- Birželis VALIDATION_FAIL: <b>Patvirtinimas nepavyko:</b>
- Liepa INVALID_INPUT: Neteisingai įvesta į
- Rugpjūtis MISSING_REQUIRED_FIELD: 'Būtina užpildyti laukelį:'
- Rugsėjis MONTHS_OF_THE_YEAR:
- Spalis - 'Sausis'
- Lakpritis - 'Vasaris'
- Gruodis - 'Kovas'
DAYS_OF_THE_WEEK: - 'Balandis'
- Pirmadienis - 'Gegužė'
- Antradienis - 'Birželis'
- Trečiadienis - 'Liepa'
- Ketvirtadienis - 'Rugpjūtis'
- Penktadienis - 'Rugsėjis'
- Šeštadienis - 'Spalis'
- Sekmadienis - 'Lakpritis'
- 'Gruodis'
DAYS_OF_THE_WEEK:
- 'Pirmadienis'
- 'Antradienis'
- 'Trečiadienis'
- 'Ketvirtadienis'
- 'Penktadienis'
- 'Šeštadienis'
- 'Sekmadienis'
+4 -2
View File
@@ -1,2 +1,4 @@
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'] GRAV:
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']
+143 -63
View File
@@ -1,64 +1,144 @@
--- ---
INFLECTOR_IRREGULAR: GRAV:
person: personen FRONTMATTER_ERROR_PAGE: "---\ntitel: %1$s\n---\n\n# Fout: ongeldige frontmatter\n\nPad: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
man: mensen INFLECTOR_PLURALS:
child: kinderen '/(quiz)$/i': '\1zes'
sex: geslacht '/^(ox)$/i': '\1en'
move: verplaatsen '/([m|l])ouse$/i': '\1ice'
NICETIME: '/(matr|vert|ind)ix|ex$/i': '\1ices'
NO_DATE_PROVIDED: geen datum opgegeven '/(x|ch|ss|sh)$/i': '\1es'
BAD_DATE: Datumformaat onjuist '/([^aeiouy]|qu)ies$/i': '\1y'
AGO: geleden '/([^aeiouy]|qu)y$/i': '\1ies'
FROM_NOW: vanaf nu '/(hive)$/i': '\1s'
SECOND: seconde '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
MINUTE: minuut '/sis$/i': 'ses'
HOUR: uur '/([ti])um$/i': '\1a'
DAY: dag '/(buffal|tomat)o$/i': '\1oes'
WEEK: week '/(bu)s$/i': '\1ses'
MONTH: maand '/(alias|status)/i': '\1es'
YEAR: jaar '/(octop|vir)us$/i': '\1i'
DECADE: decenium '/(ax|test)is$/i': '\1es'
SEC: s '/s$/i': 's'
MIN: min '/$/': 's'
HR: u INFLECTOR_SINGULAR:
MO: ma '/(quiz)zes$/i': '\1'
YR: j '/(matr)ices$/i': '\1ix'
SECOND_PLURAL: seconden '/(vert|ind)ices$/i': '\1ex'
MINUTE_PLURAL: minuten '/^(ox)en/i': '\1'
HOUR_PLURAL: uren '/(alias|status)es$/i': '\1'
DAY_PLURAL: dagen '/([octop|vir])i$/i': '\1us'
WEEK_PLURAL: weken '/(cris|ax|test)es$/i': '\1is'
MONTH_PLURAL: maanden '/(shoe)s$/i': '\1'
YEAR_PLURAL: jaren '/(o)es$/i': '\1'
DECADE_PLURAL: decennia '/(bus)es$/i': '\1'
SEC_PLURAL: seconden '/([m|l])ice$/i': '\1ouse'
MIN_PLURAL: minuten '/(x|ch|ss|sh)es$/i': '\1'
HR_PLURAL: uren '/(m)ovies$/i': '\1ovie'
WK_PLURAL: weken '/(s)eries$/i': '\1eries'
MO_PLURAL: maanden '/([^aeiouy]|qu)ies$/i': '\1y'
YR_PLURAL: jaren '/([lr])ves$/i': '\1f'
FORM: '/(tive)s$/i': '\1'
VALIDATION_FAIL: '<b>Validatie mislukt:</b>' '/(hive)s$/i': '\1'
INVALID_INPUT: Ongeldige invoer in '/([^f])ves$/i': '\1fe'
MISSING_REQUIRED_FIELD: 'Verplicht veld ontbreekt:' '/(^analy)ses$/i': '\1sis'
MONTHS_OF_THE_YEAR: '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i': '\1\2sis'
- Januari '/([ti])a$/i': '\1um'
- Februari '/(n)ews$/i': '\1ews'
- Maart INFLECTOR_UNCOUNTABLE:
- april - 'uitrusting'
- Mei - 'informatie'
- Juni - 'rijst'
- Juli - 'geld'
- Augustus - 'soorten'
- september - 'reeks'
- Oktober - 'vis'
- november - 'schaap'
- december INFLECTOR_IRREGULAR:
DAYS_OF_THE_WEEK: 'person': 'personen'
- Maandag 'man': 'mensen'
- Dinsdag 'child': 'kinderen'
- Woensdag 'sex': 'geslacht'
- Donderdag 'move': 'verplaatsen'
- Vrijdag INFLECTOR_ORDINALS:
- Zaterdag 'default': 'th'
- Zondag 'first': 'st'
'second': 'nd'
'third': 'rd'
NICETIME:
NO_DATE_PROVIDED: geen datum opgegeven
BAD_DATE: Datumformaat onjuist
AGO: geleden
FROM_NOW: vanaf nu
JUST_NOW: zojuist
SECOND: seconde
MINUTE: minuut
HOUR: uur
DAY: dag
WEEK: week
MONTH: maand
YEAR: jaar
DECADE: decennium
SEC: s
MIN: min
HR: u
WK: week
MO: ma
YR: j
DEC: decennia
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
DEC_PLURAL: decennia
FORM:
VALIDATION_FAIL: <b>Validatie mislukt:</b>
INVALID_INPUT: Ongeldige invoer in
MISSING_REQUIRED_FIELD: 'Ontbrekend verplicht veld:'
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'
CRON:
EVERY: elke
EVERY_HOUR: elk uur
EVERY_MINUTE: elke minuut
EVERY_DAY_OF_WEEK: elke dag van de week
EVERY_DAY_OF_MONTH: elke dag van de maand
EVERY_MONTH: elke maand
TEXT_PERIOD: Elke <b />
TEXT_MINS: ' <b /> minuten te laat'
TEXT_TIME: ' op <b />:<b />'
TEXT_DOW: ' op <b />'
TEXT_MONTH: ' van <b />'
TEXT_DOM: ' op <b />'
ERROR1: De tag %s wordt niet ondersteund!
ERROR2: Slecht aantal elementen
ERROR3: Het jquery_element moet ingesteld worden in de jqCron instellingen
ERROR4: Onbekende expressie
+76 -92
View File
@@ -1,93 +1,77 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\nTittel: %1$s\n---\n\n# Feilmelding: Ugyldig Frontmatter\n\nSti: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
Tittel: %1$s INFLECTOR_UNCOUNTABLE:
--- - 'utstyr'
- 'informasjon'
# Feilmelding: Ugyldig Frontmatter - 'ris'
- 'penger'
Pane: '%2$s' - 'arter'
- 'serier'
**%3$s ** - 'fisk'
- 'sau'
``` INFLECTOR_IRREGULAR:
%4$s 'person': 'folk'
``` 'man': 'menn'
INFLECTOR_PLURALS: 'child': 'barn'
/(quiz)$/i: '\1zes' 'sex': 'kjønn'
/^(ox)$/i: '\1en' 'move': 'trekk'
INFLECTOR_UNCOUNTABLE: NICETIME:
- utstyr NO_DATE_PROVIDED: Ingen dato gitt
- informasjon BAD_DATE: Ugyldig dato
- ris AGO: siden
- penger FROM_NOW: fra nå
- arter SECOND: sekund
- serier MINUTE: minutt
- fisk HOUR: time
- sau DAY: dag
INFLECTOR_IRREGULAR: WEEK: uke
person: folk MONTH: måned
man: menn YEAR: år
child: barn DECADE: tiår
sex: kjønn SEC: sek
move: trekk HR: t
NICETIME: WK: uke
NO_DATE_PROVIDED: Ingen dato gitt MO:
BAD_DATE: Dårlig dato YR: år
AGO: siden DEC: tiår
FROM_NOW: fra nå SECOND_PLURAL: sekunder
SECOND: sekund MINUTE_PLURAL: minutter
MINUTE: minutt HOUR_PLURAL: timer
HOUR: time DAY_PLURAL: dager
DAY: dag WEEK_PLURAL: uker
WEEK: uke MONTH_PLURAL: måneder
MONTH: måned YEAR_PLURAL: år
YEAR: år DECADE_PLURAL: tiår
DECADE: tiår SEC_PLURAL: sek
SEC: sek MIN_PLURAL: min
MIN: min HR_PLURAL: timer
HR: t WK_PLURAL: uker
WK: uke MO_PLURAL: md
MO: må YR_PLURAL: år
YR: år DEC_PLURAL: årtier
DEC: des FORM:
SECOND_PLURAL: sekunder VALIDATION_FAIL: <b>Godkjenning mislyktes:</b>
MINUTE_PLURAL: minutter INVALID_INPUT: Ugyldig innhold i
HOUR_PLURAL: timer MISSING_REQUIRED_FIELD: 'Mangler påkrevd felt:'
DAY_PLURAL: dager MONTHS_OF_THE_YEAR:
WEEK_PLURAL: uker - 'januar'
MONTH_PLURAL: måneder - 'februar'
YEAR_PLURAL: år - 'mars'
DECADE_PLURAL: tiår - 'april'
SEC_PLURAL: sek - 'mai'
MIN_PLURAL: min - 'juni'
HR_PLURAL: timer - 'juli'
WK_PLURAL: uker - 'august'
MO_PLURAL: mdr - 'september'
YR_PLURAL: år - 'oktober'
DEC_PLURAL: årtier - 'november'
FORM: - 'desember'
VALIDATION_FAIL: '<b>Validering mislyktes:</b>' DAYS_OF_THE_WEEK:
INVALID_INPUT: Ugyldig innhold i - 'mandag'
MISSING_REQUIRED_FIELD: 'Mangler påkrevd felt:' - 'tirsdag'
MONTHS_OF_THE_YEAR: - 'onsdag'
- januar - 'torsdag'
- februar - 'fredag'
- mars - 'lørdag'
- april - 'søndag'
- mai
- juni
- juli
- august
- september
- oktober
- november
- desember
DAYS_OF_THE_WEEK:
- mandag
- tirsdag
- onsdag
- torsdag
- fredag
- lørdag
- søndag
+61 -74
View File
@@ -1,75 +1,62 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Error: Nieprawidłowy Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s NICETIME:
--- NO_DATE_PROVIDED: Nie podano daty
BAD_DATE: Zła data
# Error: Nieprawidłowy Frontmatter AGO: temu
FROM_NOW: od teraz
Path: `%2$s` SECOND: sekunda
MINUTE: minuta
**%3$s** HOUR: godzina
DAY: dzień
``` WEEK: tydzień
%4$s MONTH: miesiąc
``` YEAR: rok
NICETIME: DECADE: dekada
NO_DATE_PROVIDED: Nie podano daty SEC: sek
BAD_DATE: Zła data HR: godz
AGO: temu WK: tydz
FROM_NOW: od teraz MO: m-c
SECOND: sekunda YR: rok
MINUTE: minuta DEC: dekada
HOUR: godzina SECOND_PLURAL: sekund
DAY: dzień MINUTE_PLURAL: minut
WEEK: tydzień HOUR_PLURAL: godzin
MONTH: miesiąc DAY_PLURAL: dni
YEAR: rok WEEK_PLURAL: tygodnie
DECADE: dekada MONTH_PLURAL: miesięcy
SEC: sek YEAR_PLURAL: lat
MIN: min DECADE_PLURAL: dekad
HR: godz SEC_PLURAL: sek
WK: tydz MIN_PLURAL: min
MO: m-c HR_PLURAL: godz
YR: rok WK_PLURAL: tyg
DEC: dekada MO_PLURAL: m-ce
SECOND_PLURAL: sekund YR_PLURAL: lat
MINUTE_PLURAL: minut DEC_PLURAL: dekad
HOUR_PLURAL: godzin FORM:
DAY_PLURAL: dni VALIDATION_FAIL: <b>Weryfikacja nie powiodła się:</b>
WEEK_PLURAL: tygodnie INVALID_INPUT: Nieprawidłowe dane wejściowe
MONTH_PLURAL: miesięcy MISSING_REQUIRED_FIELD: 'Opuszczono wymagane pole:'
YEAR_PLURAL: lat MONTHS_OF_THE_YEAR:
DECADE_PLURAL: dekad - 'Styczeń'
SEC_PLURAL: sek - 'Luty'
MIN_PLURAL: min - 'Marzec'
HR_PLURAL: godz - 'Kwiecień'
WK_PLURAL: tyg - 'Maj'
MO_PLURAL: m-ce - 'Czerwiec'
YR_PLURAL: lat - 'Lipiec'
DEC_PLURAL: dekad - 'Sierpień'
FORM: - 'Wrzesień'
VALIDATION_FAIL: '<b>Weryfikacja nie powiodła się:</b>' - 'Październik'
INVALID_INPUT: Nieprawidłowe dane wejściowe - 'Listopad'
MISSING_REQUIRED_FIELD: 'Opuszczono wymagane pole:' - 'Grudzień'
MONTHS_OF_THE_YEAR: DAYS_OF_THE_WEEK:
- Styczeń - 'Poniedziałek'
- Luty - 'Wtorek'
- Marzec - 'Środa'
- Kwiecień - 'Czwartek'
- Maj - 'Piątek'
- Czerwiec - 'Sobota'
- Lipiec - 'Niedziela'
- Sierpień
- Wrzesień
- Październik
- Listopad
- Grudzień
DAYS_OF_THE_WEEK:
- Poniedziałek
- Wtorek
- Środa
- Czwartek
- Piątek
- Sobota
- Niedziela
+45 -78
View File
@@ -1,79 +1,46 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- NICETIME:
título: %1$s NO_DATE_PROVIDED: Nenhuma data fornecida
--- AGO: atrás
SECOND: segundo
# Erro: Frontmatter inválida MINUTE: minuto
HOUR: hora
Caminho: `%2$s` DAY: dia
WEEK: semana
**%3$s** MONTH: mês
YEAR: ano
``` DECADE: década
%4$s SEC: segundos
``` MIN: minutos
INFLECTOR_UNCOUNTABLE: MINUTE_PLURAL: minutos
1: informação DAY_PLURAL: dias
2: arroz WEEK_PLURAL: semanas
3: dinheiro MONTH_PLURAL: meses
INFLECTOR_IRREGULAR: YEAR_PLURAL: anos
man: homens DECADE_PLURAL: decadas
sex: sexos FORM:
NICETIME: VALIDATION_FAIL: <b>Falha na validação!</b>
NO_DATE_PROVIDED: Não foi fornecida data MISSING_REQUIRED_FIELD: 'Campo obrigatório requerido:'
BAD_DATE: Data inválida MONTHS_OF_THE_YEAR:
AGO: atrás - 'Janeiro'
FROM_NOW: a partir de agora - 'Fevereiro'
SECOND: segundo - 'Março'
MINUTE: minuto - 'Abril'
HOUR: hora - 'Maio'
DAY: dia - 'Junho'
WEEK: semana - 'Julho'
MONTH: mês - 'Agosto'
YEAR: ano - 'Setembro'
DECADE: década - 'Outubro'
SEC: seg - 'Novembro'
MIN: mín - 'Dezembro'
HR: h INFLECTOR_UNCOUNTABLE:
WK: sem - 'equipment'
MO: m - 'information'
YR: a - 'arroz'
DEC: dec - 'money'
SECOND_PLURAL: segundos - 'species'
MINUTE_PLURAL: minutos - 'series'
HOUR_PLURAL: horas - 'fish'
DAY_PLURAL: dias - 'sheep'
WEEK_PLURAL: semanas
MONTH_PLURAL: meses
YEAR_PLURAL: anos
DECADE_PLURAL: décadas
SEC_PLURAL: seg
MIN_PLURAL: mins
HR_PLURAL: hrs
WK_PLURAL: sems
YR_PLURAL: anos
FORM:
VALIDATION_FAIL: '<b>Validação falhada: </b>'
MISSING_REQUIRED_FIELD: 'Campo obrigatório ausente:'
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
+95 -100
View File
@@ -1,101 +1,96 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\nTitlu: %1$s\n---\n# Eroare: Frontmatter este invalid\n\nCalea: `%2$s`\n\n**%3$s**\n\n```\n%4$s"
Titlu: %1$s INFLECTOR_UNCOUNTABLE:
--- - 'echipament'
# Eroare: Frontmatter este invalid - 'informaţie'
- 'orez'
Calea: `%2$s` - 'bani'
- 'specii'
**%3$s** - 'serii'
- 'peşte'
``` - 'oaie'
%4$s INFLECTOR_IRREGULAR:
INFLECTOR_PLURALS: 'person': 'persoane'
/(quiz)$/i: '\1zes' 'man': 'bărbați'
/^(ox)$/i: '\1en' 'child': 'copii'
"/([m|l])ouse$/i": '\1ice' 'sex': 'sexe'
/(matr|vert|ind)ix|ex$/i: '\1ices' 'move': 'mutări'
/(x|ch|ss|sh)$/i: '\1es' NICETIME:
"/([^aeiouy]|qu)ies$/i": '\1y' NO_DATE_PROVIDED: Nu există o dată prevăzută
"/([^aeiouy]|qu)y$/i": '\1ies' BAD_DATE: Dată incorectă
/(hive)$/i: '\1s' AGO: în urmă
"/(?:([^f])fe|([lr])f)$/i": '\1\2ves' FROM_NOW: de acum
/sis$/i: ses JUST_NOW: chiar acum
"/([ti])um$/i": '\1a' SECOND: secundă
/(buffal|tomat)o$/i: '\1oes' MINUTE: minut
INFLECTOR_UNCOUNTABLE: HOUR: oră
- echipament DAY: zi
- informaţie WEEK: săptămână
- orez MONTH: lună
- bani YEAR: an
- specii DECADE: decadă
- serii SEC: secunde
- peşte MIN: minute
- oaie HR: oră
INFLECTOR_IRREGULAR: WK: săpt
person: persoane MO: lună
man: bărbați YR: an
child: copii DEC: decadă
sex: sexe SECOND_PLURAL: secunde
move: mutări MINUTE_PLURAL: minute
NICETIME: HOUR_PLURAL: ore
NO_DATE_PROVIDED: Nu există o dată prevăzută DAY_PLURAL: zile
BAD_DATE: Dată incorectă WEEK_PLURAL: săptămâni
AGO: în urmă MONTH_PLURAL: luni
FROM_NOW: de acum YEAR_PLURAL: ani
SECOND: secundă DECADE_PLURAL: decade
MINUTE: minut SEC_PLURAL: sec
HOUR: oră MIN_PLURAL: min
DAY: zi HR_PLURAL: ore
WEEK: săptămână WK_PLURAL: săpt
MONTH: lună MO_PLURAL: luni
YEAR: an YR_PLURAL: ani
DECADE: decadă DEC_PLURAL: decenii
SEC: sec FORM:
MIN: min VALIDATION_FAIL: <b>Validare nereușită</b>
HR: oră INVALID_INPUT: Date incorecte în
WK: săpt MISSING_REQUIRED_FIELD: 'Câmp obligatoriu lipsă:'
MO: lună MONTHS_OF_THE_YEAR:
YR: an - 'Ianuarie'
DEC: decadă - 'Februarie'
SECOND_PLURAL: secunde - 'Martie'
MINUTE_PLURAL: minute - 'Aprilie'
HOUR_PLURAL: ore - 'Mai'
DAY_PLURAL: zile - 'Iunie'
WEEK_PLURAL: săptămâni - 'Iulie'
MONTH_PLURAL: luni - 'August'
YEAR_PLURAL: ani - 'Septembrie'
DECADE_PLURAL: decade - 'Octombrie'
SEC_PLURAL: sec - 'Noiembrie'
MIN_PLURAL: min - 'Decembrie'
HR_PLURAL: ore DAYS_OF_THE_WEEK:
WK_PLURAL: săpt - 'Luni'
MO_PLURAL: luni - 'Marți'
YR_PLURAL: ani - 'Miercuri'
DEC_PLURAL: decenii - 'Joi'
FORM: - 'Vineri'
VALIDATION_FAIL: '<b>Validare nereușită</b>' - 'Sâmbătă'
INVALID_INPUT: Date incorecte în - 'Duminică'
MISSING_REQUIRED_FIELD: 'Câmp obligatoriu lipsă:' CRON:
MONTHS_OF_THE_YEAR: EVERY: la fiecare
- Ianuarie EVERY_HOUR: la fiecare oră
- Februarie EVERY_MINUTE: la fiecare minut
- Martie EVERY_DAY_OF_WEEK: fiecare zi a săptămânii
- Aprilie EVERY_DAY_OF_MONTH: fiecare zi a lunii
- Mai EVERY_MONTH: fiecare lună
- Iunie TEXT_PERIOD: Fiecare <b />
- Iulie TEXT_MINS: ' la <b /> minut(e) ale fiecărei ore'
- August TEXT_TIME: ' la <b />:<b />'
- Septembrie TEXT_DOW: ' pe <b />'
- Octombrie TEXT_MONTH: 'al(e) <b />'
- Noiembrie TEXT_DOM: ' pe <b />'
- Decembrie ERROR1: Eticheta %s nu este acceptată!
DAYS_OF_THE_WEEK: ERROR2: Număr nevalid de elemente
- Luni ERROR3: jquery_element ar trebui setat în opțiunile jqCron
- Marți ERROR4: Expresie necunoscută
- Miercuri
- Joi
- Vineri
- Sâmbătă
- Duminică
+100 -80
View File
@@ -1,81 +1,101 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Ошибка: недопустимое содержимое Frontmatter\n\nПуть: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s INFLECTOR_UNCOUNTABLE:
--- - 'экипировка'
- 'информация'
# Ошибка: Недопустимое содержимое - 'рис'
- 'деньги'
Path: `%2$s` - 'виды'
- 'серии'
**%3$s** - 'рыба'
- 'овца'
``` INFLECTOR_IRREGULAR:
%4$s 'person': 'люди'
``` 'man': 'человек'
INFLECTOR_IRREGULAR: 'child': 'ребенок'
person: люди 'sex': 'пол'
man: человек 'move': 'движется'
child: ребенок INFLECTOR_ORDINALS:
sex: пол 'default': 'й'
move: движется 'first': 'й'
NICETIME: 'second': 'й'
NO_DATE_PROVIDED: Дата не указана 'third': 'й'
BAD_DATE: Неверная дата NICETIME:
AGO: назад NO_DATE_PROVIDED: Дата не указана
FROM_NOW: теперь BAD_DATE: Неверная дата
SECOND: секунда AGO: назад
MINUTE: минута FROM_NOW: теперь
HOUR: час JUST_NOW: только что
DAY: д SECOND: секунда
WEEK: неделя MINUTE: минута
MONTH: месяц HOUR: час
YEAR: год DAY: день
DECADE: десятилетие WEEK: неделя
SEC: с MONTH: месяц
MIN: мин YEAR: год
HR: ч DECADE: десятилетие
WK: нед. SEC: сек
MO: мес. MIN: мин
YR: г. HR: ч
DEC: гг. WK: нед
SECOND_PLURAL: секунды MO: мес
MINUTE_PLURAL: минуты YR: г
HOUR_PLURAL: часы DEC: дстлт
DAY_PLURAL: д SECOND_PLURAL: сек
WEEK_PLURAL: недели MINUTE_PLURAL: мин
MONTH_PLURAL: месяцы HOUR_PLURAL: ч
YEAR_PLURAL: годы DAY_PLURAL: д
DECADE_PLURAL: десятилетия WEEK_PLURAL: нед
SEC_PLURAL: с MONTH_PLURAL: мес
MIN_PLURAL: мин YEAR_PLURAL: г
HR_PLURAL: ч DECADE_PLURAL: дстлт
WK_PLURAL: нед SEC_PLURAL: сек
MO_PLURAL: мес MIN_PLURAL: мин
YR_PLURAL: г. HR_PLURAL: ч
DEC_PLURAL: гг. WK_PLURAL: нед
FORM: MO_PLURAL: мес
VALIDATION_FAIL: '<b>Проверка не удалась:</b>' YR_PLURAL: г
INVALID_INPUT: Неверный ввод в DEC_PLURAL: дстлт
MISSING_REQUIRED_FIELD: 'Отсутствует необходимое поле:' FORM:
MONTHS_OF_THE_YEAR: VALIDATION_FAIL: <b>Проверка не удалась:</b>
- Январь INVALID_INPUT: Неверный ввод в
- Февраль MISSING_REQUIRED_FIELD: 'Отсутствует необходимое поле:'
- Март MONTHS_OF_THE_YEAR:
- Апрель - 'январь'
- Май - 'февраль'
- Июнь - 'март'
- Июль - 'апрель'
- Август - 'май'
- Сентябрь - 'июнь'
- Октябрь - 'Июль'
- Ноябрь - 'Август'
- Декабрь - 'Сентябрь'
DAYS_OF_THE_WEEK: - 'Октябрь'
- Понедельник - 'Ноябрь'
- Вторник - 'Декабрь'
- Среда DAYS_OF_THE_WEEK:
- Четверг - 'понедельник'
- Пятница - 'вторник'
- Суббота - 'среда'
- Воскресенье - 'четверг'
- 'пятница'
- 'суббота'
- 'воскресенье'
CRON:
EVERY: раз в
EVERY_HOUR: раз в час
EVERY_MINUTE: раз в минуту
EVERY_DAY_OF_WEEK: каждый день недели
EVERY_DAY_OF_MONTH: каждый день недели
EVERY_MONTH: раз в месяц
TEXT_PERIOD: Каждый <b />
TEXT_MINS: ' в <b /> минуте(ах) за час'
TEXT_TIME: ' в <b />:<b />'
TEXT_DOW: ' на <b />'
TEXT_MONTH: ' из <b />'
TEXT_DOM: ' на <b />'
ERROR1: Тег %s не поддерживается!
ERROR2: Неверное количество элементов
ERROR3: jquery_element должен быть установлен в настройки jqCron
ERROR4: Выражение не распознано
+143 -41
View File
@@ -1,42 +1,144 @@
--- ---
NICETIME: GRAV:
NO_DATE_PROVIDED: Neposkytnutý žiaden dátum FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Chyba: Chybný frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
BAD_DATE: Nesprávny dátum INFLECTOR_PLURALS:
AGO: pred '/(quiz)$/i': '\1zes'
FROM_NOW: odteraz '/^(ox)$/i': '\1en'
SECOND: sekunda '/([m|l])ouse$/i': '\1ice'
MINUTE: minúta '/(matr|vert|ind)ix|ex$/i': '\1ices'
HOUR: hodina '/(x|ch|ss|sh)$/i': '\1es'
DAY: deň '/([^aeiouy]|qu)ies$/i': '\1y'
WEEK: týždeň '/([^aeiouy]|qu)y$/i': '\1ies'
MONTH: mesiac '/(hive)$/i': '\1s'
YEAR: rok '/(?:([^f])fe|([lr])f)$/i': '\1\2ves'
DECADE: desaťročie '/sis$/i': 'ses'
SEC: sek '/([ti])um$/i': '\1a'
MIN: min '/(buffal|tomat)o$/i': '\1oes'
HR: hod '/(bu)s$/i': '\1ses'
FORM: '/(alias|status)/i': '\1es'
VALIDATION_FAIL: '<b>Overenie zlyhalo:</b>' '/(octop|vir)us$/i': '\1i'
INVALID_INPUT: Neplatný vstup v '/(ax|test)is$/i': '\1es'
MISSING_REQUIRED_FIELD: 'Chýba vyžadované pole:' '/s$/i': 's'
MONTHS_OF_THE_YEAR: '/$/': 's'
- Január INFLECTOR_SINGULAR:
- Február '/(quiz)zes$/i': '\1'
- Marec '/(matr)ices$/i': '\1ix'
- Apríl '/(vert|ind)ices$/i': '\1ex'
- Máj '/^(ox)en/i': '\1'
- Jún '/(alias|status)es$/i': '\1'
- Júl '/([octop|vir])i$/i': '\1us'
- August '/(cris|ax|test)es$/i': '\1is'
- September '/(shoe)s$/i': '\1'
- Október '/(o)es$/i': '\1'
- November '/(bus)es$/i': '\1'
- December '/([m|l])ice$/i': '\1ouse'
DAYS_OF_THE_WEEK: '/(x|ch|ss|sh)es$/i': '\1'
- Pondelok '/(m)ovies$/i': '\1ovie'
- Utorok '/(s)eries$/i': '\1eries'
- Streda '/([^aeiouy]|qu)ies$/i': '\1y'
- Štvrtok '/([lr])ves$/i': '\1f'
- Piatok '/(tive)s$/i': '\1'
- Sobota '/(hive)s$/i': '\1'
- Nedeľa '/([^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:
- 'vybavenie'
- 'informácie'
- 'ryža'
- 'peniaze'
- 'druhy'
- 'séria'
- 'ryba'
- 'ovce'
INFLECTOR_IRREGULAR:
'person': 'ľudia'
'man': 'muži'
'child': 'deti'
'sex': 'pohlavia'
'move': 'pohyby'
INFLECTOR_ORDINALS:
'default': '.'
'first': '.'
'second': '.'
'third': '.'
NICETIME:
NO_DATE_PROVIDED: Neposkytnutý žiaden dátum
BAD_DATE: Nesprávny dátum
AGO: pred
FROM_NOW: odteraz
JUST_NOW: práve teraz
SECOND: sekunda
MINUTE: minúta
HOUR: hodina
DAY: deň
WEEK: týždeň
MONTH: mesiac
YEAR: rok
DECADE: desaťročie
SEC: sek
MIN: min
HR: hod
WK: t
MO: m
YR: r
DEC: dec
SECOND_PLURAL: sekúnd
MINUTE_PLURAL: minút
HOUR_PLURAL: hodín
DAY_PLURAL: dní
WEEK_PLURAL: týždňov
MONTH_PLURAL: mesiacov
YEAR_PLURAL: rokov
DECADE_PLURAL: dekád
SEC_PLURAL: sek
MIN_PLURAL: min
HR_PLURAL: hod
WK_PLURAL: t
MO_PLURAL: mes.
YR_PLURAL: rokov
DEC_PLURAL: dekád
FORM:
VALIDATION_FAIL: <b>Overenie zlyhalo:</b>
INVALID_INPUT: Neplatný vstup v
MISSING_REQUIRED_FIELD: 'Chýba vyžadované pole:'
MONTHS_OF_THE_YEAR:
- 'Január'
- 'Február'
- 'Marec'
- 'Apríl'
- 'Máj'
- 'Jún'
- 'Júl'
- 'August'
- 'September'
- 'Október'
- 'November'
- 'December'
DAYS_OF_THE_WEEK:
- 'Pondelok'
- 'Utorok'
- 'Streda'
- 'Štvrtok'
- 'Piatok'
- 'Sobota'
- 'Nedeľa'
CRON:
EVERY: každý
EVERY_HOUR: každú hodinu
EVERY_MINUTE: každú minútu
EVERY_DAY_OF_WEEK: každý deň v týždni
EVERY_DAY_OF_MONTH: každý deň v mesiaci
EVERY_MONTH: každý mesiac
TEXT_PERIOD: Každý <b />
TEXT_MINS: ' at <b /> minute(s) past the hour'
TEXT_TIME: ' at <b />:<b />'
TEXT_DOW: ' on <b />'
TEXT_MONTH: ' of <b />'
TEXT_DOM: ' on <b />'
ERROR1: Tag %s nieje podporovaný!
ERROR2: Chybný počet položiek
ERROR3: jquery_element musí byť nastavený v nastaveniach pre jqCron
ERROR4: Neznámy výraz
+62
View File
@@ -0,0 +1,62 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Napaka: Neveljavna Frontmatter\n\nPath: `%2$s`\n\n**%3$s ** \n\n```\n%4$s \n```"
NICETIME:
NO_DATE_PROVIDED: Datum ni na voljo
BAD_DATE: Neveljaven datum
AGO: pred
FROM_NOW: od zdaj
SECOND: sekunda
MINUTE: minuta
HOUR: ura
DAY: dan
WEEK: teden
MONTH: mesec
YEAR: leto
DECADE: desetletje
SEC: sek
HR: ur
WK: T.
MO: m
YR: l
DEC: des
SECOND_PLURAL: sekund
MINUTE_PLURAL: minut
HOUR_PLURAL: ure
DAY_PLURAL: dnevi
WEEK_PLURAL: tednov
MONTH_PLURAL: mesecev
YEAR_PLURAL: leta
DECADE_PLURAL: desetletja
SEC_PLURAL: s
MIN_PLURAL: min
HR_PLURAL: ur
WK_PLURAL: t
MO_PLURAL: m
YR_PLURAL: l
DEC_PLURAL: des
FORM:
VALIDATION_FAIL: <b>Preverjanje veljavnosti ni uspelo:</b>
INVALID_INPUT: Neveljaven vnos v
MISSING_REQUIRED_FIELD: 'Manjka obvezno polje:'
MONTHS_OF_THE_YEAR:
- 'Januar'
- 'Februar'
- 'Marec'
- 'April'
- 'Maj'
- 'Junij'
- 'Julij'
- 'Avgust'
- 'September'
- 'Oktober'
- 'November'
- 'December'
DAYS_OF_THE_WEEK:
- 'Ponedeljek'
- 'Torek'
- 'Sreda'
- 'Četrtek'
- 'Petek'
- 'Sobota'
- 'Nedelja'
+71 -61
View File
@@ -1,62 +1,72 @@
--- ---
FRONTMATTER_ERROR_PAGE: '--- titel: %1$s --- # Fel: Ogiltig Frontmatter-sökväg: `%2$s` **%3$s** ``` %4$s ```' GRAV:
NICETIME: FRONTMATTER_ERROR_PAGE: "--- titel: %1$s --- # Fel: Ogiltig Frontmatter-sökväg: `%2$s` **%3$s** ``` %4$s ```"
NO_DATE_PROVIDED: Inget datum har angivits INFLECTOR_UNCOUNTABLE:
BAD_DATE: Ogiltigt datum - 'utrustning'
AGO: sedan - 'information'
FROM_NOW: från nu - 'ris'
SECOND: sekund - 'pengar'
MINUTE: minut - 'arter'
HOUR: timme - 'serier'
DAY: dag - 'fisk'
WEEK: vecka - 'får'
MONTH: månad INFLECTOR_IRREGULAR:
YEAR: år 'person': 'personer'
DECADE: årtionde NICETIME:
SEC: sek NO_DATE_PROVIDED: Inget datum har angivits
MIN: min BAD_DATE: Ogiltigt datum
HR: t AGO: sedan
WK: v FROM_NOW: fr.o.m nu
MO: m SECOND: sekund
YR: år MINUTE: minut
DEC: dec HOUR: timme
SECOND_PLURAL: sekunder DAY: dag
MINUTE_PLURAL: minuter WEEK: vecka
HOUR_PLURAL: timmar MONTH: månad
DAY_PLURAL: dagar YEAR: år
WEEK_PLURAL: veckor DECADE: årtionde
MONTH_PLURAL: månader SEC: sek
YEAR_PLURAL: år HR: t
DECADE_PLURAL: årtionden WK: v
SEC_PLURAL: sek MO: m
MIN_PLURAL: min YR: år
HR_PLURAL: t SECOND_PLURAL: sekunder
WK_PLURAL: v MINUTE_PLURAL: minuter
MO_PLURAL: HOUR_PLURAL: timmar
YR_PLURAL: år DAY_PLURAL: dagar
DEC_PLURAL: dec WEEK_PLURAL: veckor
FORM: MONTH_PLURAL: månader
VALIDATION_FAIL: '<b>Kontrollen misslyckades:</b>' YEAR_PLURAL: år
INVALID_INPUT: Ogiltig indata i DECADE_PLURAL: årtionden
MISSING_REQUIRED_FIELD: 'Obligatoriskt fält måste fyllas i:' SEC_PLURAL: sek
MONTHS_OF_THE_YEAR: MIN_PLURAL: min
- Januari HR_PLURAL: t
- Februrari WK_PLURAL: v
- Mars MO_PLURAL:
- April YR_PLURAL: år
- Maj DEC_PLURAL: dec
- Juni FORM:
- Juli VALIDATION_FAIL: <b>Kontrollen misslyckades:</b>
- Augusti INVALID_INPUT: Ogiltig indata i
- September MISSING_REQUIRED_FIELD: 'Obligatoriskt fält måste fyllas i:'
- Oktober MONTHS_OF_THE_YEAR:
- November - 'Januari'
- December - 'Februari'
DAYS_OF_THE_WEEK: - 'Mars'
- Måndag - 'April'
- Tisdag - 'Maj'
- Onsdag - 'Juni'
- Torsdag - 'Juli'
- Fredag - 'Augusti'
- Lördag - 'September'
- Söndag - 'Oktober'
- 'November'
- 'December'
DAYS_OF_THE_WEEK:
- 'Måndag'
- 'Tisdag'
- 'Onsdag'
- 'Torsdag'
- 'Fredag'
- 'Lördag'
- 'Söndag'
+55 -74
View File
@@ -1,75 +1,56 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\nชื่อเรื่อง: %1$s\n---\n\n# ข้อผิดพลาด: Invalid Frontmatter\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
ชื่อเรื่อง: %1$s NICETIME:
--- NO_DATE_PROVIDED: ไม่มีวันที่ให้
BAD_DATE: รูปแบบวันที่ผิด
# ข้อผิดพลาด: Invalid Frontmatter AGO: ที่ผ่านมา
FROM_NOW: จากตอนนี้
Path: `%2$s` SECOND: วินาที
MINUTE: นาที
**%3$s** HOUR: ชั่วโมง
DAY: วัน
``` WEEK: สัปดาห์
%4$s MONTH: เดือน
``` YEAR: ปี
NICETIME: DECADE: ทศวรรษที่ผ่านมา
NO_DATE_PROVIDED: ไม่มีวันที่ให้ SEC: วิ
BAD_DATE: รูปแบบวันที่ผิด MIN: นาที
AGO: ที่ผ่านมา HR: ชม.
FROM_NOW: จากตอนนี้ SECOND_PLURAL: วินาที
SECOND: วินาที MINUTE_PLURAL: นาที
MINUTE: นาที HOUR_PLURAL: ชั่วโมง
HOUR: ชั่วโมง DAY_PLURAL: วัน
DAY: วัน WEEK_PLURAL: สัปดาห์
WEEK: สัปดาห์ MONTH_PLURAL: เดือน
MONTH: เดือน YEAR_PLURAL: ปี
YEAR: ปี DECADE_PLURAL: ทศวรรษที่ผ่านมา
DECADE: ทศวรรษที่ผ่านมา SEC_PLURAL: วินาที
SEC: วิ MIN_PLURAL: นาที
MIN: นาที HR_PLURAL: ชั่วโมง
HR: ชม. YR_PLURAL: ปี
WK: wk FORM:
MO: mo VALIDATION_FAIL: '<b>ตรวจสอบล้มเหลว: </b>'
YR: yr INVALID_INPUT: ป้อนข้อมูลไม่ถูกต้องใน
DEC: dec MISSING_REQUIRED_FIELD: 'ขาดข้อมูลที่จำเป็น:'
SECOND_PLURAL: วินาที MONTHS_OF_THE_YEAR:
MINUTE_PLURAL: นาที - 'มกราคม'
HOUR_PLURAL: ชั่วโมง - 'กุมภาพันธ์'
DAY_PLURAL: วัน - 'มีนาคม'
WEEK_PLURAL: สัปดาห์ - 'เมษายน'
MONTH_PLURAL: เดือน - 'พฤษภาคม'
YEAR_PLURAL: ปี - 'มิถุนายน'
DECADE_PLURAL: ทศวรรษที่ผ่านมา - 'กรกฏาคม'
SEC_PLURAL: วินาที - 'สิงหาคม'
MIN_PLURAL: นาที - 'กันยายน'
HR_PLURAL: ชั่วโมง - 'ตุลาคม'
WK_PLURAL: wks - 'พฤศจิกายน'
MO_PLURAL: mos - 'ธันวาคม'
YR_PLURAL: ปี DAYS_OF_THE_WEEK:
DEC_PLURAL: decs - 'จันทร์'
FORM: - 'อังคาร'
VALIDATION_FAIL: '<b>ตรวจสอบล้มเหลว: </b>' - 'พุธ'
INVALID_INPUT: ป้อนข้อมูลไม่ถูกต้องใน - 'พฤหัสบดี'
MISSING_REQUIRED_FIELD: 'ขาดข้อมูลที่จำเป็น:' - 'ศุกร์'
MONTHS_OF_THE_YEAR: - 'เสาร์'
- มกราคม - 'อาทิตย์'
- กุมภาพันธ์
- มีนาคม
- เมษายน
- พฤษภาคม
- มิถุนายน
- กรกฏาคม
- สิงหาคม
- กันยายน
- ตุลาคม
- พฤศจิกายน
- ธันวาคม
DAYS_OF_THE_WEEK:
- จันทร์
- อังคาร
- พุธ
- พฤหัสบดี
- ศุกร์
- เสาร์
- อาทิตย์
+62 -58
View File
@@ -1,59 +1,63 @@
--- ---
NICETIME: GRAV:
NO_DATE_PROVIDED: Tarih yok FRONTMATTER_ERROR_PAGE: "---\nBaşlık: %1$s\n---\n\n# Hata: Geçersiz Önbölüm\n\nYol: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
BAD_DATE: Yanlış tarih NICETIME:
AGO: önce NO_DATE_PROVIDED: Sağlanan tarih yok
FROM_NOW: (şimdiden) BAD_DATE: Yanlış tarih
SECOND: saniye AGO: önce
MINUTE: dakika FROM_NOW: şu andan itibaren
HOUR: saat SECOND: saniye
DAY: gün MINUTE: dakika
WEEK: hafta HOUR: saat
MONTH: ay DAY: gün
YEAR: yıl WEEK: hafta
DECADE: onyıl MONTH: ay
SEC: sn YEAR: yıl
MIN: dk DECADE: onyıl
HR: sa SEC: sn
WK: hft MIN: dk
MO: ay HR: sa
YR: yl WK: hft
DEC: onyl MO: ay
SECOND_PLURAL: saniye YR: yl
MINUTE_PLURAL: dakika DEC: onyl
HOUR_PLURAL: saat SECOND_PLURAL: saniye
DAY_PLURAL: gün MINUTE_PLURAL: dakika
WEEK_PLURAL: hafta HOUR_PLURAL: saat
MONTH_PLURAL: ay DAY_PLURAL: gün
YEAR_PLURAL: yıl WEEK_PLURAL: hafta
DECADE_PLURAL: onyıl MONTH_PLURAL: ay
SEC_PLURAL: sn YEAR_PLURAL: yıl
MIN_PLURAL: dk DECADE_PLURAL: onyıl
HR_PLURAL: sa SEC_PLURAL: sn
WK_PLURAL: hft MIN_PLURAL: dk
MO_PLURAL: ay HR_PLURAL: sa
YR_PLURAL: yl WK_PLURAL: hft
DEC_PLURAL: onyl MO_PLURAL: ay
FORM: YR_PLURAL: yıl
VALIDATION_FAIL: '<b>Doğrulama başarısız:</b>' DEC_PLURAL: onyl
MONTHS_OF_THE_YEAR: FORM:
- Ocak VALIDATION_FAIL: <b>Doğrulama başarısız:</b>
- Şubat INVALID_INPUT: Geçersiz bilgi girişi
- Mart MISSING_REQUIRED_FIELD: 'Gerekli alan eksik:'
- Nisan MONTHS_OF_THE_YEAR:
- Mayıs - 'Ocak'
- Haziran - 'Şubat'
- Temmuz - 'Mart'
- Ağustos - 'Nisan'
- Eylül - 'Mayıs'
- Ekim - 'Haziran'
- Kasım - 'Temmuz'
- Aralık - 'Ağustos'
DAYS_OF_THE_WEEK: - 'Eylül'
- Pazartesi - 'Ekim'
- Salı - 'Kasım'
- Çarşamba - 'Aralık'
- Perşembe DAYS_OF_THE_WEEK:
- Cuma - 'Pazartesi'
- Cumartesi - 'Salı'
- Pazar - 'Çarşamba'
- 'Perşembe'
- 'Cuma'
- 'Cumartesi'
- 'Pazar'
+62 -74
View File
@@ -1,75 +1,63 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# Помилка: Недопустимий вміст\n\nPath: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s NICETIME:
--- NO_DATE_PROVIDED: Не вказана дата
BAD_DATE: Невірна дата
# Помилка: Недопустимий вміст AGO: назад
FROM_NOW: відтепер
Path: `%2$s` SECOND: секунда
MINUTE: хвилина
**%3$s** HOUR: година
DAY: день
``` WEEK: тиждень
%4$s MONTH: місяць
``` YEAR: рік
NICETIME: DECADE: десятиріччя
NO_DATE_PROVIDED: Не вказана дата SEC: с
BAD_DATE: Невірна дата MIN: хв
AGO: назад HR: год
FROM_NOW: відтепер WK: тиж.
SECOND: секунда MO: міс.
MINUTE: хвилина YR: р.
HOUR: година DEC: рр.
DAY: день SECOND_PLURAL: секунди
WEEK: тиждень MINUTE_PLURAL: хвилини
MONTH: місяць HOUR_PLURAL: години
YEAR: рік DAY_PLURAL: дні
DECADE: десятиріччя WEEK_PLURAL: тижні
SEC: с MONTH_PLURAL: місяці
MIN: хв YEAR_PLURAL: роки
HR: год DECADE_PLURAL: десятиріччя
WK: тиж. SEC_PLURAL: с
MO: міс. MIN_PLURAL: хв
YR: р. HR_PLURAL: год
DEC: рр. WK_PLURAL: тиж.
SECOND_PLURAL: секунди MO_PLURAL: міс.
MINUTE_PLURAL: хвилини YR_PLURAL: рр.
HOUR_PLURAL: години DEC_PLURAL: рр.
DAY_PLURAL: дні FORM:
WEEK_PLURAL: тижні VALIDATION_FAIL: <b>Перевірка не вдалася:</b>
MONTH_PLURAL: місяці INVALID_INPUT: Невірне введення в
YEAR_PLURAL: роки MISSING_REQUIRED_FIELD: 'Відсутнє обов''язкове поле:'
DECADE_PLURAL: десятиріччя MONTHS_OF_THE_YEAR:
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:
- Лютий - 'Понеділок'
- Березень - 'Вівторок'
- Квітень - 'Середа'
- Травень - 'Четвер'
- Червень - 'П''ятниця'
- Липень - 'Субота'
- Серпень - 'Неділя'
- Вересень
- Жовтень
- Листопад
- Грудень
DAYS_OF_THE_WEEK:
- Понеділок
- Вівторок
- Середа
- Четвер
- "П'ятниця"
- Субота
- Неділя
+62 -74
View File
@@ -1,75 +1,63 @@
--- ---
FRONTMATTER_ERROR_PAGE: | GRAV:
--- FRONTMATTER_ERROR_PAGE: "---\ntiêu đề: %1$s\n---\n\n# Error: Trang không hợp lệ\n\nĐường dẫn: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
title: %1$s NICETIME:
--- NO_DATE_PROVIDED: Không có ngày được cung cấp
BAD_DATE: Ngày không hợp lệ
# Error: Invalid Frontmatter AGO: cách đây
FROM_NOW: từ bây giờ
Path: `%2$s` SECOND: giây
MINUTE: phút
**%3$s** HOUR: giờ
DAY: ngày
``` WEEK: tuần
%4$s MONTH: tháng
``` YEAR: năm
NICETIME: DECADE: thập kỷ
NO_DATE_PROVIDED: Không có ngày được cung cấp SEC: giây
BAD_DATE: Ngày không hợp lệ MIN: phút
AGO: cách đây HR: giờ
FROM_NOW: từ bây giờ WK: tuần
SECOND: giây MO: tháng
MINUTE: phút YR: năm
HOUR: giờ DEC: thập kỷ
DAY: ngày SECOND_PLURAL: giây
WEEK: tuần MINUTE_PLURAL: phút
MONTH: tháng HOUR_PLURAL: giờ
YEAR: năm DAY_PLURAL: ngày
DECADE: thập kỷ WEEK_PLURAL: tuần
SEC: giây MONTH_PLURAL: tháng
MIN: phút YEAR_PLURAL: năm
HR: giờ DECADE_PLURAL: thập kỷ
WK: tuần SEC_PLURAL: giây
MO: tháng MIN_PLURAL: phút
YR: năm HR_PLURAL: giờ
DEC: thập kỷ WK_PLURAL: tuần
SECOND_PLURAL: giây MO_PLURAL: tháng
MINUTE_PLURAL: phút YR_PLURAL: năm
HOUR_PLURAL: giờ DEC_PLURAL: thập kỷ
DAY_PLURAL: ngày FORM:
WEEK_PLURAL: tuần VALIDATION_FAIL: <b>Xác nhận thất bại:</b>
MONTH_PLURAL: tháng INVALID_INPUT: Dữ liệu nhập không hợp lệ cho
YEAR_PLURAL: năm MISSING_REQUIRED_FIELD: 'Thiếu trường bắt buộc:'
DECADE_PLURAL: thập kỷ MONTHS_OF_THE_YEAR:
SEC_PLURAL: giây - 'Tháng 1'
MIN_PLURAL: phút - 'Tháng 2'
HR_PLURAL: giờ - 'Tháng 3'
WK_PLURAL: tuần - 'Tháng 4'
MO_PLURAL: tháng - 'Tháng 5'
YR_PLURAL: năm - 'Tháng 6'
DEC_PLURAL: thập kỷ - 'Tháng 7'
FORM: - 'Tháng 8'
VALIDATION_FAIL: '<b>Xác nhận thất bại:</b>' - 'Tháng 9'
INVALID_INPUT: Dữ liệu nhập không hợp lệ cho - 'Tháng 10'
MISSING_REQUIRED_FIELD: 'Thiếu trường bắt buộc:' - 'Tháng 11'
MONTHS_OF_THE_YEAR: - 'Tháng 12'
- Tháng 1 DAYS_OF_THE_WEEK:
- Tháng 2 - 'Thứ 2'
- Tháng 3 - 'Thứ 3'
- Tháng 4 - 'Thứ 4'
- Tháng 5 - 'Thứ 5'
- Tháng 6 - 'Thứ 6'
- Tháng 7 - 'Thứ 7'
- Tháng 8 - 'Chủ Nhật'
- Tháng 9
- Tháng 10
- Tháng Mười 11
- Tháng 12
DAYS_OF_THE_WEEK:
- Thứ 2
- Thứ 3
- Thứ 4
- Thứ 5
- Thứ 6
- Thứ 7
- Chủ Nhật
+62
View File
@@ -0,0 +1,62 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\ntitle: %1$s\n---\n\n# 錯誤: 不正確的 Frontmatter\n\n路徑: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
NICETIME:
NO_DATE_PROVIDED: 沒有提供日期
BAD_DATE: 錯誤日期
AGO: 之前
FROM_NOW: 之後
JUST_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:
MISSING_REQUIRED_FIELD: 遺漏必填欄位:
MONTHS_OF_THE_YEAR:
- '一月'
- '二月'
- '三月'
- '四月'
- '五月'
- '六月'
- '七月'
- '八月'
- '九月'
- '十月'
- '十一月'
- '十二月'
DAYS_OF_THE_WEEK:
- '星期一'
- '星期二'
- '星期三'
- '星期四'
- '星期五'
- '星期六'
- '星期日'
+144
View File
@@ -0,0 +1,144 @@
---
GRAV:
FRONTMATTER_ERROR_PAGE: "---\n标题: %1$s\n---\n\n# 错误:无效参数\n\n位置: `%2$s`\n\n**%3$s**\n\n```\n%4$s\n```"
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'
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'
INFLECTOR_UNCOUNTABLE:
- '装备'
- '信息'
- '大米'
- '钱'
- '物种'
- '系列'
- '鱼'
- '羊'
INFLECTOR_IRREGULAR:
'person': '人员'
'man': '男人'
'child': '儿童'
'sex': '性别'
'move': '移动'
INFLECTOR_ORDINALS:
'default': 'th'
'first': 'st'
'second': 'md'
'third': 'rd'
NICETIME:
NO_DATE_PROVIDED: 无日期信息
BAD_DATE: 无效日期
AGO:
FROM_NOW: 距今
JUST_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:
- '1月'
- '2月'
- '3月'
- '4月'
- '5月'
- '6月'
- '7月'
- '8月'
- '9月'
- '10月'
- '11月'
- '12月'
DAYS_OF_THE_WEEK:
- '星期一'
- '星期二'
- '星期三'
- '星期四'
- '星期五'
- '星期六'
- '星期日'
CRON:
EVERY: 每隔
EVERY_HOUR: 每小时
EVERY_MINUTE: 每分钟
EVERY_DAY_OF_WEEK: 一周中的每一天
EVERY_DAY_OF_MONTH: 月份中的每一天
EVERY_MONTH: 每月
TEXT_PERIOD: 所有 <b />
TEXT_MINS: ' 在 <b /> 小时过后的分钟'
TEXT_TIME: ' 在 <b />:<b />'
TEXT_DOW: ' on <b />'
TEXT_MONTH: ' of <b />'
TEXT_DOM: ' on <b />'
ERROR1: 不支持分享类型 %s
ERROR2: 无效数字
ERROR3: 请在 jqCron 设置中设定 jquery_element
ERROR4: 无法识别表达式
+19 -8
View File
@@ -1,13 +1,14 @@
<?php <?php
/** /**
* @package Grav.Core * @package Grav\Core
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
if (PHP_SAPI !== 'cli-server') { if (PHP_SAPI !== 'cli-server') {
exit('This script cannot be run from browser. Run it from a CLI.'); die('This script cannot be run from browser. Run it from a CLI.');
} }
$_SERVER['PHP_CLI_ROUTER'] = true; $_SERVER['PHP_CLI_ROUTER'] = true;
@@ -16,11 +17,21 @@ if (is_file($_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . $_SERVER['SCRIPT_N
return false; return false;
} }
$_SERVER = array_merge($_SERVER, $_ENV); $grav_index = 'index.php';
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . DIRECTORY_SEPARATOR . 'index.php';
$_SERVER['SCRIPT_NAME'] = DIRECTORY_SEPARATOR . 'index.php';
$_SERVER['PHP_SELF'] = DIRECTORY_SEPARATOR . 'index.php';
require 'index.php'; /* Check the GRAV_BASEDIR environment variable and use if set */
$grav_basedir = getenv('GRAV_BASEDIR') ?: '';
if ($grav_basedir) {
$grav_index = ltrim($grav_basedir, '/') . DIRECTORY_SEPARATOR . $grav_index;
$grav_basedir = DIRECTORY_SEPARATOR . trim($grav_basedir, DIRECTORY_SEPARATOR);
define('GRAV_ROOT', str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . $grav_basedir);
}
$_SERVER = array_merge($_SERVER, $_ENV);
$_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . $grav_basedir .DIRECTORY_SEPARATOR . 'index.php';
$_SERVER['SCRIPT_NAME'] = $grav_basedir . DIRECTORY_SEPARATOR . 'index.php';
$_SERVER['PHP_SELF'] = $grav_basedir . DIRECTORY_SEPARATOR . 'index.php';
error_log(sprintf('%s:%d [%d]: %s', $_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_PORT'], http_response_code(), $_SERVER['REQUEST_URI']), 4); error_log(sprintf('%s:%d [%d]: %s', $_SERVER['REMOTE_ADDR'], $_SERVER['REMOTE_PORT'], http_response_code(), $_SERVER['REQUEST_URI']), 4);
require $grav_index;
File diff suppressed because it is too large Load Diff
+198
View File
@@ -0,0 +1,198 @@
<?php
/**
* @package Grav\Common\Assets
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets;
use Grav\Common\Assets\Traits\AssetUtilsTrait;
use Grav\Common\Grav;
use Grav\Common\Uri;
use Grav\Common\Utils;
use Grav\Framework\Object\PropertyObject;
abstract class BaseAsset extends PropertyObject
{
use AssetUtilsTrait;
protected const CSS_ASSET = true;
protected const JS_ASSET = false;
/** @const Regex to match CSS import content */
protected const CSS_IMPORT_REGEX = '{@import(.*?);}';
protected $asset;
protected $asset_type;
protected $order;
protected $group;
protected $position;
protected $priority;
protected $attributes = [];
protected $timestamp;
protected $modified;
protected $remote;
protected $query = '';
// Private Bits
private $base_url;
private $fetch_command;
private $css_rewrite = false;
private $css_minify = false;
abstract function render();
public function __construct(array $elements = [], $key = null)
{
$base_config = [
'group' => 'head',
'position' => 'pipeline',
'priority' => 10,
'modified' => null,
'asset' => null
];
// Merge base defaults
$elements = array_merge($base_config, $elements);
parent::__construct($elements, $key);
}
public function init($asset, $options)
{
$config = Grav::instance()['config'];
$uri = Grav::instance()['uri'];
// set attributes
foreach ($options as $key => $value) {
if ($this->hasProperty($key)) {
$this->setProperty($key, $value);
} else {
$this->attributes[$key] = $value;
}
}
// Force priority to be an int
$this->priority = (int) $this->priority;
// Do some special stuff for CSS/JS (not inline)
if (!Utils::startsWith($this->getType(), 'inline')) {
$this->base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/';
$this->remote = static::isRemoteLink($asset);
// Move this to render?
if (!$this->remote) {
$asset_parts = parse_url($asset);
if (isset($asset_parts['query'])) {
$this->query = $asset_parts['query'];
unset($asset_parts['query']);
$asset = Uri::buildUrl($asset_parts);
}
$locator = Grav::instance()['locator'];
if ($locator->isStream($asset)) {
$path = $locator->findResource($asset, true);
} else {
$path = GRAV_ROOT . $asset;
}
// If local file is missing return
if ($path === false) {
return false;
}
$file = new \SplFileInfo($path);
$asset = $this->buildLocalLink($file->getPathname());
$this->modified = $file->isFile() ? $file->getMTime() : false;
}
}
$this->asset = $asset;
return $this;
}
public function getAsset()
{
return $this->asset;
}
public function getRemote()
{
return $this->remote;
}
public function setPosition($position)
{
$this->position = $position;
return $this;
}
/**
*
* Get the last modification time of asset
*
* @param string $asset the asset string reference
*
* @return string the last modifcation time or false on error
*/
// protected function getLastModificationTime($asset)
// {
// $file = GRAV_ROOT . $asset;
// if (Grav::instance()['locator']->isStream($asset)) {
// $file = $this->buildLocalLink($asset, true);
// }
//
// return file_exists($file) ? filemtime($file) : false;
// }
/**
*
* Build local links including grav asset shortcodes
*
* @param string $asset the asset string reference
*
* @return string the final link url to the asset
*/
protected function buildLocalLink($asset)
{
if ($asset) {
return $this->base_url . ltrim(Utils::replaceFirstOccurrence(GRAV_ROOT, '', $asset), '/');
}
return false;
}
/**
* Implements JsonSerializable interface.
*
* @return array
*/
public function jsonSerialize()
{
return ['type' => $this->getType(), 'elements' => $this->getElements()];
}
/**
* Placeholder for AssetUtilsTrait method
*
* @param string $file
* @param string $dir
* @param bool $local
*/
protected function cssRewrite($file, $dir, $local)
{
return;
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
/**
* @package Grav\Common\Assets
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets;
use Grav\Common\Utils;
class Css extends BaseAsset
{
public function __construct(array $elements = [], $key = null)
{
$base_options = [
'asset_type' => 'css',
'attributes' => [
'type' => 'text/css',
'rel' => 'stylesheet'
]
];
$merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements);
parent::__construct($merged_attributes, $key);
}
public function render()
{
if (isset($this->attributes['loading']) && $this->attributes['loading'] === 'inline') {
$buffer = $this->gatherLinks( [$this], self::CSS_ASSET);
return "<style>\n" . trim($buffer) . "\n</style>\n";
}
return '<link href="' . trim($this->asset) . $this->renderQueryString() . '"' . $this->renderAttributes() . ">\n";
}
}
@@ -0,0 +1,32 @@
<?php
/**
* @package Grav\Common\Assets
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets;
use Grav\Common\Utils;
class InlineCss extends BaseAsset
{
public function __construct(array $elements = [], $key = null)
{
$base_options = [
'asset_type' => 'css',
'position' => 'after'
];
$merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements);
parent::__construct($merged_attributes, $key);
}
public function render()
{
return '<style' . $this->renderAttributes(). ">\n" . trim($this->asset) . "\n</style>\n";
}
}
@@ -0,0 +1,32 @@
<?php
/**
* @package Grav\Common\Assets
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets;
use Grav\Common\Utils;
class InlineJs extends BaseAsset
{
public function __construct(array $elements = [], $key = null)
{
$base_options = [
'asset_type' => 'js',
'position' => 'after'
];
$merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements);
parent::__construct($merged_attributes, $key);
}
public function render()
{
return '<script' . $this->renderAttributes(). ">\n" . trim($this->asset) . "\n</script>\n";
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
/**
* @package Grav\Common\Assets
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets;
use Grav\Common\Utils;
class Js extends BaseAsset
{
public function __construct(array $elements = [], $key = null)
{
$base_options = [
'asset_type' => 'js',
];
$merged_attributes = Utils::arrayMergeRecursiveUnique($base_options, $elements);
parent::__construct($merged_attributes, $key);
}
public function render()
{
if (isset($this->attributes['loading']) && $this->attributes['loading'] === 'inline') {
$buffer = $this->gatherLinks( [$this], self::JS_ASSET);
return '<script' . $this->renderAttributes() . ">\n" . trim($buffer) . "\n</script>\n";
}
return '<script src="' . trim($this->asset) . $this->renderQueryString() . '"' . $this->renderAttributes() . "></script>\n";
}
}
+273
View File
@@ -0,0 +1,273 @@
<?php
/**
* @package Grav\Common\Assets
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets;
use Grav\Common\Assets\Traits\AssetUtilsTrait;
use Grav\Common\Config\Config;
use Grav\Common\Grav;
use Grav\Common\Uri;
use Grav\Common\Utils;
use Grav\Framework\Object\PropertyObject;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class Pipeline extends PropertyObject
{
use AssetUtilsTrait;
protected const CSS_ASSET = true;
protected const JS_ASSET = false;
/** @const Regex to match CSS urls */
protected const CSS_URL_REGEX = '{url\(([\'\"]?)(.*?)\1\)}';
/** @const Regex to match CSS sourcemap comments */
protected const CSS_SOURCEMAP_REGEX = '{\/\*# (.*?) \*\/}';
/** @const Regex to match CSS import content */
protected const CSS_IMPORT_REGEX = '{@import(.*?);}';
protected const FIRST_FORWARDSLASH_REGEX = '{^\/{1}\w}';
protected $css_minify;
protected $css_minify_windows;
protected $css_rewrite;
protected $js_minify;
protected $js_minify_windows;
protected $base_url;
protected $assets_dir;
protected $assets_url;
protected $timestamp;
protected $attributes;
protected $query;
protected $asset;
/**
* Closure used by the pipeline to fetch assets.
*
* Useful when file_get_contents() function is not available in your PHP
* installation or when you want to apply any kind of preprocessing to
* your assets before they get pipelined.
*
* The closure will receive as the only parameter a string with the path/URL of the asset and
* it should return the content of the asset file as a string.
*
* @var \Closure
*/
protected $fetch_command;
public function __construct(array $elements = [], ?string $key = null)
{
parent::__construct($elements, $key);
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
/** @var Config $config */
$config = Grav::instance()['config'];
/** @var Uri $uri */
$uri = Grav::instance()['uri'];
$this->base_url = rtrim($uri->rootUrl($config->get('system.absolute_urls')), '/') . '/';
$this->assets_dir = $locator->findResource('asset://') . DS;
$this->assets_url = $locator->findResource('asset://', false);
}
/**
* Minify and concatenate CSS
*
* @param array $assets
* @param string $group
* @param array $attributes
*
* @return bool|string URL or generated content if available, else false
*/
public function renderCss($assets, $group, $attributes = [])
{
// temporary list of assets to pipeline
$inline_group = false;
if (array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline') {
$inline_group = true;
unset($attributes['loading']);
}
// Store Attributes
$this->attributes = array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes);
// Compute uid based on assets and timestamp
$json_assets = json_encode($assets);
$uid = md5($json_assets . $this->css_minify . $this->css_rewrite . $group);
$file = $uid . '.css';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
$buffer = null;
if (file_exists($this->assets_dir . $file)) {
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
} else {
//if nothing found get out of here!
if (empty($assets)) {
return false;
}
// Concatenate files
$buffer = $this->gatherLinks($assets, self::CSS_ASSET);
// Minify if required
if ($this->shouldMinify('css')) {
$minifier = new \MatthiasMullie\Minify\CSS();
$minifier->add($buffer);
$buffer = $minifier->minify();
}
// Write file
if (trim($buffer) !== '') {
file_put_contents($this->assets_dir . $file, $buffer);
}
}
if ($inline_group) {
$output = "<style>\n" . $buffer . "\n</style>\n";
} else {
$this->asset = $relative_path;
$output = '<link href="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . ">\n";
}
return $output;
}
/**
* Minify and concatenate JS files.
*
* @param array $assets
* @param string $group
* @param array $attributes
*
* @return bool|string URL or generated content if available, else false
*/
public function renderJs($assets, $group, $attributes = [])
{
// temporary list of assets to pipeline
$inline_group = false;
if (array_key_exists('loading', $attributes) && $attributes['loading'] === 'inline') {
$inline_group = true;
unset($attributes['loading']);
}
// Store Attributes
$this->attributes = $attributes;
// Compute uid based on assets and timestamp
$json_assets = json_encode($assets);
$uid = md5($json_assets . $this->js_minify . $group);
$file = $uid . '.js';
$relative_path = "{$this->base_url}{$this->assets_url}/{$file}";
$buffer = null;
if (file_exists($this->assets_dir . $file)) {
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
} else {
//if nothing found get out of here!
if (empty($assets)) {
return false;
}
// Concatenate files
$buffer = $this->gatherLinks($assets, self::JS_ASSET);
// Minify if required
if ($this->shouldMinify('js')) {
$minifier = new \MatthiasMullie\Minify\JS();
$minifier->add($buffer);
$buffer = $minifier->minify();
}
// Write file
if (trim($buffer) !== '') {
file_put_contents($this->assets_dir . $file, $buffer);
}
}
if ($inline_group) {
$output = '<script' . $this->renderAttributes(). ">\n" . $buffer . "\n</script>\n";
} else {
$this->asset = $relative_path;
$output = '<script src="' . $relative_path . $this->renderQueryString() . '"' . $this->renderAttributes() . "></script>\n";
}
return $output;
}
/**
* Finds relative CSS urls() and rewrites the URL with an absolute one
*
* @param string $file the css source file
* @param string $dir , $local relative path to the css file
* @param bool $local is this a local or remote asset
*
* @return mixed
*/
protected function cssRewrite($file, $dir, $local)
{
// Strip any sourcemap comments
$file = preg_replace(self::CSS_SOURCEMAP_REGEX, '', $file);
// Find any css url() elements, grab the URLs and calculate an absolute path
// Then replace the old url with the new one
$file = (string)preg_replace_callback(self::CSS_URL_REGEX, function ($matches) use ($dir, $local) {
$old_url = $matches[2];
// Ensure link is not rooted to web server, a data URL, or to a remote host
if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url) || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) {
return $matches[0];
}
// clean leading /
$old_url = Utils::normalizePath($dir . '/' . $old_url);
if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url)) {
$old_url = ltrim($old_url, '/');
}
$new_url = ($local ? $this->base_url: '') . $old_url;
$fixed = str_replace($matches[2], $new_url, $matches[0]);
return $fixed;
}, $file);
return $file;
}
private function shouldMinify($type = 'css')
{
$check = $type . '_minify';
$win_check = $type . '_minify_windows';
$minify = (bool) $this->$check;
// If this is a Windows server, and minify_windows is false (default value) skip the
// minification process because it will cause Apache to die/crash due to insufficient
// ThreadStackSize in httpd.conf - See: https://bugs.php.net/bug.php?id=47689
if (stripos(php_uname('s'), 'WIN') === 0 && !$this->{$win_check}) {
$minify = false;
}
return $minify;
}
}
@@ -0,0 +1,182 @@
<?php
/**
* @package Grav\Common\Assets\Traits
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets\Traits;
use Grav\Common\Grav;
use Grav\Common\Utils;
trait AssetUtilsTrait
{
/**
* Determine whether a link is local or remote.
* Understands both "http://" and "https://" as well as protocol agnostic links "//"
*
* @param string $link
* @return bool
*/
public static function isRemoteLink($link)
{
$base = Grav::instance()['uri']->rootUrl(true);
// Sanity check for local URLs with absolute URL's enabled
if (Utils::startsWith($link, $base)) {
return false;
}
return (0 === strpos($link, 'http://') || 0 === strpos($link, 'https://') || 0 === strpos($link, '//'));
}
/**
* Download and concatenate the content of several links.
*
* @param array $assets
* @param bool $css
*
* @return string
*/
protected function gatherLinks(array $assets, $css = true)
{
$buffer = '';
foreach ($assets as $id => $asset) {
$local = true;
$link = $asset->getAsset();
$relative_path = $link;
if (static::isRemoteLink($link)) {
$local = false;
if (0 === strpos($link, '//')) {
$link = 'http:' . $link;
}
$relative_dir = \dirname($relative_path);
} else {
// Fix to remove relative dir if grav is in one
if (($this->base_url !== '/') && Utils::startsWith($relative_path, $this->base_url)) {
$base_url = '#' . preg_quote($this->base_url, '#') . '#';
$relative_path = ltrim(preg_replace($base_url, '/', $link, 1), '/');
}
$relative_dir = \dirname($relative_path);
$link = ROOT_DIR . $relative_path;
}
$file = ($this->fetch_command instanceof \Closure) ? @$this->fetch_command->__invoke($link) : @file_get_contents($link);
// No file found, skip it...
if ($file === false) {
continue;
}
// Double check last character being
if (!$css) {
$file = rtrim($file, ' ;') . ';';
}
// If this is CSS + the file is local + rewrite enabled
if ($css && $this->css_rewrite) {
$file = $this->cssRewrite($file, $relative_dir, $local);
}
$file = rtrim($file) . PHP_EOL;
$buffer .= $file;
}
// Pull out @imports and move to top
if ($css) {
$buffer = $this->moveImports($buffer);
}
return $buffer;
}
/**
* Moves @import statements to the top of the file per the CSS specification
*
* @param string $file the file containing the combined CSS files
*
* @return string the modified file with any @imports at the top of the file
*/
protected function moveImports($file)
{
$imports = [];
$file = (string)preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) use (&$imports) {
$imports[] = $matches[0];
return '';
}, $file);
return implode("\n", $imports) . "\n\n" . $file;
}
/**
*
* Build an HTML attribute string from an array.
*
* @return string
*/
protected function renderAttributes()
{
$html = '';
$no_key = ['loading'];
foreach ($this->attributes as $key => $value) {
if (is_numeric($key)) {
$key = $value;
}
if (\is_array($value)) {
$value = implode(' ', $value);
}
if (\in_array($key, $no_key, true)) {
$element = htmlentities($value, ENT_QUOTES, 'UTF-8', false);
} else {
$element = $key . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"';
}
$html .= ' ' . $element;
}
return $html;
}
/**
* Render Querystring
*
* @param string $asset
* @return string
*/
protected function renderQueryString($asset = null)
{
$querystring = '';
$asset = $asset ?? $this->asset;
if (!empty($this->query)) {
if (Utils::contains($asset, '?')) {
$querystring .= '&' . $this->query;
} else {
$querystring .= '?' . $this->query;
}
}
if ($this->timestamp) {
if (Utils::contains($asset, '?') || $querystring) {
$querystring .= '&' . $this->timestamp;
} else {
$querystring .= '?' . $this->timestamp;
}
}
return $querystring;
}
}
@@ -0,0 +1,125 @@
<?php
/**
* @package Grav\Common\Assets\Traits
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets\Traits;
use Grav\Common\Assets;
trait LegacyAssetsTrait
{
/**
* @param array $args
* @param string $type
* @return array
*/
protected function unifyLegacyArguments($args, $type = Assets::CSS_TYPE)
{
// First argument is always the asset
array_shift($args);
if (count($args) === 0) {
return [];
}
// New options array format
if (count($args) === 1 && is_array($args[0])) {
return $args[0];
}
// Handle obscure case where options array is mixed with a priority
if (count($args) === 2 && is_array($args[0]) && is_int($args[1])) {
$arguments = $args[0];
$arguments['priority'] = $args[1];
return $arguments;
}
switch ($type) {
case(Assets::JS_TYPE):
$defaults = ['priority' => null, 'pipeline' => true, 'loading' => null, 'group' => null];
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
break;
case(Assets::INLINE_JS_TYPE):
$defaults = ['priority' => null, 'group' => null, 'attributes' => null];
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
// special case to handle old attributes being passed in
if (isset($arguments['attributes'])) {
$old_attributes = $arguments['attributes'];
$arguments = array_merge($arguments, $old_attributes);
}
unset($arguments['attributes']);
break;
case(Assets::INLINE_CSS_TYPE):
$defaults = ['priority' => null, 'group' => null];
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
break;
default:
case(Assets::CSS_TYPE):
$defaults = ['priority' => null, 'pipeline' => true, 'group' => null, 'loading' => null];
$arguments = $this->createArgumentsFromLegacy($args, $defaults);
}
return $arguments;
}
protected function createArgumentsFromLegacy(array $args, array $defaults)
{
// Remove arguments with old default values.
$arguments = [];
foreach ($args as $arg) {
$default = current($defaults);
if ($arg !== $default) {
$arguments[key($defaults)] = $arg;
}
next($defaults);
}
return $arguments;
}
/**
* Convenience wrapper for async loading of JavaScript
*
* @param string|array $asset
* @param int $priority
* @param bool $pipeline
* @param string $group name of the group
*
* @return \Grav\Common\Assets
* @deprecated Please use dynamic method with ['loading' => 'async'].
*/
public function addAsyncJs($asset, $priority = 10, $pipeline = true, $group = 'head')
{
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use dynamic method with [\'loading\' => \'async\']', E_USER_DEPRECATED);
return $this->addJs($asset, $priority, $pipeline, 'async', $group);
}
/**
* Convenience wrapper for deferred loading of JavaScript
*
* @param string|array $asset
* @param int $priority
* @param bool $pipeline
* @param string $group name of the group
*
* @return \Grav\Common\Assets
* @deprecated Please use dynamic method with ['loading' => 'defer'].
*/
public function addDeferJs($asset, $priority = 10, $pipeline = true, $group = 'head')
{
user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6, use dynamic method with [\'loading\' => \'defer\']', E_USER_DEPRECATED);
return $this->addJs($asset, $priority, $pipeline, 'defer', $group);
}
}
@@ -0,0 +1,343 @@
<?php
/**
* @package Grav\Common\Assets\Traits
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Assets\Traits;
use Grav\Common\Grav;
trait TestingAssetsTrait
{
/**
* Determines if an asset exists as a collection, CSS or JS reference
*
* @param string $asset
*
* @return bool
*/
public function exists($asset)
{
return isset($this->collections[$asset]) || isset($this->assets_css[$asset]) || isset($this->assets_js[$asset]);
}
/**
* Return the array of all the registered collections
*
* @return array
*/
public function getCollections()
{
return $this->collections;
}
/**
* Set the array of collections explicitly
*
* @param array $collections
*
* @return $this
*/
public function setCollection($collections)
{
$this->collections = $collections;
return $this;
}
/**
* Return the array of all the registered CSS assets
* If a $key is provided, it will try to return only that asset
* else it will return null
*
* @param null|string $key the asset key
* @return array
*/
public function getCss($key = null)
{
if (null !== $key) {
$asset_key = md5($key);
return $this->assets_css[$asset_key] ?? null;
}
return $this->assets_css;
}
/**
* Return the array of all the registered JS assets
* If a $key is provided, it will try to return only that asset
* else it will return null
*
* @param null|string $key the asset key
* @return array
*/
public function getJs($key = null)
{
if (null !== $key) {
$asset_key = md5($key);
return $this->assets_js[$asset_key] ?? null;
}
return $this->assets_js;
}
/**
* Set the whole array of CSS assets
*
* @param array $css
*
* @return $this
*/
public function setCss($css)
{
$this->assets_css = $css;
return $this;
}
/**
* Set the whole array of JS assets
*
* @param array $js
*
* @return $this
*/
public function setJs($js)
{
$this->assets_js = $js;
return $this;
}
/**
* Removes an item from the CSS array if set
*
* @param string $key The asset key
*
* @return $this
*/
public function removeCss($key)
{
$asset_key = md5($key);
if (isset($this->assets_css[$asset_key])) {
unset($this->assets_css[$asset_key]);
}
return $this;
}
/**
* Removes an item from the JS array if set
*
* @param string $key The asset key
*
* @return $this
*/
public function removeJs($key)
{
$asset_key = md5($key);
if (isset($this->assets_js[$asset_key])) {
unset($this->assets_js[$asset_key]);
}
return $this;
}
/**
* Sets the state of CSS Pipeline
*
* @param bool $value
*
* @return $this
*/
public function setCssPipeline($value)
{
$this->css_pipeline = (bool)$value;
return $this;
}
/**
* Sets the state of JS Pipeline
*
* @param bool $value
*
* @return $this
*/
public function setJsPipeline($value)
{
$this->js_pipeline = (bool)$value;
return $this;
}
/**
* Reset all assets.
*
* @return $this
*/
public function reset()
{
$this->resetCss();
$this->resetJs();
$this->setCssPipeline(false);
$this->setJsPipeline(false);
return $this;
}
/**
* Reset JavaScript assets.
*
* @return $this
*/
public function resetJs()
{
$this->assets_js = [];
return $this;
}
/**
* Reset CSS assets.
*
* @return $this
*/
public function resetCss()
{
$this->assets_css = [];
return $this;
}
/**
* Explicitly set's a timestamp for assets
*
* @param string|int $value
*/
public function setTimestamp($value)
{
$this->timestamp = $value;
}
/**
* Get the timestamp for assets
*
* @param bool $include_join
* @return string
*/
public function getTimestamp($include_join = true)
{
if ($this->timestamp) {
return $include_join ? '?' . $this->timestamp : $this->timestamp;
}
return null;
}
/**
* Add all assets matching $pattern within $directory.
*
* @param string $directory Relative to the Grav root path, or a stream identifier
* @param string $pattern (regex)
*
* @return $this
*/
public function addDir($directory, $pattern = self::DEFAULT_REGEX)
{
$root_dir = rtrim(ROOT_DIR, '/');
// Check if $directory is a stream.
if (strpos($directory, '://')) {
$directory = Grav::instance()['locator']->findResource($directory, null);
}
// Get files
$files = $this->rglob($root_dir . DIRECTORY_SEPARATOR . $directory, $pattern, $root_dir . '/');
// No luck? Nothing to do
if (!$files) {
return $this;
}
// Add CSS files
if ($pattern === self::CSS_REGEX) {
foreach ($files as $file) {
$this->addCss($file);
}
return $this;
}
// Add JavaScript files
if ($pattern === self::JS_REGEX) {
foreach ($files as $file) {
$this->addJs($file);
}
return $this;
}
// Unknown pattern.
foreach ($files as $asset) {
$this->add($asset);
}
return $this;
}
/**
* Add all JavaScript assets within $directory
*
* @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
*/
public function addDirCss($directory)
{
return $this->addDir($directory, self::CSS_REGEX);
}
/**
* Recursively get files matching $pattern within $directory.
*
* @param string $directory
* @param string $pattern (regex)
* @param string $ltrim Will be trimmed from the left of the file path
*
* @return array
*/
protected function rglob($directory, $pattern, $ltrim = null)
{
$iterator = new \RegexIterator(new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($directory,
\FilesystemIterator::SKIP_DOTS)), $pattern);
$offset = \strlen($ltrim);
$files = [];
foreach ($iterator as $file) {
$files[] = substr($file->getPathname(), $offset);
}
return $files;
}
}
+261
View File
@@ -0,0 +1,261 @@
<?php
/**
* @package Grav\Common\Backup
*
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Backup;
use Grav\Common\Filesystem\Archiver;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Inflector;
use Grav\Common\Scheduler\Job;
use Grav\Common\Scheduler\Scheduler;
use Grav\Common\Utils;
use Grav\Common\Grav;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\Event\EventDispatcher;
use RocketTheme\Toolbox\File\JsonFile;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class Backups
{
protected const BACKUP_FILENAME_REGEXZ = "#(.*)--(\d*).zip#";
protected const BACKUP_DATE_FORMAT = 'YmdHis';
protected static $backup_dir;
protected static $backups = null;
public function init()
{
/** @var EventDispatcher $dispatcher */
$dispatcher = Grav::instance()['events'];
$dispatcher->addListener('onSchedulerInitialized', [$this, 'onSchedulerInitialized']);
Grav::instance()->fireEvent('onBackupsInitialized', new Event(['backups' => $this]));
}
public function setup()
{
if (null === static::$backup_dir) {
static::$backup_dir = Grav::instance()['locator']->findResource('backup://', true, true);
Folder::create(static::$backup_dir);
}
}
public function onSchedulerInitialized(Event $event)
{
/** @var Scheduler $scheduler */
$scheduler = $event['scheduler'];
/** @var Inflector $inflector */
$inflector = Grav::instance()['inflector'];
foreach (static::getBackupProfiles() as $id => $profile) {
$at = $profile['schedule_at'];
$name = $inflector::hyphenize($profile['name']);
$logs = 'logs/backup-' . $name . '.out';
/** @var Job $job */
$job = $scheduler->addFunction('Grav\Common\Backup\Backups::backup', [$id], $name );
$job->at($at);
$job->output($logs);
$job->backlink('/tools/backups');
}
}
public function getBackupDownloadUrl($backup, $base_url)
{
$param_sep = $param_sep = Grav::instance()['config']->get('system.param_sep', ':');
$download = urlencode(base64_encode($backup));
$url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim($base_url,
'/') . '/task' . $param_sep . 'backup/download' . $param_sep . $download . '/admin-nonce' . $param_sep . Utils::getNonce('admin-form');
return $url;
}
public static function getBackupProfiles()
{
return Grav::instance()['config']->get('backups.profiles');
}
public static function getPurgeConfig()
{
return Grav::instance()['config']->get('backups.purge');
}
public function getBackupNames()
{
return array_column(static::getBackupProfiles(), 'name');
}
public static function getTotalBackupsSize()
{
$backups = static::getAvailableBackups();
$size = array_sum(array_column($backups, 'size'));
return $size ?? 0;
}
public static function getAvailableBackups($force = false)
{
if ($force || null === static::$backups) {
static::$backups = [];
$backups_itr = new \GlobIterator(static::$backup_dir . '/*.zip', \FilesystemIterator::KEY_AS_FILENAME);
$inflector = Grav::instance()['inflector'];
$long_date_format = DATE_RFC2822;
/**
* @var string $name
* @var \SplFileInfo $file
*/
foreach ($backups_itr as $name => $file) {
if (preg_match(static::BACKUP_FILENAME_REGEXZ, $name, $matches)) {
$date = \DateTime::createFromFormat(static::BACKUP_DATE_FORMAT, $matches[2]);
$timestamp = $date->getTimestamp();
$backup = new \stdClass();
$backup->title = $inflector->titleize($matches[1]);
$backup->time = $date;
$backup->date = $date->format($long_date_format);
$backup->filename = $name;
$backup->path = $file->getPathname();
$backup->size = $file->getSize();
static::$backups[$timestamp] = $backup;
}
}
// Reverse Key Sort to get in reverse date order
krsort(static::$backups);
}
return static::$backups;
}
/**
* Backup
*
* @param int $id
* @param callable|null $status
*
* @return null|string
*/
public static function backup($id = 0, callable $status = null)
{
$profiles = static::getBackupProfiles();
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
if (isset($profiles[$id])) {
$backup = (object) $profiles[$id];
} else {
throw new \RuntimeException('No backups defined...');
}
$name = Grav::instance()['inflector']->underscorize($backup->name);
$date = date(static::BACKUP_DATE_FORMAT, time());
$filename = trim($name, '_') . '--' . $date . '.zip';
$destination = static::$backup_dir . DS . $filename;
$max_execution_time = ini_set('max_execution_time', 600);
$backup_root = $backup->root;
if ($locator->isStream($backup_root)) {
$backup_root = $locator->findResource($backup_root);
} else {
$backup_root = rtrim(GRAV_ROOT . $backup_root, '/');
}
if (!file_exists($backup_root)) {
throw new \RuntimeException("Backup location: {$backup_root} does not exist...");
}
$options = [
'exclude_files' => static::convertExclude($backup->exclude_files ?? ''),
'exclude_paths' => static::convertExclude($backup->exclude_paths ?? ''),
];
/** @var Archiver $archiver */
$archiver = Archiver::create('zip');
$archiver->setArchive($destination)->setOptions($options)->compress($backup_root, $status)->addEmptyFolders($options['exclude_paths'], $status);
$status && $status([
'type' => 'message',
'message' => 'Done...',
]);
$status && $status([
'type' => 'progress',
'complete' => true
]);
if ($max_execution_time !== false) {
ini_set('max_execution_time', $max_execution_time);
}
// Log the backup
Grav::instance()['log']->notice('Backup Created: ' . $destination);
// Fire Finished event
Grav::instance()->fireEvent('onBackupFinished', new Event(['backup' => $destination]));
// Purge anything required
static::purge();
// Log
$log = JsonFile::instance(Grav::instance()['locator']->findResource("log://backup.log", true, true));
$log->content([
'time' => time(),
'location' => $destination
]);
$log->save();
return $destination;
}
public static function purge()
{
$purge_config = static::getPurgeConfig();
$trigger = $purge_config['trigger'];
$backups = static::getAvailableBackups(true);
switch ($trigger)
{
case 'number':
$backups_count = count($backups);
if ($backups_count > $purge_config['max_backups_count']) {
$last = end($backups);
unlink ($last->path);
static::purge();
}
break;
case 'time':
$last = end($backups);
$now = new \DateTime();
$interval = $now->diff($last->time);
if ($interval->days > $purge_config['max_backups_time']) {
unlink($last->path);
static::purge();
}
break;
default:
$used_space = static::getTotalBackupsSize();
$max_space = $purge_config['max_backups_space'] * 1024 * 1024 * 1024;
if ($used_space > $max_space) {
$last = end($backups);
unlink($last->path);
static::purge();
}
break;
}
}
protected static function convertExclude($exclude)
{
$lines = preg_split("/[\s,]+/", $exclude);
return array_map('trim', $lines, array_fill(0, \count($lines), '/'));
}
}
-144
View File
@@ -1,144 +0,0 @@
<?php
/**
* @package Grav.Common.Backup
*
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Backup;
use Grav\Common\Grav;
use Grav\Common\Inflector;
class ZipBackup
{
protected static $ignorePaths = [
'backup',
'cache',
'images',
'logs',
'tmp'
];
protected static $ignoreFolders = [
'.git',
'.svn',
'.hg',
'.idea',
'node_modules'
];
/**
* Backup
*
* @param string|null $destination
* @param callable|null $messager
*
* @return null|string
*/
public static function backup($destination = null, callable $messager = null)
{
if (!$destination) {
$destination = Grav::instance()['locator']->findResource('backup://', true);
if (!$destination) {
throw new \RuntimeException('The backup folder is missing.');
}
}
$name = substr(strip_tags(Grav::instance()['config']->get('site.title', basename(GRAV_ROOT))), 0, 20);
$inflector = new Inflector();
if (is_dir($destination)) {
$date = date('YmdHis', time());
$filename = trim($inflector->hyphenize($name), '-') . '-' . $date . '.zip';
$destination = rtrim($destination, DS) . DS . $filename;
}
$messager && $messager([
'type' => 'message',
'level' => 'info',
'message' => 'Creating new Backup "' . $destination . '"'
]);
$messager && $messager([
'type' => 'message',
'level' => 'info',
'message' => ''
]);
$zip = new \ZipArchive();
$zip->open($destination, \ZipArchive::CREATE);
$max_execution_time = ini_set('max_execution_time', 600);
static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager);
$messager && $messager([
'type' => 'progress',
'percentage' => false,
'complete' => true
]);
$messager && $messager([
'type' => 'message',
'level' => 'info',
'message' => ''
]);
$messager && $messager([
'type' => 'message',
'level' => 'info',
'message' => 'Saving and compressing archive...'
]);
$zip->close();
if ($max_execution_time !== false) {
ini_set('max_execution_time', $max_execution_time);
}
return $destination;
}
/**
* @param $folder
* @param $zipFile
* @param $exclusiveLength
* @param $messager
*/
private static function folderToZip($folder, \ZipArchive $zipFile, $exclusiveLength, callable $messager = null)
{
$handle = opendir($folder);
while (false !== $f = readdir($handle)) {
if ($f !== '.' && $f !== '..') {
$filePath = "$folder/$f";
// Remove prefix from file path before add to zip.
$localPath = substr($filePath, $exclusiveLength);
if (in_array($f, static::$ignoreFolders)) {
continue;
}
if (in_array($localPath, static::$ignorePaths)) {
$zipFile->addEmptyDir($f);
continue;
}
if (is_file($filePath)) {
$zipFile->addFile($filePath, $localPath);
$messager && $messager([
'type' => 'progress',
'percentage' => false,
'complete' => false
]);
} elseif (is_dir($filePath)) {
// Add sub-directory.
$zipFile->addEmptyDir($localPath);
static::folderToZip($filePath, $zipFile, $exclusiveLength, $messager);
}
}
}
closedir($handle);
}
}
+15 -3
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common * @package Grav\Common
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -113,7 +114,7 @@ class Browser
{ {
$version = explode('.', $this->getLongVersion()); $version = explode('.', $this->getLongVersion());
return intval($version[0]); return (int)$version[0];
} }
/** /**
@@ -134,4 +135,15 @@ class Browser
return true; return true;
} }
/**
* Determine if “Do Not Track” is set by browser
* @see https://www.w3.org/TR/tracking-dnt/
*
* @return bool
*/
public function isTrackable(): bool
{
return !(isset($_SERVER['HTTP_DNT']) && $_SERVER['HTTP_DNT'] === '1');
}
} }
+209 -63
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common * @package Grav\Common
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -11,15 +12,16 @@ namespace Grav\Common;
use \Doctrine\Common\Cache as DoctrineCache; use \Doctrine\Common\Cache as DoctrineCache;
use Grav\Common\Config\Config; use Grav\Common\Config\Config;
use Grav\Common\Filesystem\Folder; use Grav\Common\Filesystem\Folder;
use Grav\Common\Scheduler\Scheduler;
use Psr\SimpleCache\CacheInterface;
use RocketTheme\Toolbox\Event\Event; use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\Event\EventDispatcher;
/** /**
* The GravCache object is used throughout Grav to store and retrieve cached data. * The GravCache object is used throughout Grav to store and retrieve cached data.
* It uses DoctrineCache library and supports a variety of caching mechanisms. Those include: * It uses DoctrineCache library and supports a variety of caching mechanisms. Those include:
* *
* APCu * APCu
* APC
* XCache
* RedisCache * RedisCache
* MemCache * MemCache
* MemCacheD * MemCacheD
@@ -43,6 +45,11 @@ class Cache extends Getters
*/ */
protected $driver; protected $driver;
/**
* @var CacheInterface
*/
protected $simpleCache;
protected $driver_name; protected $driver_name;
protected $driver_setting; protected $driver_setting;
@@ -117,37 +124,77 @@ class Cache extends Getters
$this->config = $grav['config']; $this->config = $grav['config'];
$this->now = time(); $this->now = time();
$this->cache_dir = $grav['locator']->findResource('cache://doctrine', true, true); if (null === $this->enabled) {
$this->enabled = (bool)$this->config->get('system.cache.enabled');
}
/** @var Uri $uri */ /** @var Uri $uri */
$uri = $grav['uri']; $uri = $grav['uri'];
$prefix = $this->config->get('system.cache.prefix'); $prefix = $this->config->get('system.cache.prefix');
$uniqueness = substr(md5($uri->rootUrl(true) . $this->config->key() . GRAV_VERSION), 2, 8);
if (is_null($this->enabled)) {
$this->enabled = (bool)$this->config->get('system.cache.enabled');
}
// Cache key allows us to invalidate all cache on configuration changes. // 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), $this->key = ($prefix ? $prefix : 'g') . '-' . $uniqueness;
2, 8); $this->cache_dir = $grav['locator']->findResource('cache://doctrine/' . $uniqueness, true, true);
$this->driver_setting = $this->config->get('system.cache.driver'); $this->driver_setting = $this->config->get('system.cache.driver');
$this->driver = $this->getCacheDriver(); $this->driver = $this->getCacheDriver();
// Set the cache namespace to our unique key
$this->driver->setNamespace($this->key); $this->driver->setNamespace($this->key);
/** @var EventDispatcher $dispatcher */
$dispatcher = Grav::instance()['events'];
$dispatcher->addListener('onSchedulerInitialized', [$this, 'onSchedulerInitialized']);
}
/**
* @return CacheInterface
*/
public function getSimpleCache()
{
if (null === $this->simpleCache) {
$cache = new \Grav\Framework\Cache\Adapter\DoctrineCache($this->driver, '', $this->getLifetime());
// Disable cache key validation.
$cache->setValidation(false);
$this->simpleCache = $cache;
}
return $this->simpleCache;
}
/**
* Deletes the old out of date file-based caches
*
* @return int
*/
public function purgeOldCache()
{
$cache_dir = dirname($this->cache_dir);
$current = basename($this->cache_dir);
$count = 0;
foreach (new \DirectoryIterator($cache_dir) as $file) {
$dir = $file->getBasename();
if ($dir === $current || $file->isDot() || $file->isFile()) {
continue;
}
Folder::delete($file->getPathname());
$count++;
}
return $count;
} }
/** /**
* Public accessor to set the enabled state of the cache * Public accessor to set the enabled state of the cache
* *
* @param $enabled * @param bool|int $enabled
*/ */
public function setEnabled($enabled) public function setEnabled($enabled)
{ {
$this->enabled = (bool) $enabled; $this->enabled = (bool)$enabled;
} }
/** /**
@@ -184,19 +231,15 @@ class Cache extends Getters
// CLI compatibility requires a non-volatile cache driver // CLI compatibility requires a non-volatile cache driver
if ($this->config->get('system.cache.cli_compatibility') && ( if ($this->config->get('system.cache.cli_compatibility') && (
$setting == 'auto' || $this->isVolatileDriver($setting))) { $setting === 'auto' || $this->isVolatileDriver($setting))) {
$setting = $driver_name; $setting = $driver_name;
} }
if (!$setting || $setting == 'auto') { if (!$setting || $setting === 'auto') {
if (extension_loaded('apcu')) { if (extension_loaded('apcu')) {
$driver_name = 'apcu'; $driver_name = 'apcu';
} elseif (extension_loaded('apc')) {
$driver_name = 'apc';
} elseif (extension_loaded('wincache')) { } elseif (extension_loaded('wincache')) {
$driver_name = 'wincache'; $driver_name = 'wincache';
} elseif (extension_loaded('xcache')) {
$driver_name = 'xcache';
} }
} else { } else {
$driver_name = $setting; $driver_name = $setting;
@@ -206,9 +249,6 @@ class Cache extends Getters
switch ($driver_name) { switch ($driver_name) {
case 'apc': case 'apc':
$driver = new DoctrineCache\ApcCache();
break;
case 'apcu': case 'apcu':
$driver = new DoctrineCache\ApcuCache(); $driver = new DoctrineCache\ApcuCache();
break; break;
@@ -217,45 +257,53 @@ class Cache extends Getters
$driver = new DoctrineCache\WinCacheCache(); $driver = new DoctrineCache\WinCacheCache();
break; break;
case 'xcache':
$driver = new DoctrineCache\XcacheCache();
break;
case 'memcache': case 'memcache':
$memcache = new \Memcache(); if (extension_loaded('memcache')) {
$memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'), $memcache = new \Memcache();
$this->config->get('system.cache.memcache.port', 11211)); $memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'),
$driver = new DoctrineCache\MemcacheCache(); $this->config->get('system.cache.memcache.port', 11211));
$driver->setMemcache($memcache); $driver = new DoctrineCache\MemcacheCache();
$driver->setMemcache($memcache);
} else {
throw new \LogicException('Memcache PHP extension has not been installed');
}
break; break;
case 'memcached': case 'memcached':
$memcached = new \Memcached(); if (extension_loaded('memcached')) {
$memcached->addServer($this->config->get('system.cache.memcached.server', 'localhost'), $memcached = new \Memcached();
$this->config->get('system.cache.memcached.port', 11211)); $memcached->addServer($this->config->get('system.cache.memcached.server', 'localhost'),
$driver = new DoctrineCache\MemcachedCache(); $this->config->get('system.cache.memcached.port', 11211));
$driver->setMemcached($memcached); $driver = new DoctrineCache\MemcachedCache();
$driver->setMemcached($memcached);
} else {
throw new \LogicException('Memcached PHP extension has not been installed');
}
break; break;
case 'redis': case 'redis':
$redis = new \Redis(); if (extension_loaded('redis')) {
$socket = $this->config->get('system.cache.redis.socket', false); $redis = new \Redis();
$password = $this->config->get('system.cache.redis.password', false); $socket = $this->config->get('system.cache.redis.socket', false);
$password = $this->config->get('system.cache.redis.password', false);
if ($socket) { if ($socket) {
$redis->connect($socket); $redis->connect($socket);
} else {
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
$this->config->get('system.cache.redis.port', 6379));
}
// Authenticate with password if set
if ($password && !$redis->auth($password)) {
throw new \RedisException('Redis authentication failed');
}
$driver = new DoctrineCache\RedisCache();
$driver->setRedis($redis);
} else { } else {
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'), throw new \LogicException('Redis PHP extension has not been installed');
$this->config->get('system.cache.redis.port', 6379));
} }
// Authenticate with password if set
if ($password && !$redis->auth($password)) {
throw new \RedisException('Redis authentication failed');
}
$driver = new DoctrineCache\RedisCache();
$driver->setRedis($redis);
break; break;
default: default:
@@ -277,9 +325,9 @@ class Cache extends Getters
{ {
if ($this->enabled) { if ($this->enabled) {
return $this->driver->fetch($id); return $this->driver->fetch($id);
} else {
return false;
} }
return false;
} }
/** /**
@@ -310,6 +358,21 @@ class Cache extends Getters
if ($this->enabled) { if ($this->enabled) {
return $this->driver->delete($id); return $this->driver->delete($id);
} }
return false;
}
/**
* Deletes all cache
*
* @return bool
*/
public function deleteAll()
{
if ($this->enabled) {
return $this->driver->deleteAll();
}
return false; return false;
} }
@@ -324,6 +387,7 @@ class Cache extends Getters
if ($this->enabled) { if ($this->enabled) {
return $this->driver->contains(($id)); return $this->driver->contains(($id));
} }
return false; return false;
} }
@@ -373,6 +437,9 @@ class Cache extends Getters
case 'tmp-only': case 'tmp-only':
$remove_paths = self::$tmp_remove; $remove_paths = self::$tmp_remove;
break; break;
case 'invalidate':
$remove_paths = [];
break;
default: default:
if (Grav::instance()['config']->get('system.cache.clear_images_by_default')) { if (Grav::instance()['config']->get('system.cache.clear_images_by_default')) {
$remove_paths = self::$standard_remove; $remove_paths = self::$standard_remove;
@@ -382,6 +449,12 @@ class Cache extends Getters
} }
// Delete entries in the doctrine cache if required
if (in_array($remove, ['all', 'standard'])) {
$cache = Grav::instance()['cache'];
$cache->driver->deleteAll();
}
// Clearing cache event to add paths to clear // Clearing cache event to add paths to clear
Grav::instance()->fireEvent('onBeforeCacheClear', new Event(['remove' => $remove, 'paths' => &$remove_paths])); Grav::instance()->fireEvent('onBeforeCacheClear', new Event(['remove' => $remove, 'paths' => &$remove_paths]));
@@ -422,7 +495,7 @@ class Cache extends Getters
$output[] = ''; $output[] = '';
if (($remove == 'all' || $remove == 'standard') && file_exists($user_config)) { if (($remove === 'all' || $remove === 'standard') && file_exists($user_config)) {
touch($user_config); touch($user_config);
$output[] = '<red>Touched: </red>' . $user_config; $output[] = '<red>Touched: </red>' . $user_config;
@@ -440,6 +513,23 @@ class Cache extends Getters
return $output; return $output;
} }
public static function invalidateCache()
{
$user_config = USER_DIR . 'config/system.yaml';
if (file_exists($user_config)) {
touch($user_config);
}
// Clear stat cache
@clearstatcache();
// Clear opcache
if (function_exists('opcache_reset')) {
@opcache_reset();
}
}
/** /**
* Set the cache lifetime programmatically * Set the cache lifetime programmatically
@@ -452,7 +542,7 @@ class Cache extends Getters
return; return;
} }
$interval = $future - $this->now; $interval = (int)($future - $this->now);
if ($interval > 0 && $interval < $this->getLifetime()) { if ($interval > 0 && $interval < $this->getLifetime()) {
$this->lifetime = $interval; $this->lifetime = $interval;
} }
@@ -467,7 +557,7 @@ class Cache extends Getters
public function getLifetime() public function getLifetime()
{ {
if ($this->lifetime === null) { if ($this->lifetime === null) {
$this->lifetime = $this->config->get('system.cache.lifetime') ?: 604800; // 1 week default $this->lifetime = (int)($this->config->get('system.cache.lifetime') ?: 604800); // 1 week default
} }
return $this->lifetime; return $this->lifetime;
@@ -496,15 +586,71 @@ class Cache extends Getters
/** /**
* is this driver a volatile driver in that it resides in PHP process memory * is this driver a volatile driver in that it resides in PHP process memory
* *
* @param $setting * @param string $setting
* @return bool * @return bool
*/ */
public function isVolatileDriver($setting) public function isVolatileDriver($setting)
{ {
if (in_array($setting, ['apc', 'apcu', 'xcache', 'wincache'])) { if (in_array($setting, ['apc', 'apcu', 'xcache', 'wincache'])) {
return true; return true;
} else {
return false;
} }
return false;
} }
/**
* Static function to call as a scheduled Job to purge old Doctrine files
*/
public static function purgeJob()
{
/** @var Cache $cache */
$cache = Grav::instance()['cache'];
$deleted_folders = $cache->purgeOldCache();
echo 'Purged ' . $deleted_folders . ' old cache folders...';
}
/**
* Static function to call as a scheduled Job to clear Grav cache
*
* @param string $type
*/
public static function clearJob($type)
{
$result = static::clearCache($type);
static::invalidateCache();
echo strip_tags(implode("\n", $result));
}
public function onSchedulerInitialized(Event $event)
{
/** @var Scheduler $scheduler */
$scheduler = $event['scheduler'];
$config = Grav::instance()['config'];
// File Cache Purge
$at = $config->get('system.cache.purge_at');
$name = 'cache-purge';
$logs = 'logs/' . $name . '.out';
$job = $scheduler->addFunction('Grav\Common\Cache::purgeJob', [], $name );
$job->at($at);
$job->output($logs);
$job->backlink('/config/system#caching');
// Cache Clear
$at = $config->get('system.cache.clear_at');
$clear_type = $config->get('system.cache.clear_job_type');
$name = 'cache-clear';
$logs = 'logs/' . $name . '.out';
$job = $scheduler->addFunction('Grav\Common\Cache::clearJob', [$clear_type], $name );
$job->at($at);
$job->output($logs);
$job->backlink('/config/system#caching');
}
} }
+7 -6
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common * @package Grav\Common
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -11,7 +12,7 @@ namespace Grav\Common;
class Composer class Composer
{ {
/** @const Default composer location */ /** @const Default composer location */
const DEFAULT_PATH = "bin/composer.phar"; const DEFAULT_PATH = 'bin/composer.phar';
/** /**
* Returns the location of composer. * Returns the location of composer.
@@ -20,12 +21,12 @@ class Composer
*/ */
public static function getComposerLocation() public static function getComposerLocation()
{ {
if (!function_exists('shell_exec') || strtolower(substr(PHP_OS, 0, 3)) === 'win') { if (!\function_exists('shell_exec') || stripos(PHP_OS, 'win') === 0) {
return self::DEFAULT_PATH; return self::DEFAULT_PATH;
} }
// check for global composer install // check for global composer install
$path = trim(shell_exec("command -v composer")); $path = trim(shell_exec('command -v composer'));
// fall back to grav bundled composer // fall back to grav bundled composer
if (!$path || !preg_match('/(composer|composer\.phar)$/', $path)) { if (!$path || !preg_match('/(composer|composer\.phar)$/', $path)) {
@@ -46,7 +47,7 @@ class Composer
$composer = static::getComposerLocation(); $composer = static::getComposerLocation();
if ($composer !== static::DEFAULT_PATH && is_executable($composer)) { if ($composer !== static::DEFAULT_PATH && is_executable($composer)) {
$file = fopen($composer, 'r'); $file = fopen($composer, 'rb');
$firstLine = fgets($file); $firstLine = fgets($file);
fclose($file); fclose($file);
+9 -10
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -128,7 +129,7 @@ abstract class CompiledBase
*/ */
public function checksum() public function checksum()
{ {
if (!isset($this->checksum)) { if (null === $this->checksum) {
$this->checksum = md5(json_encode($this->files) . $this->version); $this->checksum = md5(json_encode($this->files) . $this->version);
} }
@@ -197,11 +198,9 @@ abstract class CompiledBase
$cache = include $filename; $cache = include $filename;
if ( if (
!is_array($cache) !\is_array($cache)
|| !isset($cache['checksum']) || !isset($cache['checksum'], $cache['data'], $cache['@class'])
|| !isset($cache['data']) || $cache['@class'] !== \get_class($this)
|| !isset($cache['@class'])
|| $cache['@class'] != get_class($this)
) { ) {
return false; return false;
} }
@@ -212,7 +211,7 @@ abstract class CompiledBase
} }
$this->createObject($cache['data']); $this->createObject($cache['data']);
$this->timestamp = isset($cache['timestamp']) ? $cache['timestamp'] : 0; $this->timestamp = $cache['timestamp'] ?? 0;
$this->finalizeObject(); $this->finalizeObject();
@@ -243,7 +242,7 @@ abstract class CompiledBase
} }
$cache = [ $cache = [
'@class' => get_class($this), '@class' => \get_class($this),
'timestamp' => time(), 'timestamp' => time(),
'checksum' => $this->checksum(), 'checksum' => $this->checksum(),
'files' => $this->files, 'files' => $this->files,
@@ -1,27 +1,30 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
namespace Grav\Common\Config; namespace Grav\Common\Config;
use Grav\Common\Data\Blueprint; use Grav\Common\Data\Blueprint;
use Grav\Common\Data\BlueprintSchema; use Grav\Common\Data\BlueprintSchema;
use Grav\Common\Grav; use Grav\Common\Grav;
/**
* Class CompiledBlueprints
* @package Grav\Common\Config
*/
class CompiledBlueprints extends CompiledBase class CompiledBlueprints extends CompiledBase
{ {
/** public function __construct($cacheFolder, array $files, $path)
* @var int Version number for the compiled file. {
*/ parent::__construct($cacheFolder, $files, $path);
public $version = 2;
/** $this->version = 2;
* @var BlueprintSchema Blueprints object. }
*/
protected $object;
/** /**
* Returns checksum from the configuration files. * Returns checksum from the configuration files.
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -12,16 +13,6 @@ use Grav\Common\File\CompiledYamlFile;
class CompiledConfig extends CompiledBase class CompiledConfig extends CompiledBase
{ {
/**
* @var int Version number for the compiled file.
*/
public $version = 1;
/**
* @var Config Configuration object.
*/
protected $object;
/** /**
* @var callable Blueprints loader. * @var callable Blueprints loader.
*/ */
@@ -32,6 +23,13 @@ class CompiledConfig extends CompiledBase
*/ */
protected $withDefaults; protected $withDefaults;
public function __construct($cacheFolder, array $files, $path)
{
parent::__construct($cacheFolder, $files, $path);
$this->version = 1;
}
/** /**
* Set blueprints for the configuration. * Set blueprints for the configuration.
* *
@@ -63,7 +61,7 @@ class CompiledConfig extends CompiledBase
*/ */
protected function createObject(array $data = []) protected function createObject(array $data = [])
{ {
if ($this->withDefaults && empty($data) && is_callable($this->callable)) { if ($this->withDefaults && empty($data) && \is_callable($this->callable)) {
$blueprints = $this->callable; $blueprints = $this->callable;
$data = $blueprints()->getDefaults(); $data = $blueprints()->getDefaults();
} }
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -12,15 +13,12 @@ use Grav\Common\File\CompiledYamlFile;
class CompiledLanguages extends CompiledBase class CompiledLanguages extends CompiledBase
{ {
/** public function __construct($cacheFolder, array $files, $path)
* @var int Version number for the compiled file. {
*/ parent::__construct($cacheFolder, $files, $path);
public $version = 1;
/** $this->version = 1;
* @var Languages Configuration object. }
*/
protected $object;
/** /**
* Create configuration object. * Create configuration object.
+19 -9
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -16,14 +17,24 @@ use Grav\Common\Utils;
class Config extends Data class Config extends Data
{ {
public $environment;
/** @var string */
protected $key;
/** @var string */ /** @var string */
protected $checksum; protected $checksum;
protected $modified = false; /** @var int */
protected $timestamp = 0; protected $timestamp = 0;
/** @var bool */
protected $modified = false;
public function key() public function key()
{ {
return $this->checksum(); if (null === $this->key) {
$this->key = md5($this->checksum . $this->timestamp);
}
return $this->key;
} }
public function checksum($checksum = null) public function checksum($checksum = null)
@@ -90,7 +101,7 @@ class Config extends Data
{ {
$setup = Grav::instance()['setup']->toArray(); $setup = Grav::instance()['setup']->toArray();
foreach ($setup as $key => $value) { foreach ($setup as $key => $value) {
if ($key === 'streams' || !is_array($value)) { if ($key === 'streams' || !\is_array($value)) {
// Optimized as streams and simple values are fully defined in setup. // Optimized as streams and simple values are fully defined in setup.
$this->items[$key] = $value; $this->items[$key] = $value;
} else { } else {
@@ -98,14 +109,13 @@ class Config extends Data
} }
} }
// Override the media.upload_limit based on PHP values // Legacy value - Override the media.upload_limit based on PHP values
$upload_limit = Utils::getUploadLimit(); $this->items['system']['media']['upload_limit'] = Utils::getUploadLimit();
$this->items['system']['media']['upload_limit'] = $upload_limit > 0 ? $upload_limit : 1024*1024*1024;
} }
/** /**
* @return mixed * @return mixed
* @deprecated * @deprecated 1.5 Use Grav::instance()['languages'] instead.
*/ */
public function getLanguages() public function getLanguages()
{ {
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
+30 -2
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -13,6 +14,22 @@ use Grav\Common\Utils;
class Languages extends Data class Languages extends Data
{ {
/**
* @var string|null
*/
protected $checksum;
/**
* @var string|null
*/
protected $modified;
/**
* @var string|null
*/
protected $timestamp;
public function checksum($checksum = null) public function checksum($checksum = null)
{ {
if ($checksum !== null) { if ($checksum !== null) {
@@ -52,4 +69,15 @@ class Languages extends Data
{ {
$this->items = Utils::arrayMergeRecursiveUnique($this->items, $data); $this->items = Utils::arrayMergeRecursiveUnique($this->items, $data);
} }
public function flattenByLang($lang)
{
$language = $this->items[$lang];
return Utils::arrayFlattenDotNotation($language);
}
public function unflatten($array)
{
return Utils::arrayUnflattenDotNotation($array);
}
} }
+57 -19
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Config * @package Grav\Common\Config
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -12,11 +13,23 @@ use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Data\Data; use Grav\Common\Data\Data;
use Grav\Common\Utils; use Grav\Common\Utils;
use Pimple\Container; use Pimple\Container;
use RocketTheme\Toolbox\File\YamlFile; use Psr\Http\Message\ServerRequestInterface;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class Setup extends Data class Setup extends Data
{ {
/**
* @var array Environment aliases normalized to lower case.
*/
public static $environments = [
'' => 'unknown',
'127.0.0.1' => 'localhost',
'::1' => 'localhost'
];
/**
* @var string Current environment normalized to lower case.
*/
public static $environment; public static $environment;
protected $streams = [ protected $streams = [
@@ -38,7 +51,7 @@ class Setup extends Data
// If not defined, environment will be set up in the constructor. // If not defined, environment will be set up in the constructor.
], ],
'asset' => [ 'asset' => [
'type' => 'ReadOnlyStream', 'type' => 'Stream',
'prefixes' => [ 'prefixes' => [
'' => ['assets'], '' => ['assets'],
] ]
@@ -109,7 +122,7 @@ class Setup extends Data
] ]
], ],
'image' => [ 'image' => [
'type' => 'ReadOnlyStream', 'type' => 'Stream',
'prefixes' => [ 'prefixes' => [
'' => ['user://images', 'system://images'] '' => ['user://images', 'system://images']
] ]
@@ -120,6 +133,13 @@ class Setup extends Data
'' => ['user://pages'] '' => ['user://pages']
] ]
], ],
'user-data' => [
'type' => 'Stream',
'force' => true,
'prefixes' => [
'' => ['user://data']
]
],
'account' => [ 'account' => [
'type' => 'ReadOnlyStream', 'type' => 'ReadOnlyStream',
'prefixes' => [ 'prefixes' => [
@@ -133,12 +153,26 @@ class Setup extends Data
*/ */
public function __construct($container) public function __construct($container)
{ {
$environment = null !== static::$environment ? static::$environment : ($container['uri']->environment() ?: 'localhost'); // If no environment is set, make sure we get one (CLI or hostname).
if (!static::$environment) {
if (\defined('GRAV_CLI')) {
static::$environment = 'cli';
} else {
/** @var ServerRequestInterface $request */
$request = $container['request'];
$host = $request->getUri()->getHost();
static::$environment = Utils::substrToString($host, ':');
}
}
// Resolve server aliases to the proper environment.
$environment = $this->environments[static::$environment] ?? static::$environment;
// Pre-load setup.php which contains our initial configuration. // Pre-load setup.php which contains our initial configuration.
// Configuration may contain dynamic parts, which is why we need to always load it. // Configuration may contain dynamic parts, which is why we need to always load it.
// If "GRAVE_SETUP_PATH" has been defined, use it, otherwise use defaults. // If "GRAV_SETUP_PATH" has been defined, use it, otherwise use defaults.
$file = defined('GRAV_SETUP_PATH') ? GRAV_SETUP_PATH : GRAV_ROOT . '/setup.php'; $file = \defined('GRAV_SETUP_PATH') ? GRAV_SETUP_PATH : GRAV_ROOT . '/setup.php';
$setup = is_file($file) ? (array) include $file : []; $setup = is_file($file) ? (array) include $file : [];
// Add default streams defined in beginning of the class. // Add default streams defined in beginning of the class.
@@ -151,8 +185,8 @@ class Setup extends Data
parent::__construct($setup); parent::__construct($setup);
// Set up environment. // Set up environment.
$this->def('environment', $environment ?: 'cli'); $this->def('environment', $environment);
$this->def('streams.schemes.environment.prefixes', ['' => $environment ? ["user://{$this->environment}"] : []]); $this->def('streams.schemes.environment.prefixes', ['' => ["user://{$this->get('environment')}"]]);
} }
/** /**
@@ -212,8 +246,8 @@ class Setup extends Data
$locator->addPath($scheme, '', $config['paths']); $locator->addPath($scheme, '', $config['paths']);
} }
$override = isset($config['override']) ? $config['override'] : false; $override = $config['override'] ?? false;
$force = isset($config['force']) ? $config['force'] : false; $force = $config['force'] ?? false;
if (isset($config['prefixes'])) { if (isset($config['prefixes'])) {
foreach ((array)$config['prefixes'] as $prefix => $paths) { foreach ((array)$config['prefixes'] as $prefix => $paths) {
@@ -232,7 +266,7 @@ class Setup extends Data
{ {
$schemes = []; $schemes = [];
foreach ((array) $this->get('streams.schemes') as $scheme => $config) { foreach ((array) $this->get('streams.schemes') as $scheme => $config) {
$type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream'; $type = $config['type'] ?? 'ReadOnlyStream';
if ($type[0] !== '\\') { if ($type[0] !== '\\') {
$type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type; $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type;
} }
@@ -251,8 +285,8 @@ class Setup extends Data
*/ */
protected function check(UniformResourceLocator $locator) protected function check(UniformResourceLocator $locator)
{ {
$streams = isset($this->items['streams']['schemes']) ? $this->items['streams']['schemes'] : null; $streams = $this->items['streams']['schemes'] ?? null;
if (!is_array($streams)) { if (!\is_array($streams)) {
throw new \InvalidArgumentException('Configuration is missing streams.schemes!'); throw new \InvalidArgumentException('Configuration is missing streams.schemes!');
} }
$diff = array_keys(array_diff_key($this->streams, $streams)); $diff = array_keys(array_diff_key($this->streams, $streams));
@@ -271,10 +305,14 @@ class Setup extends Data
// Create security.yaml if it doesn't exist. // Create security.yaml if it doesn't exist.
$filename = $locator->findResource('config://security.yaml', true, true); $filename = $locator->findResource('config://security.yaml', true, true);
$file = YamlFile::instance($filename); $security_file = CompiledYamlFile::instance($filename);
if (!$file->exists()) { $security_content = (array)$security_file->content();
$file->save(['salt' => Utils::generateRandomString(14)]);
$file->free(); if (!isset($security_content['salt'])) {
$security_content = array_merge($security_content, ['salt' => Utils::generateRandomString(14)]);
$security_file->content($security_content);
$security_file->save();
$security_file->free();
} }
} catch (\RuntimeException $e) { } catch (\RuntimeException $e) {
throw new \RuntimeException(sprintf('Grav failed to initialize: %s', $e->getMessage()), 500, $e); throw new \RuntimeException(sprintf('Grav failed to initialize: %s', $e->getMessage()), 500, $e);
+200 -26
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Data * @package Grav\Common\Data
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -10,21 +11,37 @@ namespace Grav\Common\Data;
use Grav\Common\File\CompiledYamlFile; use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Grav; use Grav\Common\Grav;
use Grav\Common\User\Interfaces\UserInterface;
use RocketTheme\Toolbox\Blueprints\BlueprintForm; use RocketTheme\Toolbox\Blueprints\BlueprintForm;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class Blueprint extends BlueprintForm class Blueprint extends BlueprintForm
{ {
/** /** @var string */
* @var string
*/
protected $context = 'blueprints://'; protected $context = 'blueprints://';
/** protected $scope;
* @var BlueprintSchema
*/ /** @var BlueprintSchema */
protected $blueprintSchema; protected $blueprintSchema;
/** @var array */
protected $defaults;
protected $handlers = [];
public function __clone()
{
if ($this->blueprintSchema) {
$this->blueprintSchema = clone $this->blueprintSchema;
}
}
public function setScope($scope)
{
$this->scope = $scope;
}
/** /**
* Set default values for field types. * Set default values for field types.
* *
@@ -51,7 +68,60 @@ class Blueprint extends BlueprintForm
{ {
$this->initInternals(); $this->initInternals();
return $this->blueprintSchema->getDefaults(); if (null === $this->defaults) {
$this->defaults = $this->blueprintSchema->getDefaults();
}
return $this->defaults;
}
/**
* Initialize blueprints with its dynamic fields.
*
* @return $this
*/
public function init()
{
foreach ($this->dynamic as $key => $data) {
// Locate field.
$path = explode('/', $key);
$current = &$this->items;
foreach ($path as $field) {
if (\is_object($current)) {
// Handle objects.
if (!isset($current->{$field})) {
$current->{$field} = [];
}
$current = &$current->{$field};
} else {
// Handle arrays and scalars.
if (!\is_array($current)) {
$current = [$field => []];
} elseif (!isset($current[$field])) {
$current[$field] = [];
}
$current = &$current[$field];
}
}
// Set dynamic property.
foreach ($data as $property => $call) {
$action = $call['action'];
$method = 'dynamic' . ucfirst($action);
if (isset($this->handlers[$action])) {
$callable = $this->handlers[$action];
$callable($current, $property, $call);
} elseif (method_exists($this, $method)) {
$this->{$method}($current, $property, $call);
}
}
}
return $this;
} }
/** /**
@@ -70,6 +140,20 @@ class Blueprint extends BlueprintForm
return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator); return $this->blueprintSchema->mergeData($data1, $data2, $name, $separator);
} }
/**
* Process data coming from a form.
*
* @param array $data
* @param array $toggles
* @return array
*/
public function processForm(array $data, array $toggles = [])
{
$this->initInternals();
return $this->blueprintSchema->processForm($data, $toggles);
}
/** /**
* Return data fields that do not exist in blueprints. * Return data fields that do not exist in blueprints.
* *
@@ -101,15 +185,32 @@ class Blueprint extends BlueprintForm
* Filter data by using blueprints. * Filter data by using blueprints.
* *
* @param array $data * @param array $data
* @param bool $missingValuesAsNull
* @param bool $keepEmptyValues
* @return array * @return array
*/ */
public function filter(array $data) public function filter(array $data, bool $missingValuesAsNull = false, bool $keepEmptyValues = false)
{ {
$this->initInternals(); $this->initInternals();
return $this->blueprintSchema->filter($data); return $this->blueprintSchema->filter($data, $missingValuesAsNull, $keepEmptyValues);
} }
/**
* Flatten data by using blueprints.
*
* @param array $data
* @return array
*/
public function flattenData(array $data)
{
$this->initInternals();
return $this->blueprintSchema->flattenData($data);
}
/** /**
* Return blueprint data schema. * Return blueprint data schema.
* *
@@ -122,20 +223,28 @@ class Blueprint extends BlueprintForm
return $this->blueprintSchema; return $this->blueprintSchema;
} }
public function addDynamicHandler(string $name, callable $callable): void
{
$this->handlers[$name] = $callable;
}
/** /**
* Initialize validator. * Initialize validator.
*/ */
protected function initInternals() protected function initInternals()
{ {
if (!isset($this->blueprintSchema)) { if (null === $this->blueprintSchema) {
$types = Grav::instance()['plugins']->formFieldTypes; $types = Grav::instance()['plugins']->formFieldTypes;
$this->blueprintSchema = new BlueprintSchema; $this->blueprintSchema = new BlueprintSchema;
if ($types) { if ($types) {
$this->blueprintSchema->setTypes($types); $this->blueprintSchema->setTypes($types);
} }
$this->blueprintSchema->embed('', $this->items); $this->blueprintSchema->embed('', $this->items);
$this->blueprintSchema->init(); $this->blueprintSchema->init();
$this->defaults = null;
} }
} }
@@ -162,17 +271,19 @@ class Blueprint extends BlueprintForm
/** @var UniformResourceLocator $locator */ /** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator']; $locator = Grav::instance()['locator'];
if (is_string($path) && !$locator->isStream($path)) { if (\is_string($path) && !$locator->isStream($path)) {
// Find path overrides. // Find path overrides.
$paths = isset($this->overrides[$path]) ? (array) $this->overrides[$path] : []; $paths = (array) ($this->overrides[$path] ?? null);
// Add path pointing to default context. // Add path pointing to default context.
if ($context === null) { if ($context === null) {
$context = $this->context; $context = $this->context;
} }
if ($context && $context[strlen($context)-1] !== '/') {
if ($context && $context[\strlen($context)-1] !== '/') {
$context .= '/'; $context .= '/';
} }
$path = $context . $path; $path = $context . $path;
if (!preg_match('/\.yaml$/', $path)) { if (!preg_match('/\.yaml$/', $path)) {
@@ -186,7 +297,7 @@ class Blueprint extends BlueprintForm
$files = []; $files = [];
foreach ($paths as $lookup) { foreach ($paths as $lookup) {
if (is_string($lookup) && strpos($lookup, '://')) { if (\is_string($lookup) && strpos($lookup, '://')) {
$files = array_merge($files, $locator->findResources($lookup)); $files = array_merge($files, $locator->findResources($lookup));
} else { } else {
$files[] = $lookup; $files[] = $lookup;
@@ -205,27 +316,29 @@ class Blueprint extends BlueprintForm
{ {
$params = $call['params']; $params = $call['params'];
if (is_array($params)) { if (\is_array($params)) {
$function = array_shift($params); $function = array_shift($params);
} else { } else {
$function = $params; $function = $params;
$params = []; $params = [];
} }
list($o, $f) = preg_split('/::/', $function, 2); [$o, $f] = explode('::', $function, 2);
$data = null;
if (!$f) { if (!$f) {
if (function_exists($o)) { if (\function_exists($o)) {
$data = call_user_func_array($o, $params); $data = \call_user_func_array($o, $params);
} }
} else { } else {
if (method_exists($o, $f)) { if (method_exists($o, $f)) {
$data = call_user_func_array(array($o, $f), $params); $data = \call_user_func_array([$o, $f], $params);
} }
} }
// If function returns a value, // If function returns a value,
if (isset($data)) { if (null !== $data) {
if (isset($field[$property]) && is_array($field[$property]) && is_array($data)) { if (\is_array($data) && isset($field[$property]) && \is_array($field[$property])) {
// Combine field and @data-field together. // Combine field and @data-field together.
$field[$property] += $data; $field[$property] += $data;
} else { } else {
@@ -243,12 +356,73 @@ class Blueprint extends BlueprintForm
protected function dynamicConfig(array &$field, $property, array &$call) protected function dynamicConfig(array &$field, $property, array &$call)
{ {
$value = $call['params']; $value = $call['params'];
$default = $field[$property] ?? null;
$default = isset($field[$property]) ? $field[$property] : null;
$config = Grav::instance()['config']->get($value, $default); $config = Grav::instance()['config']->get($value, $default);
if (!is_null($config)) { if (null !== $config) {
$field[$property] = $config; $field[$property] = $config;
} }
} }
/**
* @param array $field
* @param string $property
* @param array $call
*/
protected function dynamicSecurity(array &$field, $property, array &$call)
{
if ($property || !empty($field['validate']['ignore'])) {
return;
}
$grav = Grav::instance();
$actions = (array)$call['params'];
/** @var UserInterface|null $user */
$user = $grav['user'] ?? null;
foreach ($actions as $action) {
if (!$user || !$user->authorize($action)) {
$this->addPropertyRecursive($field, 'validate', ['ignore' => true]);
return;
}
}
}
/**
* @param array $field
* @param string $property
* @param array $call
*/
protected function dynamicScope(array &$field, $property, array &$call)
{
if ($property && $property !== 'ignore') {
return;
}
$scopes = (array)$call['params'];
$matches = \in_array($this->scope, $scopes, true);
if ($this->scope && $property !== 'ignore') {
$matches = !$matches;
}
if ($matches) {
$this->addPropertyRecursive($field, 'validate', ['ignore' => true]);
return;
}
}
protected function addPropertyRecursive(array &$field, $property, $value)
{
if (\is_array($value) && isset($field[$property]) && \is_array($field[$property])) {
$field[$property] = array_merge_recursive($field[$property], $value);
} else {
$field[$property] = $value;
}
if (!empty($field['fields'])) {
foreach ($field['fields'] as $key => &$child) {
$this->addPropertyRecursive($child, $property, $value);
}
}
}
} }
+174 -26
View File
@@ -1,8 +1,9 @@
<?php <?php
/** /**
* @package Grav.Common.Data * @package Grav\Common\Data
* *
* @copyright Copyright (C) 2015 - 2018 Trilby Media, LLC. All rights reserved. * @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details. * @license MIT License; see LICENSE file for details.
*/ */
@@ -26,6 +27,23 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
'fields' => true 'fields' => true
]; ];
/**
* @return array
*/
public function getTypes()
{
return $this->types;
}
/**
* @param string $name
* @return array
*/
public function getType($name)
{
return $this->types[$name] ?? [];
}
/** /**
* Validate data against blueprints. * Validate data against blueprints.
* *
@@ -47,35 +65,90 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
} }
/** /**
* Filter data by using blueprints. * @param array $data
* * @param array $toggles
* @param array $data
* @return array * @return array
*/ */
public function filter(array $data) public function processForm(array $data, array $toggles = [])
{ {
return $this->filterArray($data, $this->nested); return $this->processFormRecursive($data, $toggles, $this->nested);
}
/**
* Filter data by using blueprints.
*
* @param array $data Incoming data, for example from a form.
* @param bool $missingValuesAsNull Include missing values as nulls.
* @param bool $keepEmptyValues Include empty values.
* @return array
*/
public function filter(array $data, $missingValuesAsNull = false, $keepEmptyValues = false)
{
return $this->filterArray($data, $this->nested, $missingValuesAsNull, $keepEmptyValues);
}
/**
* Flatten data by using blueprints.
*
* @param array $data Data to be flattened.
* @return array
*/
public function flattenData(array $data)
{
return $this->flattenArray($data, $this->nested, '');
} }
/** /**
* @param array $data * @param array $data
* @param array $rules * @param array $rules
* @returns array * @param string $prefix
* @return array
*/
protected function flattenArray(array $data, array $rules, string $prefix)
{
$array = [];
foreach ($data as $key => $field) {
$val = $rules[$key] ?? $rules['*'] ?? null;
$rule = is_string($val) ? $this->items[$val] : null;
if ($rule || isset($val['*'])) {
// Item has been defined in blueprints.
$array[$prefix.$key] = $field;
} elseif (is_array($field) && is_array($val)) {
// Array has been defined in blueprints.
$array += $this->flattenArray($field, $val, $prefix . $key . '.');
} else {
// Undefined/extra item.
$array[$prefix.$key] = $field;
}
}
return $array;
}
/**
* @param array $data
* @param array $rules
* @return array
* @throws \RuntimeException * @throws \RuntimeException
* @internal
*/ */
protected function validateArray(array $data, array $rules) protected function validateArray(array $data, array $rules)
{ {
$messages = $this->checkRequired($data, $rules); $messages = $this->checkRequired($data, $rules);
foreach ($data as $key => $field) { foreach ($data as $key => $field) {
$val = isset($rules[$key]) ? $rules[$key] : (isset($rules['*']) ? $rules['*'] : null); $val = $rules[$key] ?? $rules['*'] ?? null;
$rule = is_string($val) ? $this->items[$val] : null; $rule = \is_string($val) ? $this->items[$val] : null;
if ($rule) { if ($rule) {
// Item has been defined in blueprints. // Item has been defined in blueprints.
if (!empty($rule['disabled']) || !empty($rule['validate']['ignore'])) {
// Skip validation in the ignored field.
continue;
}
$messages += Validation::validate($field, $rule); $messages += Validation::validate($field, $rule);
} elseif (is_array($field) && is_array($val)) { } elseif (\is_array($field) && \is_array($val)) {
// Array has been defined in blueprints. // Array has been defined in blueprints.
$messages += $this->validateArray($field, $val); $messages += $this->validateArray($field, $val);
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') { } elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
@@ -90,32 +163,99 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
/** /**
* @param array $data * @param array $data
* @param array $rules * @param array $rules
* @param bool $missingValuesAsNull
* @param bool $keepEmptyValues
* @return array * @return array
* @internal
*/ */
protected function filterArray(array $data, array $rules) protected function filterArray(array $data, array $rules, $missingValuesAsNull, $keepEmptyValues)
{ {
$results = array(); $results = [];
if ($missingValuesAsNull) {
// First pass is to fill up all the fields with null. This is done to lock the ordering of the fields.
foreach ($rules as $key => $rule) {
if ($key && !isset($results[$key])) {
$val = $rules[$key] ?? $rules['*'] ?? null;
$rule = \is_string($val) ? $this->items[$val] : null;
if (empty($rule['disabled']) && empty($rule['validate']['ignore'])) {
continue;
}
}
}
}
foreach ($data as $key => $field) { foreach ($data as $key => $field) {
$val = isset($rules[$key]) ? $rules[$key] : (isset($rules['*']) ? $rules['*'] : null); $val = $rules[$key] ?? $rules['*'] ?? null;
$rule = is_string($val) ? $this->items[$val] : null; $rule = \is_string($val) ? $this->items[$val] : null;
if ($rule) { if ($rule) {
// Item has been defined in blueprints. // Item has been defined in blueprints.
if (!empty($rule['disabled']) || !empty($rule['validate']['ignore'])) {
// Skip any data in the ignored field.
unset($results[$key]);
continue;
}
$field = Validation::filter($field, $rule); $field = Validation::filter($field, $rule);
} elseif (is_array($field) && is_array($val)) { } elseif (\is_array($field) && \is_array($val)) {
// Array has been defined in blueprints. // Array has been defined in blueprints.
$field = $this->filterArray($field, $val); $field = $this->filterArray($field, $val, $missingValuesAsNull, $keepEmptyValues);
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') { } elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
$field = null; // Skip any extra data.
continue;
} }
if (isset($field) && (!is_array($field) || !empty($field))) { if ($keepEmptyValues || (null !== $field && (!\is_array($field) || !empty($field)))) {
$results[$key] = $field; $results[$key] = $field;
} }
} }
return $results; return $results ?: null;
}
/**
* @param array|null $data
* @param array $toggles
* @param array $nested
* @return array|null
*/
protected function processFormRecursive(?array $data, array $toggles, array $nested)
{
foreach ($nested as $key => $value) {
if ($key === '') {
continue;
}
if ($key === '*') {
// TODO: Add support to collections.
continue;
}
if (is_array($value)) {
// Recursively fetch the items.
$data[$key] = $this->processFormRecursive($data[$key] ?? null, $toggles[$key] ?? [], $value);
} else {
$field = $this->get($value);
// Do not add the field if:
if (
// Not an input field
!$field
// Field has been disabled
|| !empty($field['disabled'])
// Field validation is set to be ignored
|| !empty($field['validate']['ignore'])
// Field is toggleable and the toggle is turned off
|| (!empty($field['toggleable']) && empty($toggles[$key]))
) {
continue;
}
if (!isset($data[$key])) {
$data[$key] = null;
}
}
}
return $data;
} }
/** /**
@@ -128,10 +268,18 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
$messages = []; $messages = [];
foreach ($fields as $name => $field) { foreach ($fields as $name => $field) {
if (!is_string($field)) { if (!\is_string($field)) {
continue; continue;
} }
$field = $this->items[$field]; $field = $this->items[$field];
// Skip ignored field, it will not be required.
if (!empty($field['disabled']) || !empty($field['validate']['ignore'])) {
continue;
}
// Check if required.
if (isset($field['validate']['required']) if (isset($field['validate']['required'])
&& $field['validate']['required'] === true) { && $field['validate']['required'] === true) {
@@ -142,9 +290,9 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
continue; continue;
} }
$value = isset($field['label']) ? $field['label'] : $field['name']; $value = $field['label'] ?? $field['name'];
$language = Grav::instance()['language']; $language = Grav::instance()['language'];
$message = sprintf($language->translate('FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $language->translate($value)); $message = sprintf($language->translate('GRAV.FORM.MISSING_REQUIRED_FIELD', null, true) . ' %s', $language->translate($value));
$messages[$field['name']][] = $message; $messages[$field['name']][] = $message;
} }
} }
@@ -161,7 +309,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
{ {
$value = $call['params']; $value = $call['params'];
$default = isset($field[$property]) ? $field[$property] : null; $default = $field[$property] ?? null;
$config = Grav::instance()['config']->get($value, $default); $config = Grav::instance()['config']->get($value, $default);
if (null !== $config) { if (null !== $config) {

Some files were not shown because too many files have changed in this diff Show More