mirror of
https://github.com/getgrav/grav.git
synced 2025-12-05 23:39:58 +01:00
Compare commits
227 Commits
1.6.0-rc.3
...
1.6.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bc6848464 | ||
|
|
abefbfc776 | ||
|
|
ad173ca129 | ||
|
|
d69ef0e39c | ||
|
|
436be17881 | ||
|
|
9a5fa7e699 | ||
|
|
d502ff08c1 | ||
|
|
14eb1281f9 | ||
|
|
8fd7a5aebe | ||
|
|
08423df547 | ||
|
|
40563ed2f8 | ||
|
|
b639f09ca7 | ||
|
|
dd134ad551 | ||
|
|
3d93d50cf0 | ||
|
|
f1da7b6063 | ||
|
|
ef7b33f9b6 | ||
|
|
0f0e6ab1c8 | ||
|
|
5362b312d1 | ||
|
|
ca4d6a398f | ||
|
|
ed00d480f2 | ||
|
|
057bdd546b | ||
|
|
7762f0c85e | ||
|
|
1e6c01ea65 | ||
|
|
4b777f508b | ||
|
|
d15f125964 | ||
|
|
32b435b7e6 | ||
|
|
31d301911f | ||
|
|
911eec5e68 | ||
|
|
2e4bb25e2e | ||
|
|
d99c80eae9 | ||
|
|
0e03240d13 | ||
|
|
02064117bc | ||
|
|
a9e0cc7159 | ||
|
|
6b4332db72 | ||
|
|
0f591953a0 | ||
|
|
0a5e78ccc6 | ||
|
|
fbf7c50a12 | ||
|
|
09c1255239 | ||
|
|
75650ceba3 | ||
|
|
e2a65004f3 | ||
|
|
d4e1bcc660 | ||
|
|
b1b1670c77 | ||
|
|
5a3674f6f6 | ||
|
|
e622e204bf | ||
|
|
c378b06a90 | ||
|
|
c6ce6e6c32 | ||
|
|
355f7ee748 | ||
|
|
c19fa22a26 | ||
|
|
5ba4c8ee5b | ||
|
|
306df5837d | ||
|
|
66bba376db | ||
|
|
ec07d37623 | ||
|
|
cab78d36f3 | ||
|
|
449682baea | ||
|
|
6eb11b9717 | ||
|
|
5a1d138d08 | ||
|
|
dfd75efbe5 | ||
|
|
76ed48fc7c | ||
|
|
1043b9a189 | ||
|
|
e401c683f5 | ||
|
|
9d4fe331fa | ||
|
|
fbae3fd194 | ||
|
|
022f1ce758 | ||
|
|
b367c664c7 | ||
|
|
8512968726 | ||
|
|
2ffc110f03 | ||
|
|
36836c516f | ||
|
|
1f288c25de | ||
|
|
a4b62d48b2 | ||
|
|
397f6902f3 | ||
|
|
e97bceed56 | ||
|
|
7efc0f418e | ||
|
|
ac2a4e1c06 | ||
|
|
ef43348020 | ||
|
|
b6e68bb362 | ||
|
|
8d9ceb5d99 | ||
|
|
af47825b76 | ||
|
|
a4c88697af | ||
|
|
45fbfb098a | ||
|
|
9172e442f2 | ||
|
|
3b91f9af8c | ||
|
|
d5e9cc4bfe | ||
|
|
bb719c5d53 | ||
|
|
05a6775b08 | ||
|
|
1accbb8edc | ||
|
|
a04a7f5714 | ||
|
|
f31f7f7499 | ||
|
|
354d6f307c | ||
|
|
90aa4083ca | ||
|
|
5fbd252db9 | ||
|
|
04d3237a89 | ||
|
|
55aaaeed47 | ||
|
|
84d995335e | ||
|
|
f7d3299ebb | ||
|
|
e762c3add9 | ||
|
|
df6bb065d3 | ||
|
|
2fed02affa | ||
|
|
a739ed6825 | ||
|
|
90c708db2b | ||
|
|
fcbd819f48 | ||
|
|
a25d18bca7 | ||
|
|
4480077894 | ||
|
|
e9aa338c1e | ||
|
|
88a3e874aa | ||
|
|
87814039bc | ||
|
|
af72951671 | ||
|
|
5f2dfc8221 | ||
|
|
c706756d19 | ||
|
|
a4801ead6a | ||
|
|
a57cec8404 | ||
|
|
8b171435a7 | ||
|
|
ab23d071a4 | ||
|
|
3e6c4e9c5e | ||
|
|
28db98c95d | ||
|
|
95583dbbcd | ||
|
|
9d8fc4a065 | ||
|
|
b23cd7bb65 | ||
|
|
28d5be982c | ||
|
|
3836e4d38a | ||
|
|
4ebfd51e98 | ||
|
|
25ff1241d4 | ||
|
|
0dc3e5806e | ||
|
|
982b12a239 | ||
|
|
5995515419 | ||
|
|
8c1c813acd | ||
|
|
0e95d7faf6 | ||
|
|
47c3d4bf9b | ||
|
|
33282e043b | ||
|
|
81efef7c60 | ||
|
|
2678f56499 | ||
|
|
cd8f578b39 | ||
|
|
ab535ec8be | ||
|
|
ada6c3f160 | ||
|
|
0917850634 | ||
|
|
c09a8fbbc4 | ||
|
|
2b392055c1 | ||
|
|
45acd237f5 | ||
|
|
cbf79e38c4 | ||
|
|
ed10ce03e2 | ||
|
|
561abc851f | ||
|
|
8789fd91ee | ||
|
|
b835db49f4 | ||
|
|
a5e832b0b0 | ||
|
|
2b16f813ef | ||
|
|
30b013f5b0 | ||
|
|
5eccfaa34b | ||
|
|
fde69ade6b | ||
|
|
af3d5e9683 | ||
|
|
c757e00ac9 | ||
|
|
19d61b4013 | ||
|
|
b4a4b60871 | ||
|
|
9727f30c61 | ||
|
|
db8e5b3cbb | ||
|
|
b0b6c1dd17 | ||
|
|
47bb35e2e9 | ||
|
|
2433e0d2cd | ||
|
|
cdf891478e | ||
|
|
39b1940f94 | ||
|
|
8564524984 | ||
|
|
2f74f0f587 | ||
|
|
6e2e533184 | ||
|
|
ecd39421d6 | ||
|
|
68d43a0c88 | ||
|
|
c80a3f5568 | ||
|
|
b3d84a05f5 | ||
|
|
95495614a8 | ||
|
|
45d7a164b5 | ||
|
|
97b236d117 | ||
|
|
8718c5ef31 | ||
|
|
7d7418df26 | ||
|
|
dd9aa5bf78 | ||
|
|
7f86f8eb6f | ||
|
|
8b4cac7ba6 | ||
|
|
b388e91177 | ||
|
|
a2ac3f4c8b | ||
|
|
1db8b93cfa | ||
|
|
6217ac90e0 | ||
|
|
bb385490bc | ||
|
|
a5e48ba160 | ||
|
|
c7a4e8e4bb | ||
|
|
85d5b6e889 | ||
|
|
1c725c02f0 | ||
|
|
5008672a48 | ||
|
|
4e03f19bac | ||
|
|
a03c328ee3 | ||
|
|
77ac68f2e8 | ||
|
|
02acc34461 | ||
|
|
a402a8ef84 | ||
|
|
60573c1d78 | ||
|
|
56adf40bb4 | ||
|
|
d33c45165d | ||
|
|
032acedafe | ||
|
|
6a48216afb | ||
|
|
85af461eb4 | ||
|
|
4b1a129f38 | ||
|
|
1762ef3d1e | ||
|
|
8ffba2d88d | ||
|
|
f19cb94f89 | ||
|
|
8fb7caa22a | ||
|
|
07646860f2 | ||
|
|
6765c5f594 | ||
|
|
026f9cb3a0 | ||
|
|
516dfd5c26 | ||
|
|
1fbd5e0b38 | ||
|
|
b35a892853 | ||
|
|
578f8e4947 | ||
|
|
a934dd4fff | ||
|
|
18625758e5 | ||
|
|
eb689c417b | ||
|
|
df226a1102 | ||
|
|
8947f5ade9 | ||
|
|
941a5db8de | ||
|
|
2fcaaea6ac | ||
|
|
5887a396c1 | ||
|
|
f934256e06 | ||
|
|
ccb465e998 | ||
|
|
1b0a6e99f7 | ||
|
|
2e647be565 | ||
|
|
863123ac92 | ||
|
|
434620dea0 | ||
|
|
212d7d24ef | ||
|
|
61cf416df4 | ||
|
|
ff23f6b015 | ||
|
|
d59d60647c | ||
|
|
cf088d00ff | ||
|
|
dd5a10d0e2 | ||
|
|
0da39aa397 |
@@ -13,6 +13,5 @@ indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# 2 space indentation
|
||||
[*.yaml, *.yml]
|
||||
indent_style = space
|
||||
[*.{yaml,.yml}]
|
||||
indent_size = 2
|
||||
|
||||
@@ -2,6 +2,7 @@ language: php
|
||||
php:
|
||||
- '7.1'
|
||||
- '7.2'
|
||||
- '7.3'
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
|
||||
309
CHANGELOG.md
309
CHANGELOG.md
@@ -1,67 +1,62 @@
|
||||
# v1.6.0-rc.3
|
||||
## 02/18/2019
|
||||
# v1.6.4
|
||||
## 04/15/2019
|
||||
|
||||
1. [](#new)
|
||||
* Implemented `Grav\Framework\Psr7` classes as `Nyholm/psr7` decorators
|
||||
* Renamed `blueprints/user/accounts.yaml` to `blueprints/user/users.yaml`
|
||||
* Moved FlexUser index into `user-data://flex/indexes/users.yaml` [#2378](https://github.com/getgrav/grav/issues/2378)
|
||||
* Added a new `cache-clear` scheduled job to go along with `cache-purge`
|
||||
1. [](#improved)
|
||||
* More code cleanup
|
||||
* Fixed `FlexUser` caching
|
||||
* 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
|
||||
1. [](#bugfix)
|
||||
* Fixed validation for select field type with selectize
|
||||
* Fixed validation for boolean toggles
|
||||
* Fixed `Flex[class]::getType()` to return the same value in every class
|
||||
* Fixed `FlexIndex` keys being lost when `FlexCollection` gets loaded
|
||||
* Fixed missing `form_nonce` for JS when using `FlexForm`
|
||||
* Fixed slow loading of `FlexUser` objects on `$grav['users']->find()` and `load()` calls
|
||||
* 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.0-rc.2
|
||||
## 02/07/2019
|
||||
# v1.6.3
|
||||
## 04/12/2019
|
||||
|
||||
1. [](#new)
|
||||
* New experimental **FlexObjects** powered `Users` for increased performance and capability (**disabled** by default)
|
||||
* New `$grav['users']` service to allow custom user classes implementing `UserInterface`
|
||||
* Added index file support for Flex Objects
|
||||
* Added `LogViewer` helper class and CLI command: `bin/grav logviewer`
|
||||
1. [](#improved)
|
||||
* Improved error detection for broken Flex Objects
|
||||
* 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
|
||||
* Renamed `FlexAuthorizeInterface::authorize()` to `isAuthorized()`
|
||||
* Added `Blueprint::addDynamicHandler()` method to allow custom dynamic handlers, for example `custom-options@: getCustomOptions`
|
||||
1. [](#bugfix)
|
||||
* Fixed non-namespaced exceptions in scheduler
|
||||
* Fixed trailing slash redirect in multlang environment [#2350](https://github.com/getgrav/grav/issues/2350)
|
||||
* Fixed Flex from indexing hidden folders/files as objects
|
||||
* Regression: `$session->getFlashObject('files-upload')` did not work with Form 3.0
|
||||
* 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.0-rc.1
|
||||
## 01/30/2019
|
||||
# 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 `$page->forms()` call, added `$page->addForms()`
|
||||
* Made `FormFlashFile` more robust against deleted files
|
||||
* Updated languages from crowdin
|
||||
* Fixed a bug in `FormFlashFile::moveTo()` not deleting the old file
|
||||
* Fixed `FlexMediaTrait::getMedia()` trying to include uploaded but already moved media
|
||||
* Fixed `ImageMedium` constructor warning when file does not exist
|
||||
* Fixed bad host header in PSR-7 (if using `php -S localhost:8000 system/router.php`)
|
||||
|
||||
# v1.6.0-beta.8
|
||||
## 01/25/2019
|
||||
* 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`
|
||||
@@ -73,25 +68,8 @@
|
||||
* 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
|
||||
1. [](#improved)
|
||||
* Added method argument `Data::filter($missingValuesAsNull)`, defaulting to `false`
|
||||
* Improved `Grav\Common\User` class; added `$user->update()` method
|
||||
* Added trim support for text input fields `validate: trim: true`
|
||||
1. [](#bugfix)
|
||||
* Fixed environment getting port added [#2284](https://github.com/getgrav/grav/issues/2284)
|
||||
* Fixed `FlexForm::updateObject()` to update array values when they are empty in the form
|
||||
* 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
|
||||
|
||||
# v1.6.0-beta.7
|
||||
## 12/14/2018
|
||||
|
||||
1. [](#new)
|
||||
* Updated Symfony Components to 4.2
|
||||
* 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)
|
||||
@@ -102,46 +80,64 @@
|
||||
* 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
|
||||
* Grav 1.6: Flex: Added support for custom object index classes (API compatibility break)
|
||||
1. [](#improved)
|
||||
* Improved `Grav\Framework\File\Formatter` classes to have abstract parent class and some useful methods
|
||||
* Grav 1.6: Improved Flex storage classes
|
||||
* Grav 1.6: Improved `Grav\Framework\File` classes to use better type hints and the new `Filesystem` class
|
||||
1. [](#bugfix)
|
||||
* 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
|
||||
* Grav 1.6: Fixed `FlexObject::update()` call with partial object update
|
||||
* Fixed `YamlFormatter::decode()` when calling `init_set()` with integer
|
||||
* Fixed session throwing error in CLI if initialized
|
||||
|
||||
# v1.6.0-beta.6
|
||||
## 11/12/2018
|
||||
|
||||
1. [](#new)
|
||||
* Added `$grav->setup()` to simplify CLI and custom access points
|
||||
* Grav 1.6: Added `CsvFormatter` and `CsvFile` classes
|
||||
* 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`
|
||||
* Grav 1.6: Allow custom Flex form views
|
||||
1. [](#bugfix)
|
||||
* 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
|
||||
|
||||
# v1.6.0-beta.5
|
||||
## 11/05/2018
|
||||
|
||||
1. [](#new)
|
||||
* 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
|
||||
1. [](#improved)
|
||||
* Updated `Grav` container object to implement PSR-11 `ContainerInterface`
|
||||
* Updated Grav `Processor` classes to implement PSR-15 `MiddlewareInterface`
|
||||
* Make `Data` class to extend `JsonSerializable`
|
||||
@@ -150,67 +146,68 @@
|
||||
* 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
|
||||
* Grav 1.6: Merged Grav 1.5.4 fixes in
|
||||
|
||||
# v1.6.0-beta.4
|
||||
## 10/24/2018
|
||||
|
||||
1. [](#new)
|
||||
* 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)
|
||||
* Added apcu autoloader optimization
|
||||
* Additional helper methods in `Language`, `Languages`, and `LanguageCodes` classes
|
||||
1. [](#bugfix)
|
||||
* Use login provider User avatar if set
|
||||
* Fixed `Folder::doDelete($folder, false)` removing symlink when it should not
|
||||
|
||||
# v1.6.0-beta.3
|
||||
## 10/15/2018
|
||||
|
||||
1. [](#improved)
|
||||
* Call `onFatalException` event also on internal PHP errors
|
||||
* Built-in PHP Webserver: log requests before handling them
|
||||
1. [](#bugfix)
|
||||
* Grav 1.6: Scheduler Fallback for never runs and Windows support [#2202](https://github.com/getgrav/grav/pull/2202)
|
||||
|
||||
# v1.6.0-beta.2
|
||||
## 10/09/2018
|
||||
|
||||
1. [](#new)
|
||||
* Grav 1.6: Added Flex support for custom media tasks
|
||||
1. [](#improved)
|
||||
* 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)
|
||||
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)
|
||||
* Grav 1.6: Regression: Fixed asset manager methods with default legacy attributes
|
||||
|
||||
# v1.6.0-beta.1
|
||||
## 10/01/2018
|
||||
# v1.5.10
|
||||
## 03/21/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.5
|
||||
* Updated Doctrine Cache to 1.8
|
||||
* Updated Symfony Components to 4.1
|
||||
* Added a new Deferred Twig extension to allow adding content to Twig blocks after render
|
||||
* 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
|
||||
* 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)
|
||||
* Doctrine filecache is now namespaced with prefix to support purging
|
||||
* Register all page types into `blueprint://pages` stream
|
||||
* 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
|
||||
## 02/07/2019
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#  Grav
|
||||
|
||||
[](https://github.com/phpstan/phpstan)
|
||||
[](https://insight.sensiolabs.com/projects/cfd20465-d0f8-4a0a-8444-467f5b5f16ad)
|
||||
[](https://chat.getgrav.org)
|
||||
[](https://travis-ci.org/getgrav/grav) [](#backers) [](#sponsors)
|
||||
@@ -105,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
|
||||
* Learn about the [Grav CLI](https://learn.getgrav.org/cli-console/grav-cli)
|
||||
* Review examples in the [Grav Cookbook](https://learn.getgrav.org/cookbook)
|
||||
* More [Awesome Grav Stuff](https://github.com/getgrav/awesome-grav)
|
||||
|
||||
# Backers
|
||||
Support Grav with a monthly donation to help us continue development. [[Become a backer](https://opencollective.com/grav#backer)]
|
||||
|
||||
2
bin/grav
2
bin/grav
@@ -40,7 +40,7 @@ $app->addCommands(array(
|
||||
new \Grav\Console\Cli\ComposerCommand(),
|
||||
new \Grav\Console\Cli\SandboxCommand(),
|
||||
new \Grav\Console\Cli\CleanCommand(),
|
||||
new \Grav\Console\Cli\CacheCommand(),
|
||||
new \Grav\Console\Cli\ClearCacheCommand(),
|
||||
new \Grav\Console\Cli\BackupCommand(),
|
||||
new \Grav\Console\Cli\NewProjectCommand(),
|
||||
new \Grav\Console\Cli\SchedulerCommand(),
|
||||
|
||||
15
bin/plugin
15
bin/plugin
@@ -58,7 +58,6 @@ $grav['users'];
|
||||
$grav['plugins']->init();
|
||||
$grav['themes']->init();
|
||||
|
||||
|
||||
$app = new Application('Grav Plugins Commands', GRAV_VERSION);
|
||||
$pattern = '([A-Z]\w+Command\.php)';
|
||||
|
||||
@@ -73,12 +72,26 @@ $argv = array_merge([$bin], $argv);
|
||||
|
||||
$input = new ArgvInput($argv);
|
||||
|
||||
/** @var \Grav\Common\Data\Data $plugin */
|
||||
$plugin = $grav['plugins']->get($name);
|
||||
|
||||
$output = new ConsoleOutput();
|
||||
$output->getFormatter()->setStyle('red', new OutputFormatterStyle('red', null, array('bold')));
|
||||
$output->getFormatter()->setStyle('white', new OutputFormatterStyle('white', null, array('bold')));
|
||||
|
||||
if (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 (!$name) {
|
||||
$output->writeln('');
|
||||
$output->writeln('<red>Usage:</red>');
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
"ext-openssl": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-dom": "*",
|
||||
"symfony/polyfill-iconv": "^1.9",
|
||||
"symfony/polyfill-php72": "^1.9",
|
||||
"symfony/polyfill-php73": "^1.9",
|
||||
@@ -53,10 +54,19 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.4",
|
||||
"phpstan/phpstan": "^0.11",
|
||||
"phpstan/phpstan-deprecation-rules": "^0.11.0",
|
||||
"phpunit/php-code-coverage": "~6.0",
|
||||
"fzaninotto/faker": "^1.8",
|
||||
"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": {
|
||||
"apcu-autoloader": true,
|
||||
"platform": {
|
||||
@@ -80,6 +90,9 @@
|
||||
},
|
||||
"scripts": {
|
||||
"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-windows": "vendor\\bin\\codecept run unit"
|
||||
},
|
||||
|
||||
1195
composer.lock
generated
1195
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -30,9 +30,25 @@ div.phpdebugbar {
|
||||
}
|
||||
|
||||
.phpdebugbar .phpdebugbar-widgets-toolbar {
|
||||
border-top: 1px solid #ddd;
|
||||
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] {
|
||||
padding: 0;
|
||||
display: inline;
|
||||
|
||||
@@ -19,22 +19,22 @@ form:
|
||||
|
||||
purge.trigger:
|
||||
type: select
|
||||
label: Backup Storage Purge Trigger
|
||||
label: PLUGIN_ADMIN.BACKUPS_STORAGE_PURGE_TRIGGER
|
||||
size: medium
|
||||
default: space
|
||||
options:
|
||||
space: Maximum Backup Space
|
||||
number: Maximum Number of Backups
|
||||
time: maximum Rention Time
|
||||
time: maximum Retention Time
|
||||
validate:
|
||||
required: true
|
||||
|
||||
purge.max_backups_count:
|
||||
type: number
|
||||
label: Maximum Number of Backups
|
||||
label: PLUGIN_ADMIN.BACKUPS_MAX_COUNT
|
||||
default: 25
|
||||
size: x-small
|
||||
help: "0 is unlimited"
|
||||
help: PLUGIN_ADMIN.BACKUPS_MAX_COUNT
|
||||
validate:
|
||||
min: 0
|
||||
type: number
|
||||
@@ -43,7 +43,7 @@ form:
|
||||
|
||||
purge.max_backups_space:
|
||||
type: number
|
||||
label: Maximum Backups Space
|
||||
label: PLUGIN_ADMIN.BACKUPS_MAX_SPACE
|
||||
append: in GB
|
||||
size: x-small
|
||||
default: 5
|
||||
@@ -55,8 +55,8 @@ form:
|
||||
|
||||
purge.max_backups_time:
|
||||
type: number
|
||||
label: Maximum Rention Time
|
||||
append: in Days
|
||||
label: PLUGIN_ADMIN.BACKUPS_MAX_RETENTION_TIME
|
||||
append: PLUGIN_ADMIN.BACKUPS_MAX_RETENTION_TIME_APPEND
|
||||
size: x-small
|
||||
default: 365
|
||||
validate:
|
||||
@@ -80,35 +80,35 @@ form:
|
||||
fields:
|
||||
.name:
|
||||
type: text
|
||||
label: Name
|
||||
placeholder: 'Clear Backup Name'
|
||||
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: Root Folder
|
||||
help: Can be an absolute path or a stream
|
||||
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: Exclude Paths
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_PATHS
|
||||
rows: 5
|
||||
placeholder: "/backup\r/cache\r/images\r/logs\r/tmp"
|
||||
help: Absolute paths to exclude, one per line
|
||||
help: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_PATHS_HELP
|
||||
.exclude_files:
|
||||
type: textarea
|
||||
label: Exclude Files
|
||||
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: Specfic Files or Folders to exclude, one per line
|
||||
help: PLUGIN_ADMIN.BACKUPS_PROFILE_EXCLUDE_FILES_HELP
|
||||
.schedule:
|
||||
type: toggle
|
||||
label: Enable Scheduled Job
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_SCHEDULE
|
||||
highlight: 1
|
||||
default: 1
|
||||
options:
|
||||
@@ -118,7 +118,7 @@ form:
|
||||
type: bool
|
||||
.schedule_at:
|
||||
type: cron
|
||||
label: Run Scheduled Job
|
||||
label: PLUGIN_ADMIN.BACKUPS_PROFILE_SCHEDULE_AT
|
||||
default: '* 3 * * *'
|
||||
validate:
|
||||
required: true
|
||||
|
||||
@@ -38,37 +38,37 @@ form:
|
||||
message: 'ID must be lowercase with dashes/underscores only and less than 20 characters'
|
||||
.command:
|
||||
type: text
|
||||
label: Command
|
||||
label: PLUGIN_ADMIN.COMMAND
|
||||
placeholder: 'cd ~;ls -lah;'
|
||||
validate:
|
||||
required: true
|
||||
.args:
|
||||
type: text
|
||||
label: Extra Arguments
|
||||
label: PLUGIN_ADMIN.EXTRA_ARGUMENTS
|
||||
.at:
|
||||
type: cron
|
||||
label: Run At
|
||||
help: 'Cron formatted "at" syntax'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_RUNAT
|
||||
help: PLUGIN_ADMIN.SCHEDULER_RUNAT_HELP
|
||||
placeholder: '* * * * *'
|
||||
validate:
|
||||
required: true
|
||||
.output:
|
||||
type: text
|
||||
label: Output File
|
||||
help: 'The path/filename of the output file (from the root of the Grav installation)'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_OUTPUT
|
||||
help: PLUGIN_ADMIN.SCHEDULER_OUTPUT_HELP
|
||||
placeholder: 'logs/ls-cron.out'
|
||||
.output_mode:
|
||||
type: select
|
||||
label: Output Type
|
||||
help: 'Either append to the same file each run, or overwrite the file with each run'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_OUTPUT_TYPE
|
||||
help: PLUGIN_ADMIN.SCHEDULER_OUTPUT_TYPE_HELP
|
||||
default: append
|
||||
options:
|
||||
append: Append
|
||||
overwrite: Overwrite
|
||||
.email:
|
||||
type: text
|
||||
label: Email
|
||||
help: 'Email to send output to. NOTE: requires output file to be set'
|
||||
label: PLUGIN_ADMIN.SCHEDULER_EMAIL
|
||||
help: PLUGIN_ADMIN.SCHEDULER_EMAIL_HELP
|
||||
placeholder: 'notifications@yoursite.com'
|
||||
|
||||
|
||||
|
||||
@@ -323,6 +323,12 @@ form:
|
||||
validate:
|
||||
type: commalist
|
||||
|
||||
languages.default_lang:
|
||||
type: text
|
||||
size: x-small
|
||||
label: PLUGIN_ADMIN.DEFAULT_LANG
|
||||
help: PLUGIN_ADMIN.DEFAULT_LANG_HELP
|
||||
|
||||
languages.include_default_lang:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.INCLUDE_DEFAULT_LANG
|
||||
@@ -1062,6 +1068,17 @@ form:
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
images.seofriendly:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.IMAGES_SEOFRIENDLY
|
||||
help: PLUGIN_ADMIN.IMAGES_SEOFRIENDLY_HELP
|
||||
highlight: 0
|
||||
options:
|
||||
1: PLUGIN_ADMIN.YES
|
||||
0: PLUGIN_ADMIN.NO
|
||||
validate:
|
||||
type: bool
|
||||
|
||||
media.enable_media_timestamp:
|
||||
type: toggle
|
||||
label: PLUGIN_ADMIN.ENABLE_MEDIA_TIMESTAMP
|
||||
|
||||
@@ -107,6 +107,7 @@ form:
|
||||
|
||||
fields:
|
||||
groups:
|
||||
security@: admin.super
|
||||
type: select
|
||||
multiple: true
|
||||
size: large
|
||||
@@ -118,6 +119,7 @@ form:
|
||||
type: commalist
|
||||
|
||||
access:
|
||||
security@: admin.super
|
||||
type: permissions
|
||||
label: PLUGIN_ADMIN.PERMISSIONS
|
||||
ignore_empty: true
|
||||
|
||||
@@ -23,7 +23,7 @@ config:
|
||||
|
||||
menu:
|
||||
list:
|
||||
route: /users
|
||||
title: Users
|
||||
route: '/accounts'
|
||||
title: Accounts
|
||||
icon: fa-users
|
||||
authorize: ['admin.users', 'admin.super']
|
||||
authorize: ['admin.users', 'admin.accounts', 'admin.super']
|
||||
@@ -13,6 +13,7 @@ intl_enabled: true # Special logic for PHP Interna
|
||||
|
||||
languages:
|
||||
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
|
||||
pages_fallback_only: false # Only fallback to find page content through supported languages
|
||||
translations: true # Enable translations by default
|
||||
@@ -53,7 +54,7 @@ pages:
|
||||
special_chars: # List of special characters to automatically convert to entities
|
||||
'>': 'gt'
|
||||
'<': 'lt'
|
||||
types: [html,htm,json,xml,txt,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)
|
||||
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
|
||||
@@ -76,7 +77,7 @@ cache:
|
||||
enabled: true # Set to true to enable caching
|
||||
check:
|
||||
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)
|
||||
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)
|
||||
@@ -133,6 +134,7 @@ images:
|
||||
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
|
||||
auto_fix_orientation: false # Automatically fix the image orientation based on the Exif data
|
||||
seofriendly: false # SEO-friendly processed image names
|
||||
|
||||
media:
|
||||
enable_media_timestamp: false # Enable media timestamps
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
// Some standard defines
|
||||
define('GRAV', true);
|
||||
define('GRAV_VERSION', '1.6.0-rc.3');
|
||||
define('GRAV_TESTING', true);
|
||||
define('GRAV_VERSION', '1.6.4');
|
||||
define('GRAV_TESTING', false);
|
||||
define('DS', '/');
|
||||
|
||||
if (!defined('GRAV_PHP_MIN')) {
|
||||
|
||||
@@ -37,12 +37,6 @@ class Assets extends PropertyObject
|
||||
/** @const Regex to match JavaScript files */
|
||||
const JS_REGEX = '/.\.js$/i';
|
||||
|
||||
/**
|
||||
* @const Regex to match <script> or <style> tag when adding inline style/script. Note that this only supports a
|
||||
* single tag, so the check is greedy to avoid issues in JS.
|
||||
*/
|
||||
const HTML_TAG_REGEX = '#(<([A-Z][A-Z0-9]*)>)+(.*)(<\/\2>)#is';
|
||||
|
||||
protected $assets_dir;
|
||||
protected $assets_url;
|
||||
|
||||
@@ -51,8 +45,10 @@ class Assets extends PropertyObject
|
||||
|
||||
// Config Options
|
||||
protected $css_pipeline;
|
||||
protected $css_pipeline_include_externals;
|
||||
protected $css_pipeline_before_excludes;
|
||||
protected $js_pipeline;
|
||||
protected $js_pipeline_include_externals;
|
||||
protected $js_pipeline_before_excludes;
|
||||
protected $pipeline_options = [];
|
||||
|
||||
@@ -123,7 +119,7 @@ class Assets extends PropertyObject
|
||||
* It automatically detects the asset type (JavaScript, CSS or collection).
|
||||
* You may add more than one asset passing an array as argument.
|
||||
*
|
||||
* @param $asset
|
||||
* @param array|string $asset
|
||||
* @return $this
|
||||
*/
|
||||
public function add($asset)
|
||||
@@ -270,6 +266,21 @@ class Assets extends PropertyObject
|
||||
protected function filterAssets($assets, $key, $value, $sort = false)
|
||||
{
|
||||
$results = array_filter($assets, function($asset) use ($key, $value) {
|
||||
|
||||
if ($key === 'position' && $value === 'pipeline') {
|
||||
|
||||
$type = $asset->getType();
|
||||
|
||||
if ($asset->getRemote() && $this->{$type . '_pipeline_include_externals'} === false) {
|
||||
if ($this->{$type . '_pipeline_before_excludes'}) {
|
||||
$asset->setPosition('after');
|
||||
} else {
|
||||
$asset->setPosition('before');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
if ($asset[$key] === $value) return true;
|
||||
return false;
|
||||
});
|
||||
@@ -298,11 +309,9 @@ class Assets extends PropertyObject
|
||||
$before_output = '';
|
||||
$pipeline_output = '';
|
||||
$after_output = '';
|
||||
$no_pipeline = [];
|
||||
|
||||
$assets = 'assets_' . $type;
|
||||
$pipeline_enabled = $type . '_pipeline';
|
||||
$before_excludes = $type . '_pipeline_before_excludes';
|
||||
$render_pipeline = 'render' . ucfirst($type);
|
||||
|
||||
$group_assets = $this->filterAssets($this->$assets, 'group', $group);
|
||||
@@ -315,22 +324,13 @@ class Assets extends PropertyObject
|
||||
$options = array_merge($this->pipeline_options, ['timestamp' => $this->timestamp]);
|
||||
|
||||
$pipeline = new Pipeline($options);
|
||||
$pipeline_output = $pipeline->$render_pipeline($pipeline_assets, $group, $attributes, $no_pipeline);
|
||||
$pipeline_output = $pipeline->$render_pipeline($pipeline_assets, $group, $attributes);
|
||||
} else {
|
||||
foreach ($pipeline_assets as $asset) {
|
||||
$pipeline_output .= $asset->render();
|
||||
}
|
||||
}
|
||||
|
||||
// Handle stuff that couldn't be pipelined
|
||||
if (!empty($no_pipeline)) {
|
||||
if ($this->{$before_excludes}) {
|
||||
$after_assets = array_merge($after_assets, $no_pipeline);
|
||||
} else {
|
||||
$before_assets = array_merge($before_assets, $no_pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
// Before Pipeline
|
||||
foreach ($before_assets as $asset) {
|
||||
$before_output .= $asset->render();
|
||||
|
||||
@@ -129,6 +129,12 @@ abstract class BaseAsset extends PropertyObject
|
||||
return $this->remote;
|
||||
}
|
||||
|
||||
public function setPosition($position)
|
||||
{
|
||||
$this->position = $position;
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -153,7 +159,6 @@ abstract class BaseAsset extends PropertyObject
|
||||
* Build local links including grav asset shortcodes
|
||||
*
|
||||
* @param string $asset the asset string reference
|
||||
* @param bool $absolute build absolute asset link
|
||||
*
|
||||
* @return string the final link url to the asset
|
||||
*/
|
||||
@@ -175,4 +180,16 @@ abstract class BaseAsset extends PropertyObject
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ class Pipeline extends PropertyObject
|
||||
/** @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;
|
||||
@@ -48,9 +50,6 @@ class Pipeline extends PropertyObject
|
||||
protected $query;
|
||||
protected $asset;
|
||||
|
||||
protected $css_pipeline_include_externals;
|
||||
protected $js_pipeline_include_externals;
|
||||
|
||||
/**
|
||||
* Closure used by the pipeline to fetch assets.
|
||||
*
|
||||
@@ -89,11 +88,10 @@ class Pipeline extends PropertyObject
|
||||
* @param array $assets
|
||||
* @param string $group
|
||||
* @param array $attributes
|
||||
* @param array $no_pipeline
|
||||
*
|
||||
* @return bool|string URL or generated content if available, else false
|
||||
*/
|
||||
public function renderCss($assets, $group, $attributes = [], &$no_pipeline = [])
|
||||
public function renderCss($assets, $group, $attributes = [])
|
||||
{
|
||||
// temporary list of assets to pipeline
|
||||
$inline_group = false;
|
||||
@@ -117,21 +115,13 @@ class Pipeline extends PropertyObject
|
||||
if (file_exists($this->assets_dir . $file)) {
|
||||
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
|
||||
} else {
|
||||
|
||||
foreach ($assets as $id => $asset) {
|
||||
if ($this->css_pipeline_include_externals === false && $asset->getRemote()) {
|
||||
$no_pipeline[$id] = $asset;
|
||||
unset($assets[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
//if nothing found get out of here!
|
||||
if (empty($assets) && empty($no_pipeline)) {
|
||||
if (empty($assets)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Concatenate files
|
||||
$buffer = $this->gatherLinks($assets, self::CSS_ASSET, $no_pipeline);
|
||||
$buffer = $this->gatherLinks($assets, self::CSS_ASSET);
|
||||
|
||||
// Minify if required
|
||||
if ($this->shouldMinify('css')) {
|
||||
@@ -162,11 +152,10 @@ class Pipeline extends PropertyObject
|
||||
* @param array $assets
|
||||
* @param string $group
|
||||
* @param array $attributes
|
||||
* @param array $no_pipeline
|
||||
*
|
||||
* @return bool|string URL or generated content if available, else false
|
||||
*/
|
||||
public function renderJs($assets, $group, $attributes = [], &$no_pipeline = [])
|
||||
public function renderJs($assets, $group, $attributes = [])
|
||||
{
|
||||
// temporary list of assets to pipeline
|
||||
$inline_group = false;
|
||||
@@ -190,21 +179,13 @@ class Pipeline extends PropertyObject
|
||||
if (file_exists($this->assets_dir . $file)) {
|
||||
$buffer = file_get_contents($this->assets_dir . $file) . "\n";
|
||||
} else {
|
||||
|
||||
foreach ($assets as $id => $asset) {
|
||||
if ($this->js_pipeline_include_externals === false && $asset->getRemote()) {
|
||||
$no_pipeline[$id] = $asset;
|
||||
unset($assets[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
//if nothing found get out of here!
|
||||
if (empty($assets) && empty($no_pipeline)) {
|
||||
if (empty($assets)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Concatenate files
|
||||
$buffer = $this->gatherLinks($assets, self::JS_ASSET, $no_pipeline);
|
||||
$buffer = $this->gatherLinks($assets, self::JS_ASSET);
|
||||
|
||||
// Minify if required
|
||||
if ($this->shouldMinify('js')) {
|
||||
@@ -235,7 +216,7 @@ class Pipeline extends PropertyObject
|
||||
*
|
||||
* @param string $file the css source file
|
||||
* @param string $dir , $local relative path to the css file
|
||||
* @param boolean $local is this a local or remote asset
|
||||
* @param bool $local is this a local or remote asset
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -251,13 +232,21 @@ class Pipeline extends PropertyObject
|
||||
$old_url = $matches[2];
|
||||
|
||||
// Ensure link is not rooted to web server, a data URL, or to a remote host
|
||||
if (Utils::startsWith($old_url, '/') || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) {
|
||||
if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url) || Utils::startsWith($old_url, 'data:') || $this->isRemoteLink($old_url)) {
|
||||
return $matches[0];
|
||||
}
|
||||
|
||||
$new_url = ($local ? $this->base_url: '') . ltrim(Utils::normalizePath($dir . '/' . $old_url), '/');
|
||||
// clean leading /
|
||||
$old_url = Utils::normalizePath($dir . '/' . $old_url);
|
||||
if (preg_match(self::FIRST_FORWARDSLASH_REGEX, $old_url)) {
|
||||
$old_url = ltrim($old_url, '/');
|
||||
}
|
||||
|
||||
return str_replace($old_url, $new_url, $matches[0]);
|
||||
$new_url = ($local ? $this->base_url: '') . $old_url;
|
||||
|
||||
$fixed = str_replace($matches[2], $new_url, $matches[0]);
|
||||
|
||||
return $fixed;
|
||||
}, $file);
|
||||
|
||||
return $file;
|
||||
|
||||
@@ -38,11 +38,10 @@ trait AssetUtilsTrait
|
||||
*
|
||||
* @param array $assets
|
||||
* @param bool $css
|
||||
* @param array $no_pipeline
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function gatherLinks(array $assets, $css = true, &$no_pipeline = [])
|
||||
protected function gatherLinks(array $assets, $css = true)
|
||||
{
|
||||
$buffer = '';
|
||||
|
||||
@@ -74,9 +73,6 @@ trait AssetUtilsTrait
|
||||
|
||||
// No file found, skip it...
|
||||
if ($file === false) {
|
||||
if (!$local) { // Assume we couldn't download this file for some reason assume it's not pipeline compatible
|
||||
$no_pipeline[$id] = $asset;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -113,7 +109,7 @@ trait AssetUtilsTrait
|
||||
{
|
||||
$imports = [];
|
||||
|
||||
$file = (string)preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) {
|
||||
$file = (string)preg_replace_callback(self::CSS_IMPORT_REGEX, function ($matches) use (&$imports) {
|
||||
$imports[] = $matches[0];
|
||||
|
||||
return '';
|
||||
|
||||
@@ -14,6 +14,11 @@ 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
|
||||
@@ -77,34 +82,36 @@ trait LegacyAssetsTrait
|
||||
/**
|
||||
* Convenience wrapper for async loading of JavaScript
|
||||
*
|
||||
* @param $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'async']
|
||||
* @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 $asset
|
||||
* @param int $priority
|
||||
* @param bool $pipeline
|
||||
* @param string $group name of the group
|
||||
*
|
||||
* @deprecated Please use dynamic method with ['loading' => 'defer']
|
||||
* @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);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Determines if an asset exists as a collection, CSS or JS reference
|
||||
*
|
||||
* @param $asset
|
||||
* @param string $asset
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -38,7 +38,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Set the array of collections explicitly
|
||||
*
|
||||
* @param $collections
|
||||
* @param array $collections
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -90,7 +90,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Set the whole array of CSS assets
|
||||
*
|
||||
* @param $css
|
||||
* @param array $css
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -104,7 +104,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Set the whole array of JS assets
|
||||
*
|
||||
* @param $js
|
||||
* @param array $js
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -152,7 +152,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Sets the state of CSS Pipeline
|
||||
*
|
||||
* @param boolean $value
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -166,7 +166,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Sets the state of JS Pipeline
|
||||
*
|
||||
* @param boolean $value
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -219,7 +219,7 @@ trait TestingAssetsTrait
|
||||
/**
|
||||
* Explicitly set's a timestamp for assets
|
||||
*
|
||||
* @param $value
|
||||
* @param string|int $value
|
||||
*/
|
||||
public function setTimestamp($value)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ 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
|
||||
@@ -194,7 +195,7 @@ class Backups
|
||||
}
|
||||
|
||||
// Log the backup
|
||||
Grav::instance()['log']->error('Backup Created: ' . $destination);
|
||||
Grav::instance()['log']->notice('Backup Created: ' . $destination);
|
||||
|
||||
// Fire Finished event
|
||||
Grav::instance()->fireEvent('onBackupFinished', new Event(['backup' => $destination]));
|
||||
@@ -202,6 +203,14 @@ class Backups
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ use \Doctrine\Common\Cache as DoctrineCache;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Scheduler\Scheduler;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
|
||||
@@ -21,8 +22,6 @@ use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
* It uses DoctrineCache library and supports a variety of caching mechanisms. Those include:
|
||||
*
|
||||
* APCu
|
||||
* APC
|
||||
* XCache
|
||||
* RedisCache
|
||||
* MemCache
|
||||
* MemCacheD
|
||||
@@ -46,6 +45,11 @@ class Cache extends Getters
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* @var CacheInterface
|
||||
*/
|
||||
protected $simpleCache;
|
||||
|
||||
protected $driver_name;
|
||||
|
||||
protected $driver_setting;
|
||||
@@ -142,6 +146,23 @@ class Cache extends Getters
|
||||
$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
|
||||
*
|
||||
@@ -169,7 +190,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* Public accessor to set the enabled state of the cache
|
||||
*
|
||||
* @param $enabled
|
||||
* @param bool|int $enabled
|
||||
*/
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
@@ -237,40 +258,52 @@ class Cache extends Getters
|
||||
break;
|
||||
|
||||
case 'memcache':
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcache.port', 11211));
|
||||
$driver = new DoctrineCache\MemcacheCache();
|
||||
$driver->setMemcache($memcache);
|
||||
if (extension_loaded('memcache')) {
|
||||
$memcache = new \Memcache();
|
||||
$memcache->connect($this->config->get('system.cache.memcache.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcache.port', 11211));
|
||||
$driver = new DoctrineCache\MemcacheCache();
|
||||
$driver->setMemcache($memcache);
|
||||
} else {
|
||||
throw new \LogicException('Memcache PHP extension has not been installed');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'memcached':
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer($this->config->get('system.cache.memcached.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcached.port', 11211));
|
||||
$driver = new DoctrineCache\MemcachedCache();
|
||||
$driver->setMemcached($memcached);
|
||||
if (extension_loaded('memcached')) {
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer($this->config->get('system.cache.memcached.server', 'localhost'),
|
||||
$this->config->get('system.cache.memcached.port', 11211));
|
||||
$driver = new DoctrineCache\MemcachedCache();
|
||||
$driver->setMemcached($memcached);
|
||||
} else {
|
||||
throw new \LogicException('Memcached PHP extension has not been installed');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'redis':
|
||||
$redis = new \Redis();
|
||||
$socket = $this->config->get('system.cache.redis.socket', false);
|
||||
$password = $this->config->get('system.cache.redis.password', false);
|
||||
if (extension_loaded('redis')) {
|
||||
$redis = new \Redis();
|
||||
$socket = $this->config->get('system.cache.redis.socket', false);
|
||||
$password = $this->config->get('system.cache.redis.password', false);
|
||||
|
||||
if ($socket) {
|
||||
$redis->connect($socket);
|
||||
if ($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 {
|
||||
$redis->connect($this->config->get('system.cache.redis.server', 'localhost'),
|
||||
$this->config->get('system.cache.redis.port', 6379));
|
||||
throw new \LogicException('Redis PHP extension has not been installed');
|
||||
}
|
||||
|
||||
// Authenticate with password if set
|
||||
if ($password && !$redis->auth($password)) {
|
||||
throw new \RedisException('Redis authentication failed');
|
||||
}
|
||||
|
||||
$driver = new DoctrineCache\RedisCache();
|
||||
$driver->setRedis($redis);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -551,7 +584,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* is this driver a volatile driver in that it resides in PHP process memory
|
||||
*
|
||||
* @param $setting
|
||||
* @param string $setting
|
||||
* @return bool
|
||||
*/
|
||||
public function isVolatileDriver($setting)
|
||||
@@ -578,7 +611,7 @@ class Cache extends Getters
|
||||
/**
|
||||
* Static function to call as a scheduled Job to clear Grav cache
|
||||
*
|
||||
* @param $type
|
||||
* @param string $type
|
||||
*/
|
||||
public static function clearJob($type)
|
||||
{
|
||||
|
||||
@@ -109,14 +109,13 @@ class Config extends Data
|
||||
}
|
||||
}
|
||||
|
||||
// Override the media.upload_limit based on PHP values
|
||||
$upload_limit = Utils::getUploadLimit();
|
||||
$this->items['system']['media']['upload_limit'] = $upload_limit > 0 ? $upload_limit : 1024*1024*1024;
|
||||
// Legacy value - Override the media.upload_limit based on PHP values
|
||||
$this->items['system']['media']['upload_limit'] = Utils::getUploadLimit();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @deprecated
|
||||
* @deprecated 1.5 Use Grav::instance()['languages'] instead.
|
||||
*/
|
||||
public function getLanguages()
|
||||
{
|
||||
|
||||
@@ -14,6 +14,22 @@ use Grav\Common\Utils;
|
||||
|
||||
class Languages extends Data
|
||||
{
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $checksum;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $modified;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $timestamp;
|
||||
|
||||
|
||||
public function checksum($checksum = null)
|
||||
{
|
||||
if ($checksum !== null) {
|
||||
|
||||
@@ -25,6 +25,18 @@ class Blueprint extends BlueprintForm
|
||||
/** @var 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;
|
||||
@@ -56,7 +68,60 @@ class Blueprint extends BlueprintForm
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,15 +186,31 @@ class Blueprint extends BlueprintForm
|
||||
*
|
||||
* @param array $data
|
||||
* @param bool $missingValuesAsNull
|
||||
* @param bool $keepEmptyValues
|
||||
* @return array
|
||||
*/
|
||||
public function filter(array $data, bool $missingValuesAsNull = false)
|
||||
public function filter(array $data, bool $missingValuesAsNull = false, bool $keepEmptyValues = false)
|
||||
{
|
||||
$this->initInternals();
|
||||
|
||||
return $this->blueprintSchema->filter($data, $missingValuesAsNull);
|
||||
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.
|
||||
*
|
||||
@@ -142,6 +223,11 @@ class Blueprint extends BlueprintForm
|
||||
return $this->blueprintSchema;
|
||||
}
|
||||
|
||||
public function addDynamicHandler(string $name, callable $callable): void
|
||||
{
|
||||
$this->handlers[$name] = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize validator.
|
||||
*/
|
||||
@@ -158,6 +244,7 @@ class Blueprint extends BlueprintForm
|
||||
|
||||
$this->blueprintSchema->embed('', $this->items);
|
||||
$this->blueprintSchema->init();
|
||||
$this->defaults = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -79,11 +79,51 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
*
|
||||
* @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)
|
||||
public function filter(array $data, $missingValuesAsNull = false, $keepEmptyValues = false)
|
||||
{
|
||||
return $this->filterArray($data, $this->nested, $missingValuesAsNull);
|
||||
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 $rules
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,9 +164,10 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
* @param array $data
|
||||
* @param array $rules
|
||||
* @param bool $missingValuesAsNull
|
||||
* @param bool $keepEmptyValues
|
||||
* @return array
|
||||
*/
|
||||
protected function filterArray(array $data, array $rules, $missingValuesAsNull)
|
||||
protected function filterArray(array $data, array $rules, $missingValuesAsNull, $keepEmptyValues)
|
||||
{
|
||||
$results = [];
|
||||
|
||||
@@ -138,7 +179,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
$rule = \is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
if (empty($rule['validate']['ignore'])) {
|
||||
$results[$key] = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,33 +193,35 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
// Item has been defined in blueprints.
|
||||
if (!empty($rule['validate']['ignore'])) {
|
||||
// Skip any data in the ignored field.
|
||||
unset($results[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$field = Validation::filter($field, $rule);
|
||||
} elseif (\is_array($field) && \is_array($val)) {
|
||||
// Array has been defined in blueprints.
|
||||
$field = $this->filterArray($field, $val, $missingValuesAsNull);
|
||||
$field = $this->filterArray($field, $val, $missingValuesAsNull, $keepEmptyValues);
|
||||
|
||||
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
|
||||
$field = null;
|
||||
// Skip any extra data.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $field && (!\is_array($field) || !empty($field))) {
|
||||
if ($keepEmptyValues || (null !== $field && (!\is_array($field) || !empty($field)))) {
|
||||
$results[$key] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
return $results ?: null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array|null $data
|
||||
* @param array $toggles
|
||||
* @param array $nested
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
protected function processFormRecursive(array $data, array $toggles, array $nested)
|
||||
protected function processFormRecursive(?array $data, array $toggles, array $nested)
|
||||
{
|
||||
foreach ($nested as $key => $value) {
|
||||
if ($key === '') {
|
||||
@@ -190,11 +233,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
}
|
||||
if (is_array($value)) {
|
||||
// Recursively fetch the items.
|
||||
$array = $this->processFormRecursive($data[$key] ?? [], $toggles[$key] ?? [], $value);
|
||||
|
||||
if (!empty($array)) {
|
||||
$data[$key] = $array;
|
||||
}
|
||||
$data[$key] = $this->processFormRecursive($data[$key] ?? null, $toggles[$key] ?? [], $value);
|
||||
} else {
|
||||
$field = $this->get($value);
|
||||
// Do not add the field if:
|
||||
|
||||
@@ -26,7 +26,7 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
/** @var array */
|
||||
protected $items;
|
||||
|
||||
/** @var Blueprints */
|
||||
/** @var Blueprint */
|
||||
protected $blueprints;
|
||||
|
||||
/** @var File */
|
||||
@@ -197,13 +197,15 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $missingValuesAsNull
|
||||
* @return $this
|
||||
* Filter all items by using blueprints.
|
||||
*/
|
||||
public function filter(bool $missingValuesAsNull = false)
|
||||
public function filter()
|
||||
{
|
||||
$this->items = $this->blueprints()->filter($this->items, $missingValuesAsNull);
|
||||
$args = func_get_args();
|
||||
$missingValuesAsNull = (bool)(array_shift($args) ?: false);
|
||||
$keepEmptyValues = (bool)(array_shift($args) ?: false);
|
||||
|
||||
$this->items = $this->blueprints()->filter($this->items, $missingValuesAsNull, $keepEmptyValues);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class Validation
|
||||
/**
|
||||
* Validate value against a blueprint field definition.
|
||||
*
|
||||
* @param $value
|
||||
* @param mixed $value
|
||||
* @param array $field
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
use DebugBar\DataCollector\ConfigCollector;
|
||||
use DebugBar\DataCollector\DataCollectorInterface;
|
||||
use DebugBar\DataCollector\ExceptionsCollector;
|
||||
use DebugBar\DataCollector\MemoryCollector;
|
||||
use DebugBar\DataCollector\MessagesCollector;
|
||||
@@ -20,6 +21,9 @@ use DebugBar\DebugBar;
|
||||
use DebugBar\JavascriptRenderer;
|
||||
use DebugBar\StandardDebugBar;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Processors\ProcessorInterface;
|
||||
use Twig\Template;
|
||||
use Twig\TemplateWrapper;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
@@ -43,7 +47,7 @@ class Debugger
|
||||
/** @var array */
|
||||
protected $timers = [];
|
||||
|
||||
/** @var string[] $deprecations */
|
||||
/** @var array $deprecations */
|
||||
protected $deprecations = [];
|
||||
|
||||
/** @var callable */
|
||||
@@ -95,7 +99,7 @@ class Debugger
|
||||
$this->config = $this->grav['config'];
|
||||
|
||||
// Enable/disable debugger based on configuration.
|
||||
$this->enabled = $this->config->get('system.debugger.enabled');
|
||||
$this->enabled = (bool)$this->config->get('system.debugger.enabled');
|
||||
|
||||
if ($this->enabled()) {
|
||||
$this->initialized = true;
|
||||
@@ -120,12 +124,12 @@ class Debugger
|
||||
*
|
||||
* @param bool $state If null, the method returns the enabled value. If set, the method sets the enabled state
|
||||
*
|
||||
* @return null
|
||||
* @return bool
|
||||
*/
|
||||
public function enabled($state = null)
|
||||
{
|
||||
if ($state !== null) {
|
||||
$this->enabled = $state;
|
||||
$this->enabled = (bool)$state;
|
||||
}
|
||||
|
||||
return $this->enabled;
|
||||
@@ -181,7 +185,7 @@ class Debugger
|
||||
/**
|
||||
* Adds a data collector
|
||||
*
|
||||
* @param $collector
|
||||
* @param DataCollectorInterface $collector
|
||||
*
|
||||
* @return $this
|
||||
* @throws \DebugBar\DebugBarException
|
||||
@@ -196,9 +200,9 @@ class Debugger
|
||||
/**
|
||||
* Returns a data collector
|
||||
*
|
||||
* @param $collector
|
||||
* @param DataCollectorInterface $collector
|
||||
*
|
||||
* @return \DebugBar\DataCollector\DataCollectorInterface
|
||||
* @return DataCollectorInterface
|
||||
* @throws \DebugBar\DebugBarException
|
||||
*/
|
||||
public function getCollector($collector)
|
||||
@@ -297,7 +301,7 @@ class Debugger
|
||||
/**
|
||||
* Dump variables into the Messages tab of the Debug Bar
|
||||
*
|
||||
* @param $message
|
||||
* @param mixed $message
|
||||
* @param string $label
|
||||
* @param bool $isString
|
||||
*
|
||||
@@ -355,57 +359,183 @@ class Debugger
|
||||
return true;
|
||||
}
|
||||
|
||||
$backtrace = debug_backtrace(false);
|
||||
// Figure out error scope from the error.
|
||||
$scope = 'unknown';
|
||||
if (stripos($errstr, 'grav') !== false) {
|
||||
$scope = 'grav';
|
||||
} elseif (strpos($errfile, '/twig/') !== false) {
|
||||
$scope = 'twig';
|
||||
} elseif (stripos($errfile, '/yaml/') !== false) {
|
||||
$scope = 'yaml';
|
||||
} elseif (strpos($errfile, '/vendor/') !== false) {
|
||||
$scope = 'vendor';
|
||||
}
|
||||
|
||||
// Clean up backtrace to make it more useful.
|
||||
$backtrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT);
|
||||
|
||||
// Skip current call.
|
||||
array_shift($backtrace);
|
||||
|
||||
// Find yaml file where the error happened.
|
||||
if ($scope === 'yaml') {
|
||||
foreach ($backtrace as $current) {
|
||||
if (isset($current['args'])) {
|
||||
foreach ($current['args'] as $arg) {
|
||||
if ($arg instanceof \SplFileInfo) {
|
||||
$arg = $arg->getPathname();
|
||||
}
|
||||
if (\is_string($arg) && preg_match('/.+\.(yaml|md)$/i', $arg)) {
|
||||
$errfile = $arg;
|
||||
$errline = 0;
|
||||
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter arguments.
|
||||
$cut = 0;
|
||||
$previous = null;
|
||||
foreach ($backtrace as $i => &$current) {
|
||||
if (isset($current['args'])) {
|
||||
$args = [];
|
||||
foreach ($current['args'] as $arg) {
|
||||
if (\is_string($arg)) {
|
||||
$arg = "'" . $arg . "'";
|
||||
if (mb_strlen($arg) > 100) {
|
||||
$arg = 'string';
|
||||
}
|
||||
} elseif (\is_bool($arg)) {
|
||||
$arg = $arg ? 'true' : 'false';
|
||||
} elseif (\is_scalar($arg)) {
|
||||
$arg = $arg;
|
||||
} elseif (\is_object($arg)) {
|
||||
$arg = get_class($arg) . ' $object';
|
||||
} elseif (\is_array($arg)) {
|
||||
$arg = '$array';
|
||||
} else {
|
||||
$arg = '$object';
|
||||
}
|
||||
|
||||
$args[] = $arg;
|
||||
}
|
||||
$current['args'] = $args;
|
||||
}
|
||||
|
||||
$object = $current['object'] ?? null;
|
||||
unset($current['object']);
|
||||
|
||||
$reflection = null;
|
||||
if ($object instanceof TemplateWrapper) {
|
||||
$reflection = new \ReflectionObject($object);
|
||||
$property = $reflection->getProperty('template');
|
||||
$property->setAccessible(true);
|
||||
$object = $property->getValue($object);
|
||||
}
|
||||
|
||||
if ($object instanceof Template) {
|
||||
$file = $current['file'] ?? null;
|
||||
|
||||
if (preg_match('`(Template.php|TemplateWrapper.php)$`', $file)) {
|
||||
$current = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
$debugInfo = $object->getDebugInfo();
|
||||
|
||||
$line = 1;
|
||||
if (!$reflection) {
|
||||
foreach ($debugInfo as $codeLine => $templateLine) {
|
||||
if ($codeLine <= $current['line']) {
|
||||
$line = $templateLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$src = $object->getSourceContext();
|
||||
//$code = preg_split('/\r\n|\r|\n/', $src->getCode());
|
||||
//$current['twig']['twig'] = trim($code[$line - 1]);
|
||||
$current['twig']['file'] = $src->getPath();
|
||||
$current['twig']['line'] = $line;
|
||||
|
||||
$prevFile = $previous['file'] ?? null;
|
||||
if ($prevFile && $file === $prevFile) {
|
||||
$prevLine = $previous['line'];
|
||||
|
||||
$line = 1;
|
||||
foreach ($debugInfo as $codeLine => $templateLine) {
|
||||
if ($codeLine <= $prevLine) {
|
||||
$line = $templateLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//$previous['twig']['twig'] = trim($code[$line - 1]);
|
||||
$previous['twig']['file'] = $src->getPath();
|
||||
$previous['twig']['line'] = $line;
|
||||
}
|
||||
|
||||
$cut = $i;
|
||||
} elseif ($object instanceof ProcessorInterface) {
|
||||
$cut = $cut ?: $i;
|
||||
break;
|
||||
}
|
||||
|
||||
$previous = &$backtrace[$i];
|
||||
}
|
||||
unset($current);
|
||||
|
||||
if ($cut) {
|
||||
$backtrace = array_slice($backtrace, 0, $cut + 1);
|
||||
}
|
||||
$backtrace = array_values(array_filter($backtrace));
|
||||
|
||||
// Skip vendor libraries and the method where error was triggered.
|
||||
while ($current = array_shift($backtrace)) {
|
||||
if (isset($current['file']) && strpos($current['file'], 'vendor') !== false) {
|
||||
foreach ($backtrace as $i => $current) {
|
||||
if (!isset($current['file'])) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($current['file'], '/vendor/') !== false) {
|
||||
$cut = $i + 1;
|
||||
continue;
|
||||
}
|
||||
if (isset($current['function']) && ($current['function'] === 'user_error' || $current['function'] === 'trigger_error')) {
|
||||
$current = array_shift($backtrace);
|
||||
$cut = $i + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Add back last call.
|
||||
array_unshift($backtrace, $current);
|
||||
|
||||
// Filter arguments.
|
||||
foreach ($backtrace as &$current) {
|
||||
if (isset($current['args'])) {
|
||||
$args = [];
|
||||
foreach ($current['args'] as $arg) {
|
||||
if (\is_string($arg)) {
|
||||
$args[] = "'" . $arg . "'";
|
||||
} elseif (\is_bool($arg)) {
|
||||
$args[] = $arg ? 'true' : 'false';
|
||||
} elseif (\is_scalar($arg)) {
|
||||
$args[] = $arg;
|
||||
} elseif (\is_object($arg)) {
|
||||
$args[] = get_class($arg) . ' $object';
|
||||
} elseif (\is_array($arg)) {
|
||||
$args[] = '$array';
|
||||
} else {
|
||||
$args[] = '$object';
|
||||
}
|
||||
}
|
||||
$current['args'] = $args;
|
||||
}
|
||||
if ($cut) {
|
||||
$backtrace = array_slice($backtrace, $cut);
|
||||
}
|
||||
unset($current);
|
||||
$backtrace = array_values(array_filter($backtrace));
|
||||
|
||||
$this->deprecations[] = [
|
||||
$current = reset($backtrace);
|
||||
|
||||
// If the issue happened inside twig file, change the file and line to match that file.
|
||||
$file = $current['twig']['file'] ?? '';
|
||||
if ($file) {
|
||||
$errfile = $file;
|
||||
$errline = $current['twig']['line'] ?? 0;
|
||||
}
|
||||
|
||||
$deprecation = [
|
||||
'scope' => $scope,
|
||||
'message' => $errstr,
|
||||
'file' => $errfile,
|
||||
'line' => $errline,
|
||||
'trace' => $backtrace,
|
||||
'count' => 1
|
||||
];
|
||||
|
||||
$this->deprecations[] = $deprecation;
|
||||
|
||||
// Do not pass forward.
|
||||
return true;
|
||||
}
|
||||
@@ -430,38 +560,37 @@ class Debugger
|
||||
|
||||
protected function getDepracatedMessage($deprecated)
|
||||
{
|
||||
$scope = 'unknown';
|
||||
if (stripos($deprecated['message'], 'grav') !== false) {
|
||||
$scope = 'grav';
|
||||
} elseif (!isset($deprecated['file'])) {
|
||||
$scope = 'unknown';
|
||||
} elseif (stripos($deprecated['file'], 'twig') !== false) {
|
||||
$scope = 'twig';
|
||||
} elseif (stripos($deprecated['file'], 'yaml') !== false) {
|
||||
$scope = 'yaml';
|
||||
} elseif (stripos($deprecated['file'], 'vendor') !== false) {
|
||||
$scope = 'vendor';
|
||||
}
|
||||
$scope = $deprecated['scope'];
|
||||
|
||||
$trace = [];
|
||||
foreach ($deprecated['trace'] as $current) {
|
||||
$class = $current['class'] ?? '';
|
||||
$type = $current['type'] ?? '';
|
||||
$function = $this->getFunction($current);
|
||||
if (isset($current['file'])) {
|
||||
$current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']);
|
||||
if (isset($deprecated['trace'])) {
|
||||
foreach ($deprecated['trace'] as $current) {
|
||||
$class = $current['class'] ?? '';
|
||||
$type = $current['type'] ?? '';
|
||||
$function = $this->getFunction($current);
|
||||
if (isset($current['file'])) {
|
||||
$current['file'] = str_replace(GRAV_ROOT . '/', '', $current['file']);
|
||||
}
|
||||
|
||||
unset($current['class'], $current['type'], $current['function'], $current['args']);
|
||||
|
||||
if (isset($current['twig'])) {
|
||||
$trace[] = $current['twig'];
|
||||
} else {
|
||||
$trace[] = ['call' => $class . $type . $function] + $current;
|
||||
}
|
||||
}
|
||||
|
||||
unset($current['class'], $current['type'], $current['function'], $current['args']);
|
||||
|
||||
$trace[] = ['call' => $class . $type . $function] + $current;
|
||||
}
|
||||
|
||||
$array = [
|
||||
'message' => $deprecated['message'],
|
||||
'file' => $deprecated['file'],
|
||||
'line' => $deprecated['line'],
|
||||
'trace' => $trace
|
||||
];
|
||||
|
||||
return [
|
||||
[
|
||||
'message' => $deprecated['message'],
|
||||
'trace' => $trace
|
||||
],
|
||||
array_filter($array),
|
||||
$scope
|
||||
];
|
||||
}
|
||||
@@ -472,6 +601,6 @@ class Debugger
|
||||
return '';
|
||||
}
|
||||
|
||||
return $trace['function'] . '(' . implode(', ', $trace['args']) . ')';
|
||||
return $trace['function'] . '(' . implode(', ', $trace['args'] ?? []) . ')';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ class Errors
|
||||
} catch (\Exception $e) {
|
||||
echo $e;
|
||||
}
|
||||
}, 'log');
|
||||
});
|
||||
}
|
||||
|
||||
$whoops->register();
|
||||
|
||||
@@ -59,7 +59,7 @@ class SimplePageHandler extends Handler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $resource
|
||||
* @param string $resource
|
||||
*
|
||||
* @return string
|
||||
* @throws \RuntimeException
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Grav\Common\Filesystem;
|
||||
|
||||
use Grav\Common\Utils;
|
||||
|
||||
abstract class Archiver
|
||||
{
|
||||
protected $options = [
|
||||
@@ -35,6 +37,11 @@ abstract class Archiver
|
||||
|
||||
public function setOptions($options)
|
||||
{
|
||||
// Set infinite PHP execution time if possible.
|
||||
if (function_exists('set_time_limit') && !Utils::isFunctionDisabled('set_time_limit')) {
|
||||
set_time_limit(0);
|
||||
}
|
||||
|
||||
$this->options = $options + $this->options;
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ abstract class Folder
|
||||
/**
|
||||
* Recursively find the last modified time under given path by file.
|
||||
*
|
||||
* @param string $path
|
||||
* @param string $path
|
||||
* @param string $extensions which files to search for specifically
|
||||
*
|
||||
* @return int
|
||||
@@ -87,7 +87,7 @@ abstract class Folder
|
||||
/**
|
||||
* Recursively md5 hash all files in a path
|
||||
*
|
||||
* @param $path
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
public static function hashAllFiles($path)
|
||||
@@ -418,23 +418,27 @@ abstract class Folder
|
||||
*/
|
||||
public static function create($folder)
|
||||
{
|
||||
if (is_dir($folder)) {
|
||||
// Silence error for open_basedir; should fail in mkdir instead.
|
||||
if (@is_dir($folder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$success = @mkdir($folder, 0777, true);
|
||||
|
||||
if (!$success) {
|
||||
$error = error_get_last();
|
||||
throw new \RuntimeException($error['message']);
|
||||
// Take yet another look, make sure that the folder doesn't exist.
|
||||
clearstatcache(true, $folder);
|
||||
if (!@is_dir($folder)) {
|
||||
throw new \RuntimeException(sprintf('Unable to create directory: %s', $folder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive copy of one directory to another
|
||||
*
|
||||
* @param $src
|
||||
* @param $dest
|
||||
* @param string $src
|
||||
* @param string $dest
|
||||
*
|
||||
* @return bool
|
||||
* @throws \RuntimeException
|
||||
@@ -450,7 +454,7 @@ abstract class Folder
|
||||
|
||||
// If the destination directory does not exist create it
|
||||
if (!is_dir($dest)) {
|
||||
static::mkdir($dest);
|
||||
static::create($dest);
|
||||
}
|
||||
|
||||
// Open the source directory to read in files
|
||||
|
||||
@@ -39,7 +39,7 @@ class RecursiveDirectoryFilterIterator extends \RecursiveFilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
/** @var $file \SplFileInfo */
|
||||
/** @var \SplFileInfo $file */
|
||||
$file = $this->current();
|
||||
$filename = $file->getFilename();
|
||||
$relative_filename = str_replace($this::$root . '/', '', $file->getPathname());
|
||||
@@ -57,7 +57,11 @@ class RecursiveDirectoryFilterIterator extends \RecursiveFilterIterator
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getChildren() {
|
||||
return new self($this->getInnerIterator()->getChildren(), $this::$root, $this::$ignore_folders, $this::$ignore_files);
|
||||
public function getChildren()
|
||||
{
|
||||
/** @var RecursiveDirectoryFilterIterator $iterator */
|
||||
$iterator = $this->getInnerIterator();
|
||||
|
||||
return new self($iterator->getChildren(), $this::$root, $this::$ignore_folders, $this::$ignore_files);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class RecursiveFolderFilterIterator extends \RecursiveFilterIterator
|
||||
*/
|
||||
public function accept()
|
||||
{
|
||||
/** @var $current \SplFileInfo */
|
||||
/** @var \SplFileInfo $current */
|
||||
$current = $this->current();
|
||||
|
||||
return $current->isDir() && !in_array($current->getFilename(), $this::$ignore_folders, true);
|
||||
|
||||
@@ -18,7 +18,7 @@ class ZipArchiver extends Archiver
|
||||
$archive = $zip->open($this->archive_file);
|
||||
|
||||
if ($archive === true) {
|
||||
Folder::mkdir($destination);
|
||||
Folder::create($destination);
|
||||
|
||||
if (!$zip->extractTo($destination)) {
|
||||
throw new \RuntimeException('ZipArchiver: ZIP failed to extract ' . $this->archive_file . ' to ' . $destination);
|
||||
|
||||
@@ -60,7 +60,7 @@ class FormFlash extends \Grav\Framework\Form\FormFlash
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @deprecated 1.6 For backwards compatibility only, do not use.
|
||||
* @deprecated 1.6 For backwards compatibility only, do not use
|
||||
*/
|
||||
public function getLegacyFiles(): array
|
||||
{
|
||||
@@ -85,7 +85,7 @@ class FormFlash extends \Grav\Framework\Form\FormFlash
|
||||
* @param string $filename
|
||||
* @param array $upload
|
||||
* @return bool
|
||||
* @deprecated 1.6 For backwards compatibility only, do not use.
|
||||
* @deprecated 1.6 For backwards compatibility only, do not use
|
||||
*/
|
||||
public function uploadFile(string $field, string $filename, array $upload): bool
|
||||
{
|
||||
@@ -114,7 +114,7 @@ class FormFlash extends \Grav\Framework\Form\FormFlash
|
||||
* @param array $upload
|
||||
* @param array $crop
|
||||
* @return bool
|
||||
* @deprecated 1.6 For backwards compatibility only, do not use.
|
||||
* @deprecated 1.6 For backwards compatibility only, do not use
|
||||
*/
|
||||
public function cropFile(string $field, string $filename, array $upload, array $crop): bool
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ class CachedCollection extends Iterator {
|
||||
|
||||
public function __construct($items)
|
||||
{
|
||||
parent::__construct();
|
||||
// local cache to speed things up
|
||||
if (!isset(self::$cache[get_called_class() . __METHOD__])) {
|
||||
self::$cache[get_called_class() . __METHOD__] = $items;
|
||||
|
||||
@@ -13,6 +13,9 @@ use Grav\Common\Data\Data;
|
||||
|
||||
class Package {
|
||||
|
||||
/**
|
||||
* @var Data
|
||||
*/
|
||||
protected $data;
|
||||
|
||||
public function __construct(Data $package, $type = null)
|
||||
@@ -24,6 +27,9 @@ class Package {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Data
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
@@ -54,6 +60,9 @@ class Package {
|
||||
return $this->data->toJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->data->toArray();
|
||||
|
||||
@@ -37,7 +37,7 @@ class GPM extends Iterator
|
||||
|
||||
/**
|
||||
* Internal cache
|
||||
* @var
|
||||
* @var array
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
@@ -49,11 +49,13 @@ class GPM extends Iterator
|
||||
|
||||
/**
|
||||
* Creates a new GPM instance with Local and Remote packages available
|
||||
* @param boolean $refresh Applies to Remote Packages only and forces a refetch of data
|
||||
* @param bool $refresh Applies to Remote Packages only and forces a refetch of data
|
||||
* @param callable $callback Either a function or callback in array notation
|
||||
*/
|
||||
public function __construct($refresh = false, $callback = null)
|
||||
{
|
||||
parent::__construct();
|
||||
$this->cache = [];
|
||||
$this->installed = new Local\Packages();
|
||||
try {
|
||||
$this->repository = new Remote\Packages($refresh, $callback);
|
||||
@@ -95,7 +97,7 @@ class GPM extends Iterator
|
||||
|
||||
/**
|
||||
* Returns the amount of locally installed packages
|
||||
* @return integer Amount of installed packages
|
||||
* @return int Amount of installed packages
|
||||
*/
|
||||
public function countInstalled()
|
||||
{
|
||||
@@ -145,7 +147,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Checks if a Plugin is installed
|
||||
* @param string $slug The slug of the Plugin
|
||||
* @return boolean True if the Plugin has been installed. False otherwise
|
||||
* @return bool True if the Plugin has been installed. False otherwise
|
||||
*/
|
||||
public function isPluginInstalled($slug)
|
||||
{
|
||||
@@ -179,7 +181,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Checks if a Theme is installed
|
||||
* @param string $slug The slug of the Theme
|
||||
* @return boolean True if the Theme has been installed. False otherwise
|
||||
* @return bool True if the Theme has been installed. False otherwise
|
||||
*/
|
||||
public function isThemeInstalled($slug)
|
||||
{
|
||||
@@ -188,7 +190,7 @@ class GPM extends Iterator
|
||||
|
||||
/**
|
||||
* Returns the amount of updates available
|
||||
* @return integer Amount of available updates
|
||||
* @return int Amount of available updates
|
||||
*/
|
||||
public function countUpdates()
|
||||
{
|
||||
@@ -250,7 +252,7 @@ class GPM extends Iterator
|
||||
$repository[$slug]->available = $remote_version;
|
||||
$repository[$slug]->version = $local_version;
|
||||
$repository[$slug]->type = $repository[$slug]->release_type;
|
||||
$items[$slug] = $repository[$slug]->toArray();
|
||||
$items[$slug] = $repository[$slug];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,7 +264,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Get the latest release of a package from the GPM
|
||||
*
|
||||
* @param $package_name
|
||||
* @param string $package_name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
@@ -285,7 +287,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Check if a Plugin or Theme is updatable
|
||||
* @param string $slug The slug of the package
|
||||
* @return boolean True if updatable. False otherwise or if not found
|
||||
* @return bool True if updatable. False otherwise or if not found
|
||||
*/
|
||||
public function isUpdatable($slug)
|
||||
{
|
||||
@@ -295,7 +297,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Checks if a Plugin is updatable
|
||||
* @param string $plugin The slug of the Plugin
|
||||
* @return boolean True if the Plugin is updatable. False otherwise
|
||||
* @return bool True if the Plugin is updatable. False otherwise
|
||||
*/
|
||||
public function isPluginUpdatable($plugin)
|
||||
{
|
||||
@@ -329,7 +331,7 @@ class GPM extends Iterator
|
||||
$repository[$slug]->available = $remote_version;
|
||||
$repository[$slug]->version = $local_version;
|
||||
$repository[$slug]->type = $repository[$slug]->release_type;
|
||||
$items[$slug] = $repository[$slug]->toArray();
|
||||
$items[$slug] = $repository[$slug];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +343,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Checks if a Theme is Updatable
|
||||
* @param string $theme The slug of the Theme
|
||||
* @return boolean True if the Theme is updatable. False otherwise
|
||||
* @return bool True if the Theme is updatable. False otherwise
|
||||
*/
|
||||
public function isThemeUpdatable($theme)
|
||||
{
|
||||
@@ -351,7 +353,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Get the release type of a package (stable / testing)
|
||||
*
|
||||
* @param $package_name
|
||||
* @param string $package_name
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
@@ -374,9 +376,9 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Returns true if the package latest release is stable
|
||||
*
|
||||
* @param $package_name
|
||||
* @param string $package_name
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isStableRelease($package_name)
|
||||
{
|
||||
@@ -386,9 +388,9 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Returns true if the package latest release is testing
|
||||
*
|
||||
* @param $package_name
|
||||
* @param string $package_name
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isTestingRelease($package_name)
|
||||
{
|
||||
@@ -503,8 +505,8 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Download the zip package via the URL
|
||||
*
|
||||
* @param $package_file
|
||||
* @param $tmp
|
||||
* @param string $package_file
|
||||
* @param string $tmp
|
||||
* @return null|string
|
||||
*/
|
||||
public static function downloadPackage($package_file, $tmp)
|
||||
@@ -519,7 +521,7 @@ class GPM extends Iterator
|
||||
$output = Response::get($package_file, []);
|
||||
|
||||
if ($output) {
|
||||
Folder::mkdir($tmp);
|
||||
Folder::create($tmp);
|
||||
file_put_contents($tmp . DS . $filename, $output);
|
||||
return $tmp . DS . $filename;
|
||||
}
|
||||
@@ -530,8 +532,8 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Copy the local zip package to tmp
|
||||
*
|
||||
* @param $package_file
|
||||
* @param $tmp
|
||||
* @param string $package_file
|
||||
* @param string $tmp
|
||||
* @return null|string
|
||||
*/
|
||||
public static function copyPackage($package_file, $tmp)
|
||||
@@ -540,7 +542,7 @@ class GPM extends Iterator
|
||||
|
||||
if (file_exists($package_file)) {
|
||||
$filename = basename($package_file);
|
||||
Folder::mkdir($tmp);
|
||||
Folder::create($tmp);
|
||||
copy(realpath($package_file), $tmp . DS . $filename);
|
||||
return $tmp . DS . $filename;
|
||||
}
|
||||
@@ -551,7 +553,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Try to guess the package type from the source files
|
||||
*
|
||||
* @param $source
|
||||
* @param string $source
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function getPackageType($source)
|
||||
@@ -596,7 +598,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Try to guess the package name from the source files
|
||||
*
|
||||
* @param $source
|
||||
* @param string $source
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function getPackageName($source)
|
||||
@@ -616,7 +618,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Find/Parse the blueprint file
|
||||
*
|
||||
* @param $source
|
||||
* @param string $source
|
||||
* @return array|bool
|
||||
*/
|
||||
public static function getBlueprints($source)
|
||||
@@ -636,8 +638,8 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Get the install path for a name and a particular type of package
|
||||
*
|
||||
* @param $type
|
||||
* @param $name
|
||||
* @param string $type
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
public static function getInstallPath($type, $name)
|
||||
@@ -742,8 +744,8 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Get the required version of a dependency of a package
|
||||
*
|
||||
* @param $package_slug
|
||||
* @param $dependency_slug
|
||||
* @param string $package_slug
|
||||
* @param string $dependency_slug
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -806,7 +808,7 @@ class GPM extends Iterator
|
||||
/**
|
||||
* Check the passed packages list can be updated
|
||||
*
|
||||
* @param $packages_names_list
|
||||
* @param array $packages_names_list
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@@ -1098,7 +1100,7 @@ class GPM extends Iterator
|
||||
*
|
||||
* Example: returns true for $version: '~2.0'
|
||||
*
|
||||
* @param $version
|
||||
* @param string $version
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -1112,7 +1114,7 @@ class GPM extends Iterator
|
||||
*
|
||||
* Example: returns true for $version: '>=2.0'
|
||||
*
|
||||
* @param $version
|
||||
* @param string $version
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -40,12 +40,12 @@ class Installer
|
||||
protected static $target;
|
||||
|
||||
/**
|
||||
* @var integer Error Code
|
||||
* @var int Error Code
|
||||
*/
|
||||
protected static $error = 0;
|
||||
|
||||
/**
|
||||
* @var integer Zip Error Code
|
||||
* @var int Zip Error Code
|
||||
*/
|
||||
protected static $error_zip = 0;
|
||||
|
||||
@@ -75,7 +75,7 @@ class Installer
|
||||
* @param string $destination The local path to the Grav Instance
|
||||
* @param array $options Options to use for installing. ie, ['install_path' => 'user/themes/antimatter']
|
||||
* @param string $extracted The local path to the extacted ZIP package
|
||||
* @param bool $keepExtracted True if you want to keep the original files
|
||||
* @param bool $keepExtracted True if you want to keep the original files
|
||||
* @return bool True if everything went fine, False otherwise.
|
||||
*/
|
||||
public static function install($zip, $destination, $options = [], $extracted = null, $keepExtracted = false)
|
||||
@@ -166,8 +166,8 @@ class Installer
|
||||
/**
|
||||
* Unzip a file to somewhere
|
||||
*
|
||||
* @param $zip_file
|
||||
* @param $destination
|
||||
* @param string $zip_file
|
||||
* @param string $destination
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function unZip($zip_file, $destination)
|
||||
@@ -176,7 +176,7 @@ class Installer
|
||||
$archive = $zip->open($zip_file);
|
||||
|
||||
if ($archive === true) {
|
||||
Folder::mkdir($destination);
|
||||
Folder::create($destination);
|
||||
|
||||
$unzip = $zip->extractTo($destination);
|
||||
|
||||
@@ -253,8 +253,8 @@ class Installer
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $source_path
|
||||
* @param $install_path
|
||||
* @param string $source_path
|
||||
* @param string $install_path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -270,8 +270,8 @@ class Installer
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $source_path
|
||||
* @param $install_path
|
||||
* @param string $source_path
|
||||
* @param string $install_path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -287,10 +287,10 @@ class Installer
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $source_path
|
||||
* @param $install_path
|
||||
* @param $ignores
|
||||
* @param $keep_source
|
||||
* @param string $source_path
|
||||
* @param string $install_path
|
||||
* @param array $ignores
|
||||
* @param bool $keep_source
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -332,7 +332,7 @@ class Installer
|
||||
* @param string $path The slug of the package(s)
|
||||
* @param array $options Options to use for uninstalling
|
||||
*
|
||||
* @return boolean True if everything went fine, False otherwise.
|
||||
* @return bool True if everything went fine, False otherwise.
|
||||
*/
|
||||
public static function uninstall($path, $options = [])
|
||||
{
|
||||
@@ -374,7 +374,7 @@ class Installer
|
||||
* @param string $destination The directory to run validations at
|
||||
* @param array $exclude An array of constants to exclude from the validation
|
||||
*
|
||||
* @return boolean True if validation passed. False otherwise
|
||||
* @return bool True if validation passed. False otherwise
|
||||
*/
|
||||
public static function isValidDestination($destination, $exclude = [])
|
||||
{
|
||||
@@ -403,7 +403,7 @@ class Installer
|
||||
*
|
||||
* @param string $target The local path to the Grav Instance
|
||||
*
|
||||
* @return boolean True if is a Grav Instance. False otherwise
|
||||
* @return bool True if is a Grav Instance. False otherwise
|
||||
*/
|
||||
public static function isGravInstance($target)
|
||||
{
|
||||
@@ -523,7 +523,7 @@ class Installer
|
||||
|
||||
/**
|
||||
* Returns the last error code of the occurred error
|
||||
* @return integer The code of the last error
|
||||
* @return int|string The code of the last error
|
||||
*/
|
||||
public static function lastErrorCode()
|
||||
{
|
||||
|
||||
@@ -33,10 +33,10 @@ class Licenses
|
||||
/**
|
||||
* Returns the license for a Premium package
|
||||
*
|
||||
* @param $slug
|
||||
* @param $license
|
||||
* @param string $slug
|
||||
* @param string $license
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function set($slug, $license)
|
||||
{
|
||||
@@ -67,7 +67,7 @@ class Licenses
|
||||
/**
|
||||
* Returns the license for a Premium package
|
||||
*
|
||||
* @param $slug
|
||||
* @param string $slug
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
@@ -89,7 +89,7 @@ class Licenses
|
||||
/**
|
||||
* Validates the License format
|
||||
*
|
||||
* @param $license
|
||||
* @param string $license
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,7 @@ abstract class AbstractPackageCollection extends BaseCollection
|
||||
{
|
||||
public function __construct($items)
|
||||
{
|
||||
parent::__construct();
|
||||
foreach ($items as $name => $data) {
|
||||
$data->set('slug', $name);
|
||||
$this->items[$name] = new Package($data, $this->type);
|
||||
|
||||
@@ -23,11 +23,11 @@ class Package extends BasePackage
|
||||
|
||||
$this->settings = $package->toArray();
|
||||
|
||||
$html_description = \Parsedown::instance()->line($this->description);
|
||||
$this->data->set('slug', $package->slug);
|
||||
$html_description = \Parsedown::instance()->line($this->__get('description'));
|
||||
$this->data->set('slug', $package->__get('slug'));
|
||||
$this->data->set('description_html', $html_description);
|
||||
$this->data->set('description_plain', strip_tags($html_description));
|
||||
$this->data->set('symlink', is_link(USER_DIR . $package_type . DS . $this->slug));
|
||||
$this->data->set('symlink', is_link(USER_DIR . $package_type . DS . $this->__get('slug')));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,7 @@ class AbstractPackageCollection extends BaseCollection
|
||||
|
||||
/**
|
||||
* The lifetime to store the entry in seconds
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
private $lifetime = 86400;
|
||||
|
||||
@@ -41,6 +41,7 @@ class AbstractPackageCollection extends BaseCollection
|
||||
*/
|
||||
public function __construct($repository = null, $refresh = false, $callback = null)
|
||||
{
|
||||
parent::__construct();
|
||||
if ($repository === null) {
|
||||
throw new \RuntimeException("A repository is required to indicate the origin of the remote collection");
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ class GravCore extends AbstractPackageCollection
|
||||
|
||||
$diffLog = [];
|
||||
foreach ((array)$this->data['changelog'] as $version => $changelog) {
|
||||
preg_match("/[\w-\.]+/", $version, $cleanVersion);
|
||||
preg_match("/[\w\-\.]+/", $version, $cleanVersion);
|
||||
|
||||
if (!$cleanVersion || version_compare($diff, $cleanVersion[0], '>=')) {
|
||||
continue;
|
||||
|
||||
@@ -12,11 +12,16 @@ namespace Grav\Common\GPM\Remote;
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\GPM\Common\Package as BasePackage;
|
||||
|
||||
class Package extends BasePackage
|
||||
class Package extends BasePackage implements \JsonSerializable
|
||||
{
|
||||
public function __construct($package, $package_type = null)
|
||||
{
|
||||
$data = new Data($package);
|
||||
parent::__construct($data, $package_type);
|
||||
}
|
||||
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ class Response
|
||||
/**
|
||||
* Checks if cURL is available
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function isCurlAvailable()
|
||||
{
|
||||
@@ -193,7 +193,7 @@ class Response
|
||||
/**
|
||||
* Checks if the remote fopen request is enabled in PHP
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public static function isFopenAvailable()
|
||||
{
|
||||
@@ -203,7 +203,7 @@ class Response
|
||||
/**
|
||||
* Is this a remote file or not
|
||||
*
|
||||
* @param $file
|
||||
* @param string $file
|
||||
* @return bool
|
||||
*/
|
||||
public static function isRemote($file)
|
||||
@@ -302,8 +302,9 @@ class Response
|
||||
|
||||
if ($content === false) {
|
||||
$code = null;
|
||||
// Function file_get_contents() creates local variable $http_response_header, check it
|
||||
if (isset($http_response_header)) {
|
||||
$code = explode(' ', $http_response_header[0])[1];
|
||||
$code = explode(' ', $http_response_header[0] ?? '')[1] ?? null;
|
||||
}
|
||||
|
||||
switch ($code) {
|
||||
@@ -358,9 +359,9 @@ class Response
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $ch
|
||||
* @param $options
|
||||
* @param $callback
|
||||
* @param resource $ch
|
||||
* @param array $options
|
||||
* @param bool $callback
|
||||
*
|
||||
* @return bool|mixed
|
||||
*/
|
||||
|
||||
@@ -11,14 +11,14 @@ namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Config\Setup;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Medium\ImageMedium;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Processors\AssetsProcessor;
|
||||
use Grav\Common\Processors\BackupsProcessor;
|
||||
use Grav\Common\Processors\ConfigurationProcessor;
|
||||
use Grav\Common\Processors\DebuggerAssetsProcessor;
|
||||
use Grav\Common\Processors\DebuggerInitProcessor;
|
||||
use Grav\Common\Processors\DebuggerProcessor;
|
||||
use Grav\Common\Processors\ErrorsProcessor;
|
||||
use Grav\Common\Processors\InitializeProcessor;
|
||||
use Grav\Common\Processors\LoggerProcessor;
|
||||
@@ -38,6 +38,11 @@ use Psr\Http\Message\ServerRequestInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
|
||||
/**
|
||||
* Grav container is the heart of Grav.
|
||||
*
|
||||
* @package Grav\Common
|
||||
*/
|
||||
class Grav extends Container
|
||||
{
|
||||
/**
|
||||
@@ -55,28 +60,24 @@ class Grav extends Container
|
||||
* to the dependency injection container.
|
||||
*/
|
||||
protected static $diMap = [
|
||||
'Grav\Common\Service\AccountsServiceProvider',
|
||||
'Grav\Common\Service\AssetsServiceProvider',
|
||||
'Grav\Common\Service\BackupsServiceProvider',
|
||||
'Grav\Common\Service\ConfigServiceProvider',
|
||||
'Grav\Common\Service\ErrorServiceProvider',
|
||||
'Grav\Common\Service\FilesystemServiceProvider',
|
||||
'Grav\Common\Service\InflectorServiceProvider',
|
||||
'Grav\Common\Service\LoggerServiceProvider',
|
||||
'Grav\Common\Service\OutputServiceProvider',
|
||||
'Grav\Common\Service\PageServiceProvider',
|
||||
'Grav\Common\Service\PagesServiceProvider',
|
||||
'Grav\Common\Service\RequestServiceProvider',
|
||||
'Grav\Common\Service\SessionServiceProvider',
|
||||
'Grav\Common\Service\SetupServiceProvider',
|
||||
'Grav\Common\Service\StreamsServiceProvider',
|
||||
'Grav\Common\Service\TaskServiceProvider',
|
||||
'Grav\Common\Service\UserServiceProvider',
|
||||
'browser' => 'Grav\Common\Browser',
|
||||
'cache' => 'Grav\Common\Cache',
|
||||
'events' => 'RocketTheme\Toolbox\Event\EventDispatcher',
|
||||
'exif' => 'Grav\Common\Helpers\Exif',
|
||||
'filesystem' => 'Grav\Framework\Filesystem\Filesystem',
|
||||
'inflector' => 'Grav\Common\Inflector',
|
||||
'language' => 'Grav\Common\Language\Language',
|
||||
'pages' => 'Grav\Common\Page\Pages',
|
||||
'plugins' => 'Grav\Common\Plugins',
|
||||
'scheduler' => 'Grav\Common\Scheduler\Scheduler',
|
||||
'taxonomy' => 'Grav\Common\Taxonomy',
|
||||
@@ -92,7 +93,7 @@ class Grav extends Container
|
||||
'configurationProcessor',
|
||||
'loggerProcessor',
|
||||
'errorsProcessor',
|
||||
'debuggerInitProcessor',
|
||||
'debuggerProcessor',
|
||||
'initializeProcessor',
|
||||
'pluginsProcessor',
|
||||
'themesProcessor',
|
||||
@@ -194,8 +195,8 @@ class Grav extends Container
|
||||
'errorsProcessor' => function () {
|
||||
return new ErrorsProcessor($this);
|
||||
},
|
||||
'debuggerInitProcessor' => function () {
|
||||
return new DebuggerInitProcessor($this);
|
||||
'debuggerProcessor' => function () {
|
||||
return new DebuggerProcessor($this);
|
||||
},
|
||||
'initializeProcessor' => function () {
|
||||
return new InitializeProcessor($this);
|
||||
@@ -335,7 +336,7 @@ class Grav extends Container
|
||||
public function header(ResponseInterface $response = null)
|
||||
{
|
||||
if (null === $response) {
|
||||
/** @var Page $page */
|
||||
/** @var PageInterface $page */
|
||||
$page = $this['page'];
|
||||
$response = new Response($page->httpResponseCode(), $page->httpHeaders(), '');
|
||||
}
|
||||
@@ -470,7 +471,7 @@ class Grav extends Container
|
||||
};
|
||||
|
||||
$container->measureTime('_services', 'Services', function () use ($container) {
|
||||
$container->registerServices($container);
|
||||
$container->registerServices();
|
||||
});
|
||||
|
||||
return $container;
|
||||
@@ -500,7 +501,7 @@ class Grav extends Container
|
||||
/**
|
||||
* This attempts to find media, other files, and download them
|
||||
*
|
||||
* @param $path
|
||||
* @param string $path
|
||||
*/
|
||||
public function fallbackUrl($path)
|
||||
{
|
||||
@@ -526,7 +527,7 @@ class Grav extends Container
|
||||
|
||||
$path_parts = pathinfo($path);
|
||||
|
||||
/** @var Page $page */
|
||||
/** @var PageInterface $page */
|
||||
$page = $this['pages']->dispatch($path_parts['dirname'], true);
|
||||
|
||||
if ($page) {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
/**
|
||||
* @deprecated 1.4 Use Grav::instance() instead
|
||||
* @deprecated 1.4 Use Grav::instance() instead.
|
||||
*/
|
||||
trait GravTrait
|
||||
{
|
||||
@@ -18,15 +18,16 @@ trait GravTrait
|
||||
|
||||
/**
|
||||
* @return Grav
|
||||
* @deprecated 1.4 Use Grav::instance() instead.
|
||||
*/
|
||||
public static function getGrav()
|
||||
{
|
||||
user_error(__TRAIT__ . ' is deprecated since Grav 1.4, use Grav::instance() instead', E_USER_DEPRECATED);
|
||||
|
||||
if (!self::$grav) {
|
||||
self::$grav = Grav::instance();
|
||||
}
|
||||
|
||||
user_error(__TRAIT__ . ' is deprecated since Grav 1.4, use Grav::instance() instead', E_USER_DEPRECATED);
|
||||
|
||||
return self::$grav;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ class Base32
|
||||
/**
|
||||
* Encode in Base32
|
||||
*
|
||||
* @param $bytes
|
||||
* @param string $bytes
|
||||
* @return string
|
||||
*/
|
||||
public static function encode($bytes)
|
||||
@@ -69,7 +69,7 @@ class Base32
|
||||
/**
|
||||
* Decode in Base32
|
||||
*
|
||||
* @param $base32
|
||||
* @param string $base32
|
||||
* @return string
|
||||
*/
|
||||
public static function decode($base32)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
namespace Grav\Common\Helpers;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Utils;
|
||||
@@ -23,10 +23,10 @@ class Excerpts
|
||||
* Process Grav image media URL from HTML tag
|
||||
*
|
||||
* @param string $html HTML tag e.g. `<img src="image.jpg" />`
|
||||
* @param Page $page The current page object
|
||||
* @param PageInterface $page The current page object
|
||||
* @return string Returns final HTML string
|
||||
*/
|
||||
public static function processImageHtml($html, Page $page)
|
||||
public static function processImageHtml($html, PageInterface $page)
|
||||
{
|
||||
$excerpt = static::getExcerptFromHtml($html, 'img');
|
||||
|
||||
@@ -80,7 +80,7 @@ class Excerpts
|
||||
/**
|
||||
* Rebuild HTML tag from an excerpt array
|
||||
*
|
||||
* @param $excerpt
|
||||
* @param array $excerpt
|
||||
* @return string
|
||||
*/
|
||||
public static function getHtmlFromExcerpt($excerpt)
|
||||
@@ -111,12 +111,12 @@ class Excerpts
|
||||
/**
|
||||
* Process a Link excerpt
|
||||
*
|
||||
* @param $excerpt
|
||||
* @param Page $page
|
||||
* @param array $excerpt
|
||||
* @param PageInterface $page
|
||||
* @param string $type
|
||||
* @return mixed
|
||||
*/
|
||||
public static function processLinkExcerpt($excerpt, Page $page, $type = 'link')
|
||||
public static function processLinkExcerpt($excerpt, PageInterface $page, $type = 'link')
|
||||
{
|
||||
$url = htmlspecialchars_decode(rawurldecode($excerpt['element']['attributes']['href']));
|
||||
|
||||
@@ -192,10 +192,10 @@ class Excerpts
|
||||
* Process an image excerpt
|
||||
*
|
||||
* @param array $excerpt
|
||||
* @param Page $page
|
||||
* @return mixed
|
||||
* @param PageInterface $page
|
||||
* @return array
|
||||
*/
|
||||
public static function processImageExcerpt(array $excerpt, Page $page)
|
||||
public static function processImageExcerpt(array $excerpt, PageInterface $page)
|
||||
{
|
||||
$url = htmlspecialchars_decode(urldecode($excerpt['element']['attributes']['src']));
|
||||
$url_parts = static::parseUrl($url);
|
||||
@@ -206,13 +206,15 @@ class Excerpts
|
||||
if (!empty($url_parts['stream'])) {
|
||||
$filename = $url_parts['scheme'] . '://' . ($url_parts['path'] ?? '');
|
||||
|
||||
$media = $page->media();
|
||||
$media = $page->getMedia();
|
||||
|
||||
} else {
|
||||
$grav = Grav::instance();
|
||||
|
||||
// File is also local if scheme is http(s) and host matches.
|
||||
$local_file = isset($url_parts['path'])
|
||||
&& (empty($url_parts['scheme']) || in_array($url_parts['scheme'], ['http', 'https'], true))
|
||||
&& (empty($url_parts['host']) || $url_parts['host'] === Grav::instance()['uri']->host());
|
||||
&& (empty($url_parts['host']) || $url_parts['host'] === $grav['uri']->host());
|
||||
|
||||
if ($local_file) {
|
||||
$filename = basename($url_parts['path']);
|
||||
@@ -221,18 +223,18 @@ class Excerpts
|
||||
// Get the local path to page media if possible.
|
||||
if ($folder === $page->url(false, false, false)) {
|
||||
// Get the media objects for this page.
|
||||
$media = $page->media();
|
||||
$media = $page->getMedia();
|
||||
} else {
|
||||
// see if this is an external page to this one
|
||||
$base_url = rtrim(Grav::instance()['base_url_relative'] . Grav::instance()['pages']->base(), '/');
|
||||
$base_url = rtrim($grav['base_url_relative'] . $grav['pages']->base(), '/');
|
||||
$page_route = '/' . ltrim(str_replace($base_url, '', $folder), '/');
|
||||
|
||||
/** @var Page $ext_page */
|
||||
$ext_page = Grav::instance()['pages']->dispatch($page_route, true);
|
||||
/** @var PageInterface $ext_page */
|
||||
$ext_page = $grav['pages']->dispatch($page_route, true);
|
||||
if ($ext_page) {
|
||||
$media = $ext_page->media();
|
||||
$media = $ext_page->getMedia();
|
||||
} else {
|
||||
Grav::instance()->fireEvent('onMediaLocate', new Event(['route' => $page_route, 'media' => &$media]));
|
||||
$grav->fireEvent('onMediaLocate', new Event(['route' => $page_route, 'media' => &$media]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,9 +268,9 @@ class Excerpts
|
||||
/**
|
||||
* Process media actions
|
||||
*
|
||||
* @param $medium
|
||||
* @param $url
|
||||
* @return mixed
|
||||
* @param Medium $medium
|
||||
* @param string|array $url
|
||||
* @return Medium
|
||||
*/
|
||||
public static function processMediaActions($medium, $url)
|
||||
{
|
||||
@@ -353,6 +355,10 @@ class Excerpts
|
||||
return $url_parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return bool|string
|
||||
*/
|
||||
protected static function resolveStream($url)
|
||||
{
|
||||
/** @var UniformResourceLocator $locator */
|
||||
|
||||
@@ -16,7 +16,7 @@ class LogViewer
|
||||
/**
|
||||
* Get the objects of a tailed file
|
||||
*
|
||||
* @param $filepath
|
||||
* @param string $filepath
|
||||
* @param int $lines
|
||||
* @param bool $desc
|
||||
* @return array
|
||||
@@ -37,7 +37,7 @@ class LogViewer
|
||||
/**
|
||||
* Optimized way to get just the last few entries of a log file
|
||||
*
|
||||
* @param $filepath
|
||||
* @param string $filepath
|
||||
* @param int $lines
|
||||
* @return bool|string
|
||||
*/
|
||||
@@ -82,7 +82,7 @@ class LogViewer
|
||||
/**
|
||||
* Helper class to get level color
|
||||
*
|
||||
* @param $level
|
||||
* @param string $level
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function levelColor($level)
|
||||
@@ -103,7 +103,7 @@ class LogViewer
|
||||
/**
|
||||
* Parse a monolog row into array bits
|
||||
*
|
||||
* @param $line
|
||||
* @param string $line
|
||||
* @return array
|
||||
*/
|
||||
public function parse($line)
|
||||
@@ -136,8 +136,8 @@ class LogViewer
|
||||
/**
|
||||
* Parse text of trace into an array of lines
|
||||
*
|
||||
* @param $trace
|
||||
* @param $rows
|
||||
* @param string $trace
|
||||
* @param int $rows
|
||||
* @return array
|
||||
*/
|
||||
public static function parseTrace($trace, $rows = 10)
|
||||
|
||||
@@ -31,7 +31,7 @@ class Truncator {
|
||||
/**
|
||||
* Safely truncates HTML by a given number of words.
|
||||
* @param string $html Input HTML.
|
||||
* @param integer $limit Limit to how many words we preserve.
|
||||
* @param int $limit Limit to how many words we preserve.
|
||||
* @param string $ellipsis String to use as ellipsis (if any).
|
||||
* @return string Safe truncated HTML.
|
||||
*/
|
||||
@@ -41,13 +41,12 @@ class Truncator {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$dom = self::htmlToDomDocument($html);
|
||||
|
||||
// Grab the body of our DOM.
|
||||
$body = $dom->getElementsByTagName('body')->item(0);
|
||||
$doc = self::htmlToDomDocument($html);
|
||||
$container = $doc->getElementsByTagName('div')->item(0);
|
||||
$container = $container->parentNode->removeChild($container);
|
||||
|
||||
// Iterate over words.
|
||||
$words = new DOMWordsIterator($body);
|
||||
$words = new DOMWordsIterator($container);
|
||||
$truncated = false;
|
||||
foreach ($words as $word) {
|
||||
|
||||
@@ -66,7 +65,7 @@ class Truncator {
|
||||
$words[$offset][1] + strlen($words[$offset][0])
|
||||
);
|
||||
|
||||
self::removeProceedingNodes($curNode, $body);
|
||||
self::removeProceedingNodes($curNode, $container);
|
||||
|
||||
if (!empty($ellipsis)) {
|
||||
self::insertEllipsis($curNode, $ellipsis);
|
||||
@@ -81,7 +80,7 @@ class Truncator {
|
||||
|
||||
// Return original HTML if not truncated.
|
||||
if ($truncated) {
|
||||
return self::innerHTML($body);
|
||||
$html = self::getCleanedHtml($doc, $container);
|
||||
}
|
||||
|
||||
return $html;
|
||||
@@ -90,7 +89,7 @@ class Truncator {
|
||||
/**
|
||||
* Safely truncates HTML by a given number of letters.
|
||||
* @param string $html Input HTML.
|
||||
* @param integer $limit Limit to how many letters we preserve.
|
||||
* @param int $limit Limit to how many letters we preserve.
|
||||
* @param string $ellipsis String to use as ellipsis (if any).
|
||||
* @return string Safe truncated HTML.
|
||||
*/
|
||||
@@ -100,13 +99,12 @@ class Truncator {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$dom = self::htmlToDomDocument($html);
|
||||
|
||||
// Grab the body of our DOM.
|
||||
$body = $dom->getElementsByTagName('body')->item(0);
|
||||
$doc = self::htmlToDomDocument($html);
|
||||
$container = $doc->getElementsByTagName('div')->item(0);
|
||||
$container = $container->parentNode->removeChild($container);
|
||||
|
||||
// Iterate over letters.
|
||||
$letters = new DOMLettersIterator($body);
|
||||
$letters = new DOMLettersIterator($container);
|
||||
$truncated = false;
|
||||
foreach ($letters as $letter) {
|
||||
|
||||
@@ -115,7 +113,7 @@ class Truncator {
|
||||
|
||||
$currentText = $letters->currentTextPosition();
|
||||
$currentText[0]->nodeValue = mb_substr($currentText[0]->nodeValue, 0, $currentText[1] + 1);
|
||||
self::removeProceedingNodes($currentText[0], $body);
|
||||
self::removeProceedingNodes($currentText[0], $container);
|
||||
|
||||
if (!empty($ellipsis)) {
|
||||
self::insertEllipsis($currentText[0], $ellipsis);
|
||||
@@ -129,7 +127,7 @@ class Truncator {
|
||||
|
||||
// Return original HTML if not truncated.
|
||||
if ($truncated) {
|
||||
return self::innerHTML($body);
|
||||
$html = self::getCleanedHtml($doc, $container);
|
||||
}
|
||||
|
||||
return $html;
|
||||
@@ -143,7 +141,7 @@ class Truncator {
|
||||
public static function htmlToDomDocument($html)
|
||||
{
|
||||
if (!$html) {
|
||||
$html = '<p></p>';
|
||||
$html = '';
|
||||
}
|
||||
|
||||
// Transform multibyte entities which otherwise display incorrectly.
|
||||
@@ -155,7 +153,7 @@ class Truncator {
|
||||
// Instantiate new DOMDocument object, and then load in UTF-8 HTML.
|
||||
$dom = new DOMDocument();
|
||||
$dom->encoding = 'UTF-8';
|
||||
$dom->loadHTML($html);
|
||||
$dom->loadHTML("<div>$html</div>");
|
||||
|
||||
return $dom;
|
||||
}
|
||||
@@ -188,6 +186,27 @@ class Truncator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean extra code
|
||||
*
|
||||
* @param DOMDocument $doc
|
||||
* @param $container
|
||||
* @return string
|
||||
*/
|
||||
private static function getCleanedHTML(DOMDocument $doc, $container)
|
||||
{
|
||||
while ($doc->firstChild) {
|
||||
$doc->removeChild($doc->firstChild);
|
||||
}
|
||||
|
||||
while ($container->firstChild ) {
|
||||
$doc->appendChild($container->firstChild);
|
||||
}
|
||||
|
||||
$html = trim($doc->saveHTML());
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an ellipsis
|
||||
* @param DOMNode|DOMElement $domNode Element to insert after.
|
||||
@@ -215,21 +234,102 @@ class Truncator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the innerHTML of a particular DOMElement
|
||||
*
|
||||
* @param $element
|
||||
* @return string
|
||||
* @inheritDoc
|
||||
*/
|
||||
private static function innerHTML($element) {
|
||||
$innerHTML = '';
|
||||
$children = $element->childNodes;
|
||||
foreach ($children as $child)
|
||||
{
|
||||
$tmp_dom = new DOMDocument();
|
||||
$tmp_dom->appendChild($tmp_dom->importNode($child, true));
|
||||
$innerHTML.=trim($tmp_dom->saveHTML());
|
||||
public function truncate(
|
||||
$text,
|
||||
$length = 100,
|
||||
$ending = '...',
|
||||
$exact = false,
|
||||
$considerHtml = true
|
||||
) {
|
||||
if ($considerHtml) {
|
||||
// if the plain text is shorter than the maximum length, return the whole text
|
||||
if (strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
|
||||
return $text;
|
||||
}
|
||||
// splits all html-tags to scanable lines
|
||||
preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER);
|
||||
$total_length = strlen($ending);
|
||||
$open_tags = array();
|
||||
$truncate = '';
|
||||
foreach ($lines as $line_matchings) {
|
||||
// if there is any html-tag in this line, handle it and add it (uncounted) to the output
|
||||
if (!empty($line_matchings[1])) {
|
||||
// if it's an "empty element" with or without xhtml-conform closing slash
|
||||
if (preg_match('/^<(\s*.+?\/\s*|\s*(img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param)(\s.+?)?)>$/is', $line_matchings[1])) {
|
||||
// do nothing
|
||||
// if tag is a closing tag
|
||||
} else if (preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $line_matchings[1], $tag_matchings)) {
|
||||
// delete tag from $open_tags list
|
||||
$pos = array_search($tag_matchings[1], $open_tags);
|
||||
if ($pos !== false) {
|
||||
unset($open_tags[$pos]);
|
||||
}
|
||||
// if tag is an opening tag
|
||||
} else if (preg_match('/^<\s*([^\s>!]+).*?>$/s', $line_matchings[1], $tag_matchings)) {
|
||||
// add tag to the beginning of $open_tags list
|
||||
array_unshift($open_tags, strtolower($tag_matchings[1]));
|
||||
}
|
||||
// add html-tag to $truncate'd text
|
||||
$truncate .= $line_matchings[1];
|
||||
}
|
||||
// calculate the length of the plain text part of the line; handle entities as one character
|
||||
$content_length = strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $line_matchings[2]));
|
||||
if ($total_length+$content_length> $length) {
|
||||
// the number of characters which are left
|
||||
$left = $length - $total_length;
|
||||
$entities_length = 0;
|
||||
// search for html entities
|
||||
if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $line_matchings[2], $entities, PREG_OFFSET_CAPTURE)) {
|
||||
// calculate the real length of all entities in the legal range
|
||||
foreach ($entities[0] as $entity) {
|
||||
if ($entity[1]+1-$entities_length <= $left) {
|
||||
$left--;
|
||||
$entities_length += strlen($entity[0]);
|
||||
} else {
|
||||
// no more characters left
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$truncate .= substr($line_matchings[2], 0, $left+$entities_length);
|
||||
// maximum lenght is reached, so get off the loop
|
||||
break;
|
||||
} else {
|
||||
$truncate .= $line_matchings[2];
|
||||
$total_length += $content_length;
|
||||
}
|
||||
// if the maximum length is reached, get off the loop
|
||||
if($total_length>= $length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (strlen($text) <= $length) {
|
||||
return $text;
|
||||
} else {
|
||||
$truncate = substr($text, 0, $length - strlen($ending));
|
||||
}
|
||||
}
|
||||
return $innerHTML;
|
||||
// if the words shouldn't be cut in the middle...
|
||||
if (!$exact) {
|
||||
// ...search the last occurance of a space...
|
||||
$spacepos = strrpos($truncate, ' ');
|
||||
if (isset($spacepos)) {
|
||||
// ...and cut the text in this position
|
||||
$truncate = substr($truncate, 0, $spacepos);
|
||||
}
|
||||
}
|
||||
// add the defined ending to the text
|
||||
$truncate .= $ending;
|
||||
if($considerHtml) {
|
||||
// close all unclosed html-tags
|
||||
foreach ($open_tags as $tag) {
|
||||
$truncate .= '</' . $tag . '>';
|
||||
}
|
||||
}
|
||||
return $truncate;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ class Inflector
|
||||
*
|
||||
* This method converts 13 to 13th, 2 to 2nd ...
|
||||
*
|
||||
* @param integer $number Number to get its ordinal value
|
||||
* @param int $number Number to get its ordinal value
|
||||
*
|
||||
* @return string Ordinal representation of given string.
|
||||
*/
|
||||
|
||||
@@ -63,7 +63,7 @@ class Iterator implements \ArrayAccess, \Iterator, \Countable, \Serializable
|
||||
/**
|
||||
* Remove item from the list.
|
||||
*
|
||||
* @param $key
|
||||
* @param string $key
|
||||
*/
|
||||
public function remove($key)
|
||||
{
|
||||
|
||||
@@ -11,12 +11,16 @@ namespace Grav\Common\Language;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Config\Config;
|
||||
use Negotiation\AcceptLanguage;
|
||||
use Negotiation\LanguageNegotiator;
|
||||
|
||||
class Language
|
||||
{
|
||||
protected $grav;
|
||||
protected $enabled = true;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $languages = [];
|
||||
protected $page_extensions = [];
|
||||
protected $fallback_languages = [];
|
||||
@@ -47,7 +51,13 @@ class Language
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->default = reset($this->languages);
|
||||
$default = $this->config->get('system.languages.default_lang');
|
||||
if (isset($default) && $this->validate($default)) {
|
||||
$this->default = $default;
|
||||
} else {
|
||||
$this->default = reset($this->languages);
|
||||
}
|
||||
|
||||
$this->page_extensions = null;
|
||||
|
||||
if (empty($this->languages)) {
|
||||
@@ -78,7 +88,7 @@ class Language
|
||||
/**
|
||||
* Sets the current supported languages manually
|
||||
*
|
||||
* @param $langs
|
||||
* @param array $langs
|
||||
*/
|
||||
public function setLanguages($langs)
|
||||
{
|
||||
@@ -102,7 +112,7 @@ class Language
|
||||
/**
|
||||
* Gets language, active if set, else default
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
@@ -122,7 +132,7 @@ class Language
|
||||
/**
|
||||
* Sets default language manually
|
||||
*
|
||||
* @param $lang
|
||||
* @param string $lang
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -140,7 +150,7 @@ class Language
|
||||
/**
|
||||
* Gets current active language
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function getActive()
|
||||
{
|
||||
@@ -150,9 +160,9 @@ class Language
|
||||
/**
|
||||
* Sets active language manually
|
||||
*
|
||||
* @param $lang
|
||||
* @param string $lang
|
||||
*
|
||||
* @return bool
|
||||
* @return string|bool
|
||||
*/
|
||||
public function setActive($lang)
|
||||
{
|
||||
@@ -168,9 +178,9 @@ class Language
|
||||
/**
|
||||
* Sets the active language based on the first part of the URL
|
||||
*
|
||||
* @param $uri
|
||||
* @param string $uri
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function setActiveFromUri($uri)
|
||||
{
|
||||
@@ -205,7 +215,7 @@ class Language
|
||||
$negotiator = new LanguageNegotiator();
|
||||
$best_language = $negotiator->getBest($accept, $this->languages);
|
||||
|
||||
if ($best_language) {
|
||||
if ($best_language instanceof AcceptLanguage) {
|
||||
$this->active = $best_language->getType();
|
||||
} else {
|
||||
$this->active = $this->getDefault();
|
||||
@@ -221,7 +231,7 @@ class Language
|
||||
/**
|
||||
* Get's a URL prefix based on configuration
|
||||
*
|
||||
* @param null $lang
|
||||
* @param string|null $lang
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguageURLPrefix($lang = null)
|
||||
@@ -237,7 +247,7 @@ class Language
|
||||
/**
|
||||
* Test to see if language is default and language should be included in the URL
|
||||
*
|
||||
* @param null $lang
|
||||
* @param string|null $lang
|
||||
* @return bool
|
||||
*/
|
||||
public function isIncludeDefaultLanguage($lang = null)
|
||||
@@ -349,7 +359,7 @@ class Language
|
||||
/**
|
||||
* Ensures the language is valid and supported
|
||||
*
|
||||
* @param $lang
|
||||
* @param string $lang
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -361,7 +371,7 @@ class Language
|
||||
/**
|
||||
* Translate a key and possibly arguments into a string using current lang and fallbacks
|
||||
*
|
||||
* @param mixed $args The first argument is the lookup key value
|
||||
* @param string|array $args The first argument is the lookup key value
|
||||
* Other arguments can be passed and replaced in the translation with sprintf syntax
|
||||
* @param array $languages
|
||||
* @param bool $array_support
|
||||
@@ -414,9 +424,9 @@ class Language
|
||||
/**
|
||||
* Translate Array
|
||||
*
|
||||
* @param $key
|
||||
* @param $index
|
||||
* @param null $languages
|
||||
* @param string $key
|
||||
* @param string $index
|
||||
* @param array|null $languages
|
||||
* @param bool $html_out
|
||||
*
|
||||
* @return string
|
||||
@@ -473,10 +483,9 @@ class Language
|
||||
/**
|
||||
* Get the browser accepted languages
|
||||
*
|
||||
* @deprecated 1.6.0 no longer used - using content negotiation
|
||||
*
|
||||
* @param array $accept_langs
|
||||
* @return array
|
||||
* @deprecated 1.6 No longer used - using content negotiation.
|
||||
*/
|
||||
public function getBrowserLanguages($accept_langs = [])
|
||||
{
|
||||
@@ -489,6 +498,8 @@ class Language
|
||||
return $accept_langs;
|
||||
}
|
||||
|
||||
$langs = [];
|
||||
|
||||
foreach (explode(',', $accept_langs) as $k => $pref) {
|
||||
// split $pref again by ';q='
|
||||
// and decorate the language entries by inverted position
|
||||
@@ -509,7 +520,7 @@ class Language
|
||||
/**
|
||||
* Accessible wrapper to LanguageCodes
|
||||
*
|
||||
* @param $code
|
||||
* @param string $code
|
||||
* @param string $type
|
||||
* @return bool
|
||||
*/
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
|
||||
class Parsedown extends \Parsedown
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
@@ -16,8 +18,8 @@ class Parsedown extends \Parsedown
|
||||
/**
|
||||
* Parsedown constructor.
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
* @param PageInterface $page
|
||||
* @param array|null $defaults
|
||||
*/
|
||||
public function __construct($page, $defaults)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
|
||||
class ParsedownExtra extends \ParsedownExtra
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
@@ -16,8 +18,8 @@ class ParsedownExtra extends \ParsedownExtra
|
||||
/**
|
||||
* ParsedownExtra constructor.
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
* @param PageInterface $page
|
||||
* @param array|null $defaults
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct($page, $defaults)
|
||||
|
||||
@@ -11,12 +11,12 @@ namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Helpers\Excerpts;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
|
||||
trait ParsedownGravTrait
|
||||
{
|
||||
/** @var Page $page */
|
||||
/** @var PageInterface $page */
|
||||
protected $page;
|
||||
|
||||
protected $special_chars;
|
||||
@@ -28,8 +28,8 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Initialization function to setup key variables needed by the MarkdownGravLinkTrait
|
||||
*
|
||||
* @param $page
|
||||
* @param $defaults
|
||||
* @param PageInterface $page
|
||||
* @param array|null $defaults
|
||||
*/
|
||||
protected function init($page, $defaults)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ trait ParsedownGravTrait
|
||||
$this->special_chars = ['>' => 'gt', '<' => 'lt', '"' => 'quot'];
|
||||
|
||||
if ($defaults === null) {
|
||||
$defaults = Grav::instance()['config']->get('system.pages.markdown');
|
||||
$defaults = (array)Grav::instance()['config']->get('system.pages.markdown');
|
||||
}
|
||||
|
||||
$this->setBreaksEnabled($defaults['auto_line_breaks']);
|
||||
@@ -48,18 +48,18 @@ trait ParsedownGravTrait
|
||||
$this->setMarkupEscaped($defaults['escape_markup']);
|
||||
$this->setSpecialChars($defaults['special_chars']);
|
||||
|
||||
$grav->fireEvent('onMarkdownInitialized', new Event(['markdown' => $this]));
|
||||
$grav->fireEvent('onMarkdownInitialized', new Event(['markdown' => $this, 'page' => $page]));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Be able to define a new Block type or override an existing one
|
||||
*
|
||||
* @param $type
|
||||
* @param $tag
|
||||
* @param string $type
|
||||
* @param string $tag
|
||||
* @param bool $continuable
|
||||
* @param bool $completable
|
||||
* @param $index
|
||||
* @param int|null $index
|
||||
*/
|
||||
public function addBlockType($type, $tag, $continuable = false, $completable = false, $index = null)
|
||||
{
|
||||
@@ -88,9 +88,9 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Be able to define a new Inline type or override an existing one
|
||||
*
|
||||
* @param $type
|
||||
* @param $tag
|
||||
* @param $index
|
||||
* @param string $type
|
||||
* @param string $tag
|
||||
* @param int|null $index
|
||||
*/
|
||||
public function addInlineType($type, $tag, $index = null)
|
||||
{
|
||||
@@ -108,7 +108,7 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Overrides the default behavior to allow for plugin-provided blocks to be continuable
|
||||
*
|
||||
* @param $Type
|
||||
* @param string $Type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -122,7 +122,7 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Overrides the default behavior to allow for plugin-provided blocks to be completable
|
||||
*
|
||||
* @param $Type
|
||||
* @param string $Type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -149,7 +149,7 @@ trait ParsedownGravTrait
|
||||
/**
|
||||
* Setter for special chars
|
||||
*
|
||||
* @param $special_chars
|
||||
* @param array $special_chars
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
||||
@@ -14,4 +14,10 @@ namespace Grav\Common\Media\Interfaces;
|
||||
*/
|
||||
interface MediaCollectionInterface extends \Grav\Framework\Media\Interfaces\MediaCollectionInterface
|
||||
{
|
||||
/**
|
||||
* Return media path.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPath();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ use Grav\Common\Cache;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
|
||||
use Grav\Common\Page\Media;
|
||||
use Psr\SimpleCache\CacheInterface;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
trait MediaTrait
|
||||
@@ -71,9 +72,9 @@ trait MediaTrait
|
||||
|
||||
// Use cached media if possible.
|
||||
$cacheKey = md5('media' . $this->getCacheKey());
|
||||
if (!$media = $cache->fetch($cacheKey)) {
|
||||
if (!$media = $cache->get($cacheKey)) {
|
||||
$media = new Media($this->getMediaFolder(), $this->getMediaOrder());
|
||||
$cache->save($cacheKey, $media);
|
||||
$cache->set($cacheKey, $media);
|
||||
}
|
||||
$this->media = $media;
|
||||
}
|
||||
@@ -91,7 +92,7 @@ trait MediaTrait
|
||||
{
|
||||
$cache = $this->getMediaCache();
|
||||
$cacheKey = md5('media' . $this->getCacheKey());
|
||||
$cache->save($cacheKey, $media);
|
||||
$cache->set($cacheKey, $media);
|
||||
|
||||
$this->media = $media;
|
||||
|
||||
@@ -111,11 +112,14 @@ trait MediaTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Cache
|
||||
* @return CacheInterface
|
||||
*/
|
||||
protected function getMediaCache()
|
||||
{
|
||||
return Grav::instance()['cache'];
|
||||
/** @var Cache $cache */
|
||||
$cache = Grav::instance()['cache'];
|
||||
|
||||
return $cache->getSimpleCache();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Common\Page;
|
||||
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Iterator;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
class Collection extends Iterator
|
||||
@@ -53,11 +54,11 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Add a single page to a collection
|
||||
*
|
||||
* @param Page $page
|
||||
* @param PageInterface $page
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addPage(Page $page)
|
||||
public function addPage(PageInterface $page)
|
||||
{
|
||||
$this->items[$page->path()] = ['slug' => $page->slug()];
|
||||
|
||||
@@ -67,8 +68,8 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Add a page with path and slug
|
||||
*
|
||||
* @param $path
|
||||
* @param $slug
|
||||
* @param string $path
|
||||
* @param string $slug
|
||||
* @return $this
|
||||
*/
|
||||
public function add($path, $slug)
|
||||
@@ -140,7 +141,7 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Returns current page.
|
||||
*
|
||||
* @return Page
|
||||
* @return PageInterface
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
@@ -176,7 +177,7 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Split collection into array of smaller collections.
|
||||
*
|
||||
* @param $size
|
||||
* @param int $size
|
||||
* @return array|Collection[]
|
||||
*/
|
||||
public function batch($size)
|
||||
@@ -194,14 +195,14 @@ class Collection extends Iterator
|
||||
/**
|
||||
* Remove item from the list.
|
||||
*
|
||||
* @param Page|string|null $key
|
||||
* @param PageInterface|string|null $key
|
||||
*
|
||||
* @return $this
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function remove($key = null)
|
||||
{
|
||||
if ($key instanceof Page) {
|
||||
if ($key instanceof PageInterface) {
|
||||
$key = $key->path();
|
||||
} elseif (null === $key) {
|
||||
$key = (string)key($this->items);
|
||||
@@ -237,7 +238,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return boolean True if item is first.
|
||||
* @return bool True if item is first.
|
||||
*/
|
||||
public function isFirst($path)
|
||||
{
|
||||
@@ -249,7 +250,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return boolean True if item is last.
|
||||
* @return bool True if item is last.
|
||||
*/
|
||||
public function isLast($path)
|
||||
{
|
||||
@@ -261,7 +262,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Page The previous item.
|
||||
* @return PageInterface The previous item.
|
||||
*/
|
||||
public function prevSibling($path)
|
||||
{
|
||||
@@ -273,7 +274,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path
|
||||
*
|
||||
* @return Page The next item.
|
||||
* @return PageInterface The next item.
|
||||
*/
|
||||
public function nextSibling($path)
|
||||
{
|
||||
@@ -284,9 +285,9 @@ class Collection extends Iterator
|
||||
* Returns the adjacent sibling based on a direction.
|
||||
*
|
||||
* @param string $path
|
||||
* @param integer $direction either -1 or +1
|
||||
* @param int $direction either -1 or +1
|
||||
*
|
||||
* @return Page|Collection The sibling item.
|
||||
* @return PageInterface|Collection The sibling item.
|
||||
*/
|
||||
public function adjacentSibling($path, $direction = 1)
|
||||
{
|
||||
@@ -308,7 +309,7 @@ class Collection extends Iterator
|
||||
*
|
||||
* @param string $path the path the item
|
||||
*
|
||||
* @return Integer the index of the current page.
|
||||
* @return int the index of the current page.
|
||||
*/
|
||||
public function currentPosition($path)
|
||||
{
|
||||
@@ -321,14 +322,14 @@ class Collection extends Iterator
|
||||
* Dates can be passed in as text that strtotime() can process
|
||||
* http://php.net/manual/en/function.strtotime.php
|
||||
*
|
||||
* @param $startDate
|
||||
* @param string $startDate
|
||||
* @param bool $endDate
|
||||
* @param $field
|
||||
* @param string|null $field
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function dateRange($startDate, $endDate = false, $field = false)
|
||||
public function dateRange($startDate, $endDate = false, $field = null)
|
||||
{
|
||||
$start = Utils::date2timestamp($startDate);
|
||||
$end = $endDate ? Utils::date2timestamp($endDate) : false;
|
||||
|
||||
267
system/src/Grav/Common/Page/Interfaces/PageContentInterface.php
Normal file
267
system/src/Grav/Common/Page/Interfaces/PageContentInterface.php
Normal file
@@ -0,0 +1,267 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Grav\Common\Page
|
||||
*
|
||||
* @copyright Copyright (C) 2015 - 2019 Trilby Media, LLC. All rights reserved.
|
||||
* @license MIT License; see LICENSE file for details.
|
||||
*/
|
||||
|
||||
namespace Grav\Common\Page\Interfaces;
|
||||
|
||||
use Grav\Common\Page\Media;
|
||||
|
||||
/**
|
||||
* Methods currently implemented in Flex Page emulation layer.
|
||||
*/
|
||||
interface PageContentInterface
|
||||
{
|
||||
/**
|
||||
* Gets and Sets the header based on the YAML configuration at the top of the .md file
|
||||
*
|
||||
* @param object|array $var a YAML object representing the configuration for the file
|
||||
*
|
||||
* @return object the current YAML configuration
|
||||
*/
|
||||
public function header($var = null);
|
||||
|
||||
/**
|
||||
* Get the summary.
|
||||
*
|
||||
* @param int $size Max summary size.
|
||||
*
|
||||
* @param bool $textOnly Only count text size.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function summary($size = null, $textOnly = false);
|
||||
|
||||
/**
|
||||
* Gets and Sets the content based on content portion of the .md file
|
||||
*
|
||||
* @param string $var Content
|
||||
*
|
||||
* @return string Content
|
||||
*/
|
||||
public function content($var = null);
|
||||
|
||||
/**
|
||||
* Needed by the onPageContentProcessed event to get the raw page content
|
||||
*
|
||||
* @return string the current page content
|
||||
*/
|
||||
public function getRawContent();
|
||||
|
||||
/**
|
||||
* Needed by the onPageContentProcessed event to set the raw page content
|
||||
*
|
||||
* @param string $content
|
||||
*/
|
||||
public function setRawContent($content);
|
||||
|
||||
/**
|
||||
* Gets and Sets the Page raw content
|
||||
*
|
||||
* @param string|null $var
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function rawMarkdown($var = null);
|
||||
|
||||
/**
|
||||
* Get value from a page variable (used mostly for creating edit forms).
|
||||
*
|
||||
* @param string $name Variable name.
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function value($name, $default = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the associated media as found in the page folder.
|
||||
*
|
||||
* @param Media $var Representation of associated media.
|
||||
*
|
||||
* @return Media Representation of associated media.
|
||||
*/
|
||||
public function media($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the title for this Page. If no title is set, it will use the slug() to get a name
|
||||
*
|
||||
* @param string $var the title of the Page
|
||||
*
|
||||
* @return string the title of the Page
|
||||
*/
|
||||
public function title($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the menu name for this Page. This is the text that can be used specifically for navigation.
|
||||
* If no menu field is set, it will use the title()
|
||||
*
|
||||
* @param string $var the menu field for the page
|
||||
*
|
||||
* @return string the menu field for the page
|
||||
*/
|
||||
public function menu($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets whether or not this Page is visible for navigation
|
||||
*
|
||||
* @param bool $var true if the page is visible
|
||||
*
|
||||
* @return bool true if the page is visible
|
||||
*/
|
||||
public function visible($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets whether or not this Page is considered published
|
||||
*
|
||||
* @param bool $var true if the page is published
|
||||
*
|
||||
* @return bool true if the page is published
|
||||
*/
|
||||
public function published($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the Page publish date
|
||||
*
|
||||
* @param string $var string representation of a date
|
||||
*
|
||||
* @return int unix timestamp representation of the date
|
||||
*/
|
||||
public function publishDate($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the Page unpublish date
|
||||
*
|
||||
* @param string $var string representation of a date
|
||||
*
|
||||
* @return int|null unix timestamp representation of the date
|
||||
*/
|
||||
public function unpublishDate($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the process setup for this Page. This is multi-dimensional array that consists of
|
||||
* a simple array of arrays with the form array("markdown"=>true) for example
|
||||
*
|
||||
* @param array $var an Array of name value pairs where the name is the process and value is true or false
|
||||
*
|
||||
* @return array an Array of name value pairs where the name is the process and value is true or false
|
||||
*/
|
||||
public function process($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the slug for the Page. The slug is used in the URL routing. If not set it uses
|
||||
* the parent folder from the path
|
||||
*
|
||||
* @param string $var the slug, e.g. 'my-blog'
|
||||
*
|
||||
* @return string the slug
|
||||
*/
|
||||
public function slug($var = null);
|
||||
|
||||
/**
|
||||
* Get/set order number of this page.
|
||||
*
|
||||
* @param int $var
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function order($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the identifier for this Page object.
|
||||
*
|
||||
* @param string $var the identifier
|
||||
*
|
||||
* @return string the identifier
|
||||
*/
|
||||
public function id($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the modified timestamp.
|
||||
*
|
||||
* @param int $var modified unix timestamp
|
||||
*
|
||||
* @return int modified unix timestamp
|
||||
*/
|
||||
public function modified($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the option to show the last_modified header for the page.
|
||||
*
|
||||
* @param boolean $var show last_modified header
|
||||
*
|
||||
* @return boolean show last_modified header
|
||||
*/
|
||||
public function lastModified($var = null);
|
||||
|
||||
/**
|
||||
* Get/set the folder.
|
||||
*
|
||||
* @param string $var Optional path
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function folder($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the date for this Page object. This is typically passed in via the page headers
|
||||
*
|
||||
* @param string $var string representation of a date
|
||||
*
|
||||
* @return int unix timestamp representation of the date
|
||||
*/
|
||||
public function date($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the date format for this Page object. This is typically passed in via the page headers
|
||||
* using typical PHP date string structure - http://php.net/manual/en/function.date.php
|
||||
*
|
||||
* @param string $var string representation of a date format
|
||||
*
|
||||
* @return string string representation of a date format
|
||||
*/
|
||||
public function dateformat($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the taxonomy array which defines which taxonomies this page identifies itself with.
|
||||
*
|
||||
* @param array $var an array of taxonomies
|
||||
*
|
||||
* @return array an array of taxonomies
|
||||
*/
|
||||
public function taxonomy($var = null);
|
||||
|
||||
/**
|
||||
* Gets the configured state of the processing method.
|
||||
*
|
||||
* @param string $process the process, eg "twig" or "markdown"
|
||||
*
|
||||
* @return bool whether or not the processing method is enabled for this Page
|
||||
*/
|
||||
public function shouldProcess($process);
|
||||
|
||||
/**
|
||||
* Returns whether or not this Page object has a .md file associated with it or if its just a directory.
|
||||
*
|
||||
* @return bool True if its a page with a .md file associated
|
||||
*/
|
||||
public function isPage();
|
||||
|
||||
/**
|
||||
* Returns whether or not this Page object is a directory or a page.
|
||||
*
|
||||
* @return bool True if its a directory
|
||||
*/
|
||||
public function isDir();
|
||||
|
||||
/**
|
||||
* Returns whether the page exists in the filesystem.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function exists();
|
||||
}
|
||||
@@ -9,9 +9,11 @@
|
||||
|
||||
namespace Grav\Common\Page\Interfaces;
|
||||
|
||||
use Grav\Common\Media\Interfaces\MediaInterface;
|
||||
|
||||
/**
|
||||
* Class implements page interface.
|
||||
*/
|
||||
interface PageInterface
|
||||
interface PageInterface extends PageContentInterface, PageRoutableInterface, PageTranslateInterface, MediaInterface, PageLegacyInterface
|
||||
{
|
||||
}
|
||||
|
||||
496
system/src/Grav/Common/Page/Interfaces/PageLegacyInterface.php
Normal file
496
system/src/Grav/Common/Page/Interfaces/PageLegacyInterface.php
Normal file
@@ -0,0 +1,496 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Interfaces;
|
||||
|
||||
use Exception;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Page\Collection;
|
||||
use RocketTheme\Toolbox\File\MarkdownFile;
|
||||
|
||||
interface PageLegacyInterface
|
||||
{
|
||||
/**
|
||||
* Initializes the page instance variables based on a file
|
||||
*
|
||||
* @param \SplFileInfo $file The file information for the .md file that the page represents
|
||||
* @param string $extension
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function init(\SplFileInfo $file, $extension = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the raw data
|
||||
*
|
||||
* @param string $var Raw content string
|
||||
*
|
||||
* @return string Raw content string
|
||||
*/
|
||||
public function raw($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the page frontmatter
|
||||
*
|
||||
* @param string|null $var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function frontmatter($var = null);
|
||||
|
||||
/**
|
||||
* Modify a header value directly
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function modifyHeader($key, $value);
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function httpResponseCode();
|
||||
|
||||
public function httpHeaders();
|
||||
|
||||
/**
|
||||
* Sets the summary of the page
|
||||
*
|
||||
* @param string $summary Summary
|
||||
*/
|
||||
public function setSummary($summary);
|
||||
|
||||
/**
|
||||
* Get the contentMeta array and initialize content first if it's not already
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function contentMeta();
|
||||
|
||||
/**
|
||||
* Add an entry to the page's contentMeta array
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public function addContentMeta($name, $value);
|
||||
|
||||
/**
|
||||
* Return the whole contentMeta array as it currently stands
|
||||
*
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getContentMeta($name = null);
|
||||
|
||||
/**
|
||||
* Sets the whole content meta array in one shot
|
||||
*
|
||||
* @param array $content_meta
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function setContentMeta($content_meta);
|
||||
|
||||
/**
|
||||
* Fires the onPageContentProcessed event, and caches the page content using a unique ID for the page
|
||||
*/
|
||||
public function cachePageContent();
|
||||
|
||||
/**
|
||||
* Get file object to the page.
|
||||
*
|
||||
* @return MarkdownFile|null
|
||||
*/
|
||||
public function file();
|
||||
|
||||
/**
|
||||
* Save page if there's a file assigned to it.
|
||||
*
|
||||
* @param bool|mixed $reorder Internal use.
|
||||
*/
|
||||
public function save($reorder = true);
|
||||
|
||||
/**
|
||||
* Prepare move page to new location. Moves also everything that's under the current page.
|
||||
*
|
||||
* You need to call $this->save() in order to perform the move.
|
||||
*
|
||||
* @param PageInterface $parent New parent page.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function move(PageInterface $parent);
|
||||
|
||||
/**
|
||||
* Prepare a copy from the page. Copies also everything that's under the current page.
|
||||
*
|
||||
* Returns a new Page object for the copy.
|
||||
* You need to call $this->save() in order to perform the move.
|
||||
*
|
||||
* @param PageInterface $parent New parent page.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function copy(PageInterface $parent);
|
||||
|
||||
/**
|
||||
* Get blueprints for the page.
|
||||
*
|
||||
* @return Blueprint
|
||||
*/
|
||||
public function blueprints();
|
||||
|
||||
/**
|
||||
* Get the blueprint name for this page. Use the blueprint form field if set
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function blueprintName();
|
||||
|
||||
/**
|
||||
* Validate page header.
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function validate();
|
||||
|
||||
/**
|
||||
* Filter page header from illegal contents.
|
||||
*/
|
||||
public function filter();
|
||||
|
||||
/**
|
||||
* Get unknown header variables.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function extra();
|
||||
|
||||
/**
|
||||
* Convert page to an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray();
|
||||
|
||||
/**
|
||||
* Convert page to YAML encoded string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toYaml();
|
||||
|
||||
/**
|
||||
* Convert page to JSON encoded string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function toJson();
|
||||
|
||||
/**
|
||||
* Returns normalized list of name => form pairs.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function forms();
|
||||
|
||||
/**
|
||||
* @param array $new
|
||||
*/
|
||||
public function addForms(array $new);
|
||||
|
||||
/**
|
||||
* Gets and sets the name field. If no name field is set, it will return 'default.md'.
|
||||
*
|
||||
* @param string $var The name of this page.
|
||||
*
|
||||
* @return string The name of this page.
|
||||
*/
|
||||
public function name($var = null);
|
||||
|
||||
/**
|
||||
* Returns child page type.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function childType();
|
||||
|
||||
/**
|
||||
* Gets and sets the template field. This is used to find the correct Twig template file to render.
|
||||
* If no field is set, it will return the name without the .md extension
|
||||
*
|
||||
* @param string $var the template name
|
||||
*
|
||||
* @return string the template name
|
||||
*/
|
||||
public function template($var = null);
|
||||
|
||||
/**
|
||||
* Allows a page to override the output render format, usually the extension provided
|
||||
* in the URL. (e.g. `html`, `json`, `xml`, etc).
|
||||
*
|
||||
* @param null $var
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function templateFormat($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the extension field.
|
||||
*
|
||||
* @param null $var
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function extension($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the expires field. If not set will return the default
|
||||
*
|
||||
* @param int $var The new expires value.
|
||||
*
|
||||
* @return int The expires value
|
||||
*/
|
||||
public function expires($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the cache-control property. If not set it will return the default value (null)
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control for more details on valid options
|
||||
*
|
||||
* @param null $var
|
||||
* @return null
|
||||
*/
|
||||
public function cacheControl($var = null);
|
||||
|
||||
public function ssl($var = null);
|
||||
|
||||
/**
|
||||
* Returns the state of the debugger override etting for this page
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function debugger();
|
||||
|
||||
/**
|
||||
* Function to merge page metadata tags and build an array of Metadata objects
|
||||
* that can then be rendered in the page.
|
||||
*
|
||||
* @param array $var an Array of metadata values to set
|
||||
*
|
||||
* @return array an Array of metadata values for the page
|
||||
*/
|
||||
public function metadata($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the option to show the etag header for the page.
|
||||
*
|
||||
* @param bool $var show etag header
|
||||
*
|
||||
* @return bool show etag header
|
||||
*/
|
||||
public function eTag($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the path to the .md file for this Page object.
|
||||
*
|
||||
* @param string $var the file path
|
||||
*
|
||||
* @return string|null the file path
|
||||
*/
|
||||
public function filePath($var = null);
|
||||
|
||||
/**
|
||||
* Gets the relative path to the .md file
|
||||
*
|
||||
* @return string The relative file path
|
||||
*/
|
||||
public function filePathClean();
|
||||
|
||||
/**
|
||||
* Gets and sets the order by which any sub-pages should be sorted.
|
||||
*
|
||||
* @param string $var the order, either "asc" or "desc"
|
||||
*
|
||||
* @return string the order, either "asc" or "desc"
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function orderDir($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the order by which the sub-pages should be sorted.
|
||||
*
|
||||
* default - is the order based on the file system, ie 01.Home before 02.Advark
|
||||
* title - is the order based on the title set in the pages
|
||||
* date - is the order based on the date set in the pages
|
||||
* folder - is the order based on the name of the folder with any numerics omitted
|
||||
*
|
||||
* @param string $var supported options include "default", "title", "date", and "folder"
|
||||
*
|
||||
* @return string supported options include "default", "title", "date", and "folder"
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function orderBy($var = null);
|
||||
|
||||
/**
|
||||
* Gets the manual order set in the header.
|
||||
*
|
||||
* @param string $var supported options include "default", "title", "date", and "folder"
|
||||
*
|
||||
* @return array
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function orderManual($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the maxCount field which describes how many sub-pages should be displayed if the
|
||||
* sub_pages header property is set for this page object.
|
||||
*
|
||||
* @param int $var the maximum number of sub-pages
|
||||
*
|
||||
* @return int the maximum number of sub-pages
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function maxCount($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the modular var that helps identify this page is a modular child
|
||||
*
|
||||
* @param bool $var true if modular_twig
|
||||
*
|
||||
* @return bool true if modular_twig
|
||||
*/
|
||||
public function modular($var = null);
|
||||
|
||||
/**
|
||||
* Gets and sets the modular_twig var that helps identify this page as a modular child page that will need
|
||||
* twig processing handled differently from a regular page.
|
||||
*
|
||||
* @param bool $var true if modular_twig
|
||||
*
|
||||
* @return bool true if modular_twig
|
||||
*/
|
||||
public function modularTwig($var = null);
|
||||
|
||||
/**
|
||||
* Returns children of this page.
|
||||
*
|
||||
* @return \Grav\Common\Page\Collection
|
||||
*/
|
||||
public function children();
|
||||
|
||||
/**
|
||||
* Check to see if this item is the first in an array of sub-pages.
|
||||
*
|
||||
* @return bool True if item is first.
|
||||
*/
|
||||
public function isFirst();
|
||||
|
||||
/**
|
||||
* Check to see if this item is the last in an array of sub-pages.
|
||||
*
|
||||
* @return bool True if item is last
|
||||
*/
|
||||
public function isLast();
|
||||
|
||||
/**
|
||||
* Gets the previous sibling based on current position.
|
||||
*
|
||||
* @return PageInterface the previous Page item
|
||||
*/
|
||||
public function prevSibling();
|
||||
|
||||
/**
|
||||
* Gets the next sibling based on current position.
|
||||
*
|
||||
* @return PageInterface the next Page item
|
||||
*/
|
||||
public function nextSibling();
|
||||
|
||||
/**
|
||||
* Returns the adjacent sibling based on a direction.
|
||||
*
|
||||
* @param int $direction either -1 or +1
|
||||
*
|
||||
* @return PageInterface|bool the sibling page
|
||||
*/
|
||||
public function adjacentSibling($direction = 1);
|
||||
|
||||
/**
|
||||
* Helper method to return an ancestor page.
|
||||
*
|
||||
* @param bool $lookup Name of the parent folder
|
||||
*
|
||||
* @return PageInterface page you were looking for if it exists
|
||||
*/
|
||||
public function ancestor($lookup = null);
|
||||
|
||||
/**
|
||||
* Helper method to return an ancestor page to inherit from. The current
|
||||
* page object is returned.
|
||||
*
|
||||
* @param string $field Name of the parent folder
|
||||
*
|
||||
* @return PageInterface
|
||||
*/
|
||||
public function inherited($field);
|
||||
|
||||
/**
|
||||
* Helper method to return an ancestor field only to inherit from. The
|
||||
* first occurrence of an ancestor field will be returned if at all.
|
||||
*
|
||||
* @param string $field Name of the parent folder
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function inheritedField($field);
|
||||
|
||||
/**
|
||||
* Helper method to return a page.
|
||||
*
|
||||
* @param string $url the url of the page
|
||||
* @param bool $all
|
||||
*
|
||||
* @return PageInterface page you were looking for if it exists
|
||||
*/
|
||||
public function find($url, $all = false);
|
||||
|
||||
/**
|
||||
* Get a collection of pages in the current context.
|
||||
*
|
||||
* @param string|array $params
|
||||
* @param bool $pagination
|
||||
*
|
||||
* @return Collection
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function collection($params = 'content', $pagination = true);
|
||||
|
||||
/**
|
||||
* @param string|array $value
|
||||
* @param bool $only_published
|
||||
* @return mixed
|
||||
* @internal
|
||||
*/
|
||||
public function evaluate($value, $only_published = true);
|
||||
|
||||
/**
|
||||
* Returns whether or not the current folder exists
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function folderExists();
|
||||
|
||||
/**
|
||||
* Gets the Page Unmodified (original) version of the page.
|
||||
*
|
||||
* @return PageInterface The original version of the page.
|
||||
*/
|
||||
public function getOriginal();
|
||||
|
||||
/**
|
||||
* Gets the action.
|
||||
*
|
||||
* @return string The Action string.
|
||||
*/
|
||||
public function getAction();
|
||||
}
|
||||
188
system/src/Grav/Common/Page/Interfaces/PageRoutableInterface.php
Normal file
188
system/src/Grav/Common/Page/Interfaces/PageRoutableInterface.php
Normal file
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Interfaces;
|
||||
|
||||
interface PageRoutableInterface
|
||||
{
|
||||
/**
|
||||
* Returns the page extension, got from the page `url_extension` config and falls back to the
|
||||
* system config `system.pages.append_url_extension`.
|
||||
*
|
||||
* @return string The extension of this page. For example `.html`
|
||||
*/
|
||||
public function urlExtension();
|
||||
|
||||
/**
|
||||
* Gets and Sets whether or not this Page is routable, ie you can reach it
|
||||
* via a URL.
|
||||
* The page must be *routable* and *published*
|
||||
*
|
||||
* @param bool $var true if the page is routable
|
||||
*
|
||||
* @return bool true if the page is routable
|
||||
*/
|
||||
public function routable($var = null);
|
||||
|
||||
/**
|
||||
* Gets the URL for a page - alias of url().
|
||||
*
|
||||
* @param bool $include_host
|
||||
*
|
||||
* @return string the permalink
|
||||
*/
|
||||
public function link($include_host = false);
|
||||
|
||||
/**
|
||||
* Gets the URL with host information, aka Permalink.
|
||||
* @return string The permalink.
|
||||
*/
|
||||
public function permalink();
|
||||
|
||||
/**
|
||||
* Returns the canonical URL for a page
|
||||
*
|
||||
* @param bool $include_lang
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function canonical($include_lang = true);
|
||||
|
||||
/**
|
||||
* Gets the url for the Page.
|
||||
*
|
||||
* @param bool $include_host Defaults false, but true would include http://yourhost.com
|
||||
* @param bool $canonical true to return the canonical URL
|
||||
* @param bool $include_lang
|
||||
* @param bool $raw_route
|
||||
*
|
||||
* @return string The url.
|
||||
*/
|
||||
public function url($include_host = false, $canonical = false, $include_lang = true, $raw_route = false);
|
||||
|
||||
/**
|
||||
* Gets the route for the page based on the route headers if available, else from
|
||||
* the parents route and the current Page's slug.
|
||||
*
|
||||
* @param string $var Set new default route.
|
||||
*
|
||||
* @return string The route for the Page.
|
||||
*/
|
||||
public function route($var = null);
|
||||
|
||||
/**
|
||||
* Helper method to clear the route out so it regenerates next time you use it
|
||||
*/
|
||||
public function unsetRouteSlug();
|
||||
|
||||
/**
|
||||
* Gets and Sets the page raw route
|
||||
*
|
||||
* @param string|null $var
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function rawRoute($var = null);
|
||||
|
||||
/**
|
||||
* Gets the route aliases for the page based on page headers.
|
||||
*
|
||||
* @param array $var list of route aliases
|
||||
*
|
||||
* @return array The route aliases for the Page.
|
||||
*/
|
||||
public function routeAliases($var = null);
|
||||
|
||||
/**
|
||||
* Gets the canonical route for this page if its set. If provided it will use
|
||||
* that value, else if it's `true` it will use the default route.
|
||||
*
|
||||
* @param string|null $var
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
public function routeCanonical($var = null);
|
||||
|
||||
/**
|
||||
* Gets the redirect set in the header.
|
||||
*
|
||||
* @param string $var redirect url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirect($var = null);
|
||||
|
||||
/**
|
||||
* Returns the clean path to the page file
|
||||
*/
|
||||
public function relativePagePath();
|
||||
|
||||
/**
|
||||
* Gets and sets the path to the folder where the .md for this Page object resides.
|
||||
* This is equivalent to the filePath but without the filename.
|
||||
*
|
||||
* @param string $var the path
|
||||
*
|
||||
* @return string|null the path
|
||||
*/
|
||||
public function path($var = null);
|
||||
|
||||
/**
|
||||
* Get/set the folder.
|
||||
*
|
||||
* @param string $var Optional path
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function folder($var = null);
|
||||
|
||||
/**
|
||||
* Gets and Sets the parent object for this page
|
||||
*
|
||||
* @param PageInterface $var the parent page object
|
||||
*
|
||||
* @return PageInterface|null the parent page object if it exists.
|
||||
*/
|
||||
public function parent(PageInterface $var = null);
|
||||
|
||||
/**
|
||||
* Gets the top parent object for this page
|
||||
*
|
||||
* @return PageInterface|null the top parent page object if it exists.
|
||||
*/
|
||||
public function topParent();
|
||||
|
||||
/**
|
||||
* Returns the item in the current position.
|
||||
*
|
||||
* @return int the index of the current page.
|
||||
*/
|
||||
public function currentPosition();
|
||||
|
||||
/**
|
||||
* Returns whether or not this page is the currently active page requested via the URL.
|
||||
*
|
||||
* @return bool True if it is active
|
||||
*/
|
||||
public function active();
|
||||
|
||||
/**
|
||||
* Returns whether or not this URI's URL contains the URL of the active page.
|
||||
* Or in other words, is this page's URL in the current URL
|
||||
*
|
||||
* @return bool True if active child exists
|
||||
*/
|
||||
public function activeChild();
|
||||
|
||||
/**
|
||||
* Returns whether or not this page is the currently configured home page.
|
||||
*
|
||||
* @return bool True if it is the homepage
|
||||
*/
|
||||
public function home();
|
||||
|
||||
/**
|
||||
* Returns whether or not this page is the root node of the pages tree.
|
||||
*
|
||||
* @return bool True if it is the root
|
||||
*/
|
||||
public function root();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Interfaces;
|
||||
|
||||
interface PageTranslateInterface
|
||||
{
|
||||
/**
|
||||
* Return an array with the routes of other translated languages
|
||||
*
|
||||
* @param bool $onlyPublished only return published translations
|
||||
*
|
||||
* @return array the page translated languages
|
||||
*/
|
||||
public function translatedLanguages($onlyPublished = false);
|
||||
|
||||
/**
|
||||
* Return an array listing untranslated languages available
|
||||
*
|
||||
* @param bool $includeUnpublished also list unpublished translations
|
||||
*
|
||||
* @return array the page untranslated languages
|
||||
*/
|
||||
public function untranslatedLanguages($includeUnpublished = false);
|
||||
|
||||
/**
|
||||
* Get page language
|
||||
*
|
||||
* @param string $var
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function language($var = null);
|
||||
}
|
||||
@@ -15,13 +15,12 @@ use Grav\Common\Page\Medium\AbstractMedia;
|
||||
use Grav\Common\Page\Medium\GlobalMedia;
|
||||
use Grav\Common\Page\Medium\MediumFactory;
|
||||
use RocketTheme\Toolbox\File\File;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class Media extends AbstractMedia
|
||||
{
|
||||
protected static $global;
|
||||
|
||||
protected $path;
|
||||
|
||||
protected $standard_exif = ['FileSize', 'MimeType', 'height', 'width'];
|
||||
|
||||
/**
|
||||
@@ -31,7 +30,7 @@ class Media extends AbstractMedia
|
||||
*/
|
||||
public function __construct($path, array $media_order = null, $load = true)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->setPath($path);
|
||||
$this->media_order = $media_order;
|
||||
|
||||
$this->__wakeup();
|
||||
@@ -76,16 +75,19 @@ class Media extends AbstractMedia
|
||||
*/
|
||||
protected function init()
|
||||
{
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
$config = Grav::instance()['config'];
|
||||
$locator = Grav::instance()['locator'];
|
||||
$exif_reader = isset(Grav::instance()['exif']) ? Grav::instance()['exif']->getReader() : false;
|
||||
$media_types = array_keys(Grav::instance()['config']->get('media.types'));
|
||||
|
||||
// Handle special cases where page doesn't exist in filesystem.
|
||||
if (!is_dir($this->path)) {
|
||||
if (!is_dir($this->getPath())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$iterator = new \FilesystemIterator($this->path, \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS);
|
||||
$iterator = new \FilesystemIterator($this->getPath(), \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS);
|
||||
|
||||
$media = [];
|
||||
|
||||
@@ -159,7 +161,11 @@ class Media extends AbstractMedia
|
||||
$meta_data = $meta->getData();
|
||||
$meta_trimmed = array_diff_key($meta_data, array_flip($this->standard_exif));
|
||||
if ($meta_trimmed) {
|
||||
$file = File::instance($meta_path);
|
||||
if ($locator->isStream($meta_path)) {
|
||||
$file = File::instance($locator->findResource($meta_path, true, true));
|
||||
} else {
|
||||
$file = File::instance($meta_path);
|
||||
}
|
||||
$file->save(Yaml::dump($meta_trimmed));
|
||||
$types['meta']['file'] = $meta_path;
|
||||
}
|
||||
@@ -206,12 +212,11 @@ class Media extends AbstractMedia
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable accessing the media path
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
* @deprecated 1.6 Use $this->getPath() instead.
|
||||
*/
|
||||
public function path()
|
||||
{
|
||||
return $this->path;
|
||||
return $this->getPath();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,23 +9,47 @@
|
||||
|
||||
namespace Grav\Common\Page\Medium;
|
||||
|
||||
use Grav\Common\Getters;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
|
||||
use Grav\Common\Media\Interfaces\MediaObjectInterface;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Utils;
|
||||
use RocketTheme\Toolbox\ArrayTraits\ArrayAccess;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Countable;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Export;
|
||||
use RocketTheme\Toolbox\ArrayTraits\ExportInterface;
|
||||
use RocketTheme\Toolbox\ArrayTraits\Iterator;
|
||||
|
||||
abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
abstract class AbstractMedia implements ExportInterface, MediaCollectionInterface
|
||||
{
|
||||
protected $gettersVariable = 'instances';
|
||||
use ArrayAccess;
|
||||
use Countable;
|
||||
use Iterator;
|
||||
use Export;
|
||||
|
||||
protected $instances = [];
|
||||
protected $items = [];
|
||||
protected $path;
|
||||
protected $images = [];
|
||||
protected $videos = [];
|
||||
protected $audios = [];
|
||||
protected $files = [];
|
||||
protected $media_order;
|
||||
|
||||
/**
|
||||
* Return media path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
public function setPath(?string $path)
|
||||
{
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get medium by filename.
|
||||
*
|
||||
@@ -48,21 +72,6 @@ abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
return $this->offsetGet($filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$object = parent::offsetGet($offset);
|
||||
|
||||
// It would be nice if previous image modification would not affect the later ones.
|
||||
//$object = $object ? clone($object) : null;
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file modification timestamps (query params) for all the media files.
|
||||
*
|
||||
@@ -72,7 +81,7 @@ abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
public function setTimestamps($timestamp = null)
|
||||
{
|
||||
/** @var Medium $instance */
|
||||
foreach ($this->instances as $instance) {
|
||||
foreach ($this->items as $instance) {
|
||||
$instance->setTimestamp($timestamp);
|
||||
}
|
||||
|
||||
@@ -82,56 +91,60 @@ abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
/**
|
||||
* Get a list of all media.
|
||||
*
|
||||
* @return array|MediaObjectInterface[]
|
||||
* @return MediaObjectInterface[]
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
$this->instances = $this->orderMedia($this->instances);
|
||||
$this->items = $this->orderMedia($this->items);
|
||||
|
||||
return $this->instances;
|
||||
return $this->items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all image media.
|
||||
*
|
||||
* @return array|MediaObjectInterface[]
|
||||
* @return MediaObjectInterface[]
|
||||
*/
|
||||
public function images()
|
||||
{
|
||||
$this->images = $this->orderMedia($this->images);
|
||||
|
||||
return $this->images;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all video media.
|
||||
*
|
||||
* @return array|MediaObjectInterface[]
|
||||
* @return MediaObjectInterface[]
|
||||
*/
|
||||
public function videos()
|
||||
{
|
||||
$this->videos = $this->orderMedia($this->videos);
|
||||
|
||||
return $this->videos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all audio media.
|
||||
*
|
||||
* @return array|MediaObjectInterface[]
|
||||
* @return MediaObjectInterface[]
|
||||
*/
|
||||
public function audios()
|
||||
{
|
||||
$this->audios = $this->orderMedia($this->audios);
|
||||
|
||||
return $this->audios;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all file media.
|
||||
*
|
||||
* @return array|MediaObjectInterface[]
|
||||
* @return MediaObjectInterface[]
|
||||
*/
|
||||
public function files()
|
||||
{
|
||||
$this->files = $this->orderMedia($this->files);
|
||||
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
@@ -141,7 +154,7 @@ abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
*/
|
||||
public function add($name, $file)
|
||||
{
|
||||
$this->instances[$name] = $file;
|
||||
$this->offsetSet($name, $file);
|
||||
switch ($file->type) {
|
||||
case 'image':
|
||||
$this->images[$name] = $file;
|
||||
@@ -160,13 +173,14 @@ abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
/**
|
||||
* Order the media based on the page's media_order
|
||||
*
|
||||
* @param $media
|
||||
* @param array $media
|
||||
* @return array
|
||||
*/
|
||||
protected function orderMedia($media)
|
||||
{
|
||||
if (null === $this->media_order) {
|
||||
$page = Grav::instance()['pages']->get($this->path);
|
||||
/** @var Page $page */
|
||||
$page = Grav::instance()['pages']->get($this->getPath());
|
||||
|
||||
if ($page && isset($page->header()->media_order)) {
|
||||
$this->media_order = array_map('trim', explode(',', $page->header()->media_order));
|
||||
|
||||
@@ -17,7 +17,7 @@ class AudioMedium extends Medium
|
||||
* Parsedown element for source display mode
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
protected function sourceParsedownElement(array $attributes, $reset = true)
|
||||
@@ -51,7 +51,7 @@ class AudioMedium extends Medium
|
||||
/**
|
||||
* Allows to set the preload behaviour
|
||||
*
|
||||
* @param $preload
|
||||
* @param string $preload
|
||||
* @return $this
|
||||
*/
|
||||
public function preload($preload)
|
||||
@@ -69,7 +69,7 @@ class AudioMedium extends Medium
|
||||
* Allows to set the controlsList behaviour
|
||||
* Separate multiple values with a hyphen
|
||||
*
|
||||
* @param $controlsList
|
||||
* @param string $controlsList
|
||||
* @return $this
|
||||
*/
|
||||
public function controlsList($controlsList)
|
||||
|
||||
@@ -14,6 +14,16 @@ use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class GlobalMedia extends AbstractMedia
|
||||
{
|
||||
/**
|
||||
* Return media path.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $offset
|
||||
*
|
||||
|
||||
@@ -33,13 +33,14 @@ class ImageFile extends Image
|
||||
/**
|
||||
* This is the same as the Gregwar Image class except this one fires a Grav Event on creation of new cached file
|
||||
*
|
||||
* @param string $type the image type
|
||||
* @param int $quality the quality (for JPEG)
|
||||
* @param bool $actual
|
||||
* @param string $type the image type
|
||||
* @param int $quality the quality (for JPEG)
|
||||
* @param bool $actual
|
||||
* @param array $extras
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function cacheFile($type = 'jpg', $quality = 80, $actual = false)
|
||||
public function cacheFile($type = 'jpg', $quality = 80, $actual = false, $extras = [])
|
||||
{
|
||||
if ($type === 'guess') {
|
||||
$type = $this->guessType();
|
||||
@@ -50,21 +51,16 @@ class ImageFile extends Image
|
||||
}
|
||||
|
||||
// Computes the hash
|
||||
$this->hash = $this->getHash($type, $quality);
|
||||
$this->hash = $this->getHash($type, $quality, $extras);
|
||||
|
||||
// Generates the cache file
|
||||
$cacheFile = '';
|
||||
// Seo friendly image names
|
||||
$seofriendly = Grav::instance()['config']->get('system.images.seofriendly', false);
|
||||
|
||||
if (!$this->prettyName || $this->prettyPrefix) {
|
||||
$cacheFile .= $this->hash;
|
||||
}
|
||||
|
||||
if ($this->prettyPrefix) {
|
||||
$cacheFile .= '-';
|
||||
}
|
||||
|
||||
if ($this->prettyName) {
|
||||
$cacheFile .= $this->prettyName;
|
||||
if ($seofriendly) {
|
||||
$mini_hash = substr($this->hash, 0, 4) . substr($this->hash, -4);
|
||||
$cacheFile = "{$this->prettyName}-{$mini_hash}";
|
||||
} else {
|
||||
$cacheFile = "{$this->hash}-{$this->prettyName}";
|
||||
}
|
||||
|
||||
$cacheFile .= '.' . $type;
|
||||
@@ -108,4 +104,42 @@ class ImageFile extends Image
|
||||
|
||||
return $this->getFilename($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hash.
|
||||
* @param string $type
|
||||
* @param int $quality
|
||||
* @param [] $extras
|
||||
* @return null
|
||||
*/
|
||||
public function getHash($type = 'guess', $quality = 80, $extras = [])
|
||||
{
|
||||
if (null === $this->hash) {
|
||||
$this->generateHash($type, $quality, $extras);
|
||||
}
|
||||
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the hash.
|
||||
* @param string $type
|
||||
* @param int $quality
|
||||
* @param array $extras
|
||||
*/
|
||||
public function generateHash($type = 'guess', $quality = 80, $extras = [])
|
||||
{
|
||||
$inputInfos = $this->source->getInfos();
|
||||
|
||||
$datas = array(
|
||||
$inputInfos,
|
||||
$this->serializeOperations(),
|
||||
$type,
|
||||
$quality,
|
||||
$extras
|
||||
);
|
||||
|
||||
$this->hash = sha1(serialize($datas));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class ImageMedium extends Medium
|
||||
protected $default_quality;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
protected $debug_watermarked = false;
|
||||
|
||||
@@ -122,7 +122,7 @@ class ImageMedium extends Medium
|
||||
/**
|
||||
* Add meta file for the medium.
|
||||
*
|
||||
* @param $filepath
|
||||
* @param string $filepath
|
||||
* @return $this
|
||||
*/
|
||||
public function addMetaFile($filepath)
|
||||
@@ -234,7 +234,7 @@ class ImageMedium extends Medium
|
||||
/**
|
||||
* Allows the ability to override the Inmage's Pretty name stored in cache
|
||||
*
|
||||
* @param $name
|
||||
* @param string $name
|
||||
*/
|
||||
public function setImagePrettyName($name)
|
||||
{
|
||||
@@ -263,8 +263,8 @@ class ImageMedium extends Medium
|
||||
* widths. Existing image alternatives won't be overwritten.
|
||||
*
|
||||
* @param int|int[] $min_width
|
||||
* @param int [$max_width=2500]
|
||||
* @param int [$step=200]
|
||||
* @param int $max_width
|
||||
* @param int $step
|
||||
* @return $this
|
||||
*/
|
||||
public function derivatives($min_width, $max_width = 2500, $step = 200)
|
||||
@@ -335,7 +335,7 @@ class ImageMedium extends Medium
|
||||
* Parsedown element for source display mode
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
public function sourceParsedownElement(array $attributes, $reset = true)
|
||||
@@ -378,7 +378,7 @@ class ImageMedium extends Medium
|
||||
/**
|
||||
* Turn the current Medium into a Link
|
||||
*
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @param array $attributes
|
||||
* @return Link
|
||||
*/
|
||||
@@ -398,7 +398,7 @@ class ImageMedium extends Medium
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return Link
|
||||
*/
|
||||
public function lightbox($width = null, $height = null, $reset = true)
|
||||
@@ -408,7 +408,7 @@ class ImageMedium extends Medium
|
||||
}
|
||||
|
||||
if ($width && $height) {
|
||||
$this->cropResize($width, $height);
|
||||
$this->__call('cropResize', [$width, $height]);
|
||||
}
|
||||
|
||||
return parent::lightbox($width, $height, $reset);
|
||||
@@ -418,7 +418,7 @@ class ImageMedium extends Medium
|
||||
* Sets or gets the quality of the image
|
||||
*
|
||||
* @param int $quality 0-100 quality
|
||||
* @return Medium
|
||||
* @return int|$this
|
||||
*/
|
||||
public function quality($quality = null)
|
||||
{
|
||||
@@ -619,7 +619,7 @@ class ImageMedium extends Medium
|
||||
$this->image->merge(ImageFile::open($overlay));
|
||||
}
|
||||
|
||||
return $this->image->cacheFile($this->format, $this->quality);
|
||||
return $this->image->cacheFile($this->format, $this->quality, false, [$this->get('width'), $this->get('height'), $this->get('modified')]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,7 +38,7 @@ class Link implements RenderableInterface
|
||||
* @param string $alt
|
||||
* @param string $class
|
||||
* @param string $id
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
public function parsedownElement($title = null, $alt = null, $class = null, $id = null, $reset = true)
|
||||
|
||||
@@ -16,6 +16,12 @@ use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Media\Interfaces\MediaObjectInterface;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
/**
|
||||
* Class Medium
|
||||
* @package Grav\Common\Page\Medium
|
||||
*
|
||||
* @property string $mime
|
||||
*/
|
||||
class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
{
|
||||
use ParsedownHtmlTrait;
|
||||
@@ -137,6 +143,20 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
return filemtime($path) ?: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function size()
|
||||
{
|
||||
$path = $this->get('filepath');
|
||||
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return filesize($path) ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set querystring to file modification timestamp (or value provided as a parameter).
|
||||
*
|
||||
@@ -163,7 +183,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
/**
|
||||
* Add meta file for the medium.
|
||||
*
|
||||
* @param $filepath
|
||||
* @param string $filepath
|
||||
*/
|
||||
public function addMetaFile($filepath)
|
||||
{
|
||||
@@ -174,7 +194,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
/**
|
||||
* Add alternative Medium to this Medium.
|
||||
*
|
||||
* @param $ratio
|
||||
* @param int|float $ratio
|
||||
* @param Medium $alternative
|
||||
*/
|
||||
public function addAlternative($ratio, Medium $alternative)
|
||||
@@ -262,7 +282,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
* Get/set querystring for the file's url
|
||||
*
|
||||
* @param string $querystring
|
||||
* @param boolean $withQuestionmark
|
||||
* @param bool $withQuestionmark
|
||||
* @return string
|
||||
*/
|
||||
public function querystring($querystring = null, $withQuestionmark = true)
|
||||
@@ -291,7 +311,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
/**
|
||||
* Get the URL with full querystring
|
||||
*
|
||||
* @param $url
|
||||
* @param string $url
|
||||
* @return string
|
||||
*/
|
||||
public function urlQuerystring($url)
|
||||
@@ -308,7 +328,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
* Get/set hash for the file's url
|
||||
*
|
||||
* @param string $hash
|
||||
* @param boolean $withHash
|
||||
* @param bool $withHash
|
||||
* @return string
|
||||
*/
|
||||
public function urlHash($hash = null, $withHash = true)
|
||||
@@ -329,7 +349,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
* @param string $alt
|
||||
* @param string $class
|
||||
* @param string $id
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
public function parsedownElement($title = null, $alt = null, $class = null, $id = null, $reset = true)
|
||||
@@ -393,6 +413,8 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
case 'source':
|
||||
$element = $this->sourceParsedownElement($attributes, false);
|
||||
break;
|
||||
default:
|
||||
$element = [];
|
||||
}
|
||||
|
||||
if ($reset) {
|
||||
@@ -408,7 +430,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
* Parsedown element for source display mode
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
protected function sourceParsedownElement(array $attributes, $reset = true)
|
||||
@@ -420,7 +442,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
* Parsedown element for text display mode
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
protected function textParsedownElement(array $attributes, $reset = true)
|
||||
@@ -512,7 +534,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
/**
|
||||
* Turn the current Medium into a Link
|
||||
*
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @param array $attributes
|
||||
* @return Link
|
||||
*/
|
||||
@@ -536,7 +558,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return Link
|
||||
*/
|
||||
public function lightbox($width = null, $height = null, $reset = true)
|
||||
@@ -571,7 +593,7 @@ class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
* Add an id to the element from Markdown or Twig
|
||||
* Example: 
|
||||
*
|
||||
* @param $id
|
||||
* @param string $id
|
||||
* @return $this
|
||||
*/
|
||||
public function id($id)
|
||||
|
||||
@@ -37,14 +37,14 @@ class MediumFactory
|
||||
$config = Grav::instance()['config'];
|
||||
|
||||
$media_params = $config->get('media.types.' . strtolower($ext));
|
||||
if (!$media_params) {
|
||||
if (!\is_array($media_params)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$params += $media_params;
|
||||
|
||||
// Add default settings for undefined variables.
|
||||
$params += $config->get('media.types.defaults');
|
||||
$params += (array)$config->get('media.types.defaults');
|
||||
$params += [
|
||||
'type' => 'file',
|
||||
'thumb' => 'media/thumb.png',
|
||||
@@ -87,14 +87,14 @@ class MediumFactory
|
||||
$config = Grav::instance()['config'];
|
||||
|
||||
$media_params = $config->get('media.types.' . strtolower($ext));
|
||||
if (!$media_params) {
|
||||
if (!\is_array($media_params)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$params += $media_params;
|
||||
|
||||
// Add default settings for undefined variables.
|
||||
$params += $config->get('media.types.defaults');
|
||||
$params += (array)$config->get('media.types.defaults');
|
||||
$params += [
|
||||
'type' => 'file',
|
||||
'thumb' => 'media/thumb.png',
|
||||
|
||||
@@ -17,7 +17,7 @@ class StaticImageMedium extends Medium
|
||||
* Parsedown element for source display mode
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
protected function sourceParsedownElement(array $attributes, $reset = true)
|
||||
|
||||
@@ -17,7 +17,7 @@ class ThumbnailImageMedium extends ImageMedium
|
||||
public $parent = null;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
* @var bool
|
||||
*/
|
||||
public $linked = false;
|
||||
|
||||
@@ -39,7 +39,7 @@ class ThumbnailImageMedium extends ImageMedium
|
||||
* @param string $alt
|
||||
* @param string $class
|
||||
* @param string $id
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
public function parsedownElement($title = null, $alt = null, $class = null, $id = null, $reset = true)
|
||||
@@ -91,7 +91,7 @@ class ThumbnailImageMedium extends ImageMedium
|
||||
/**
|
||||
* Turn the current Medium into a Link
|
||||
*
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @param array $attributes
|
||||
* @return Link
|
||||
*/
|
||||
@@ -105,7 +105,7 @@ class ThumbnailImageMedium extends ImageMedium
|
||||
*
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return Link
|
||||
*/
|
||||
public function lightbox($width = null, $height = null, $reset = true)
|
||||
@@ -118,7 +118,7 @@ class ThumbnailImageMedium extends ImageMedium
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $arguments
|
||||
* @param boolean $testLinked
|
||||
* @param bool $testLinked
|
||||
* @return Medium
|
||||
*/
|
||||
protected function bubble($method, array $arguments = [], $testLinked = true)
|
||||
|
||||
@@ -17,7 +17,7 @@ class VideoMedium extends Medium
|
||||
* Parsedown element for source display mode
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param boolean $reset
|
||||
* @param bool $reset
|
||||
* @return array
|
||||
*/
|
||||
protected function sourceParsedownElement(array $attributes, $reset = true)
|
||||
@@ -51,7 +51,7 @@ class VideoMedium extends Medium
|
||||
/**
|
||||
* Allows to set the video's poster image
|
||||
*
|
||||
* @param $urlImage
|
||||
* @param string $urlImage
|
||||
* @return $this
|
||||
*/
|
||||
public function poster($urlImage)
|
||||
|
||||
@@ -23,6 +23,7 @@ use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Yaml;
|
||||
use Negotiation\Accept;
|
||||
use Negotiation\Negotiator;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\File\MarkdownFile;
|
||||
@@ -96,7 +97,7 @@ class Page implements PageInterface
|
||||
protected $forms;
|
||||
|
||||
/**
|
||||
* @var Page Unmodified (original) version of the page. Used for copying and moving the page.
|
||||
* @var PageInterface Unmodified (original) version of the page. Used for copying and moving the page.
|
||||
*/
|
||||
private $_original;
|
||||
|
||||
@@ -345,7 +346,7 @@ class Page implements PageInterface
|
||||
$this->processFrontmatter();
|
||||
}
|
||||
}
|
||||
} catch (ParseException $e) {
|
||||
} catch (\Exception $e) {
|
||||
$file->raw(Grav::instance()['language']->translate([
|
||||
'GRAV.FRONTMATTER_ERROR_PAGE',
|
||||
$this->slug(),
|
||||
@@ -413,9 +414,7 @@ class Page implements PageInterface
|
||||
$this->markdown_extra = (bool)$this->header->markdown_extra;
|
||||
}
|
||||
if (isset($this->header->taxonomy)) {
|
||||
foreach ((array)$this->header->taxonomy as $taxonomy => $taxitems) {
|
||||
$this->taxonomy[$taxonomy] = (array)$taxitems;
|
||||
}
|
||||
$this->taxonomy($this->header->taxonomy);
|
||||
}
|
||||
if (isset($this->header->max_count)) {
|
||||
$this->max_count = (int)$this->header->max_count;
|
||||
@@ -466,7 +465,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Get page language
|
||||
*
|
||||
* @param $var
|
||||
* @param string $var
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -482,8 +481,8 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Modify a header value directly
|
||||
*
|
||||
* @param $key
|
||||
* @param $value
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function modifyHeader($key, $value)
|
||||
{
|
||||
@@ -548,7 +547,7 @@ class Page implements PageInterface
|
||||
*
|
||||
* @param int $size Max summary size.
|
||||
*
|
||||
* @param boolean $textOnly Only count text size.
|
||||
* @param bool $textOnly Only count text size.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -748,6 +747,8 @@ class Page implements PageInterface
|
||||
$this->content = str_replace("<p>{$delimiter}</p>", '', $this->content);
|
||||
}
|
||||
|
||||
// Fire event when Page::content() is called
|
||||
Grav::instance()->fireEvent('onPageContent', new Event(['page' => $this]));
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
@@ -770,8 +771,8 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Add an entry to the page's contentMeta array
|
||||
*
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public function addContentMeta($name, $value)
|
||||
{
|
||||
@@ -781,9 +782,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Return the whole contentMeta array as it currently stands
|
||||
*
|
||||
* @param null $name
|
||||
* @param string|null $name
|
||||
*
|
||||
* @return mixed
|
||||
* @return string
|
||||
*/
|
||||
public function getContentMeta($name = null)
|
||||
{
|
||||
@@ -801,9 +802,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Sets the whole content meta array in one shot
|
||||
*
|
||||
* @param $content_meta
|
||||
* @param array $content_meta
|
||||
*
|
||||
* @return mixed
|
||||
* @return array
|
||||
*/
|
||||
public function setContentMeta($content_meta)
|
||||
{
|
||||
@@ -873,7 +874,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Needed by the onPageContentProcessed event to set the raw page content
|
||||
*
|
||||
* @param $content
|
||||
* @param string $content
|
||||
*/
|
||||
public function setRawContent($content)
|
||||
{
|
||||
@@ -965,9 +966,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets and Sets the Page raw content
|
||||
*
|
||||
* @param null $var
|
||||
* @param string|null $var
|
||||
*
|
||||
* @return null
|
||||
* @return string
|
||||
*/
|
||||
public function rawMarkdown($var = null)
|
||||
{
|
||||
@@ -1023,11 +1024,11 @@ class Page implements PageInterface
|
||||
*
|
||||
* You need to call $this->save() in order to perform the move.
|
||||
*
|
||||
* @param Page $parent New parent page.
|
||||
* @param PageInterface $parent New parent page.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function move(Page $parent)
|
||||
public function move(PageInterface $parent)
|
||||
{
|
||||
if (!$this->_original) {
|
||||
$clone = clone $this;
|
||||
@@ -1067,11 +1068,11 @@ class Page implements PageInterface
|
||||
* Returns a new Page object for the copy.
|
||||
* You need to call $this->save() in order to perform the move.
|
||||
*
|
||||
* @param Page $parent New parent page.
|
||||
* @param PageInterface $parent New parent page.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function copy($parent)
|
||||
public function copy(PageInterface $parent)
|
||||
{
|
||||
$this->move($parent);
|
||||
$this->_action = 'copy';
|
||||
@@ -1240,6 +1241,9 @@ class Page implements PageInterface
|
||||
return $this->forms;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $new
|
||||
*/
|
||||
public function addForms(array $new)
|
||||
{
|
||||
// Initialize forms.
|
||||
@@ -1402,7 +1406,8 @@ class Page implements PageInterface
|
||||
$priorities = Utils::getMimeTypes($supported_types);
|
||||
|
||||
$media_type = $negotiator->getBest($http_accept, $priorities);
|
||||
$mimetype = $media_type ? $media_type->getValue() : '';
|
||||
$mimetype = $media_type instanceof Accept ? $media_type->getValue() : '';
|
||||
|
||||
$this->template_format = Utils::getExtensionByMime($mimetype);
|
||||
|
||||
return $this->template_format;
|
||||
@@ -1445,7 +1450,7 @@ class Page implements PageInterface
|
||||
}
|
||||
|
||||
// if not set in the page get the value from system config
|
||||
if (empty($this->url_extension)) {
|
||||
if (null === $this->url_extension) {
|
||||
$this->url_extension = Grav::instance()['config']->get('system.pages.append_url_extension', '');
|
||||
}
|
||||
|
||||
@@ -1737,6 +1742,14 @@ class Page implements PageInterface
|
||||
return $this->metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the metadata and pull from header again
|
||||
*/
|
||||
public function resetMetadata()
|
||||
{
|
||||
$this->metadata = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and Sets the slug for the Page. The slug is used in the URL routing. If not set it uses
|
||||
* the parent folder from the path
|
||||
@@ -2033,9 +2046,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets and sets the option to show the etag header for the page.
|
||||
*
|
||||
* @param boolean $var show etag header
|
||||
* @param bool $var show etag header
|
||||
*
|
||||
* @return boolean show etag header
|
||||
* @return bool show etag header
|
||||
*/
|
||||
public function eTag($var = null)
|
||||
{
|
||||
@@ -2052,9 +2065,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets and sets the option to show the last_modified header for the page.
|
||||
*
|
||||
* @param boolean $var show last_modified header
|
||||
* @param bool $var show last_modified header
|
||||
*
|
||||
* @return boolean show last_modified header
|
||||
* @return bool show last_modified header
|
||||
*/
|
||||
public function lastModified($var = null)
|
||||
{
|
||||
@@ -2186,9 +2199,12 @@ class Page implements PageInterface
|
||||
* @param string $var the order, either "asc" or "desc"
|
||||
*
|
||||
* @return string the order, either "asc" or "desc"
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function orderDir($var = null)
|
||||
{
|
||||
//user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED);
|
||||
|
||||
if ($var !== null) {
|
||||
$this->order_dir = $var;
|
||||
}
|
||||
@@ -2211,9 +2227,12 @@ class Page implements PageInterface
|
||||
* @param string $var supported options include "default", "title", "date", and "folder"
|
||||
*
|
||||
* @return string supported options include "default", "title", "date", and "folder"
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function orderBy($var = null)
|
||||
{
|
||||
//user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED);
|
||||
|
||||
if ($var !== null) {
|
||||
$this->order_by = $var;
|
||||
}
|
||||
@@ -2227,9 +2246,12 @@ class Page implements PageInterface
|
||||
* @param string $var supported options include "default", "title", "date", and "folder"
|
||||
*
|
||||
* @return array
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function orderManual($var = null)
|
||||
{
|
||||
//user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED);
|
||||
|
||||
if ($var !== null) {
|
||||
$this->order_manual = $var;
|
||||
}
|
||||
@@ -2244,9 +2266,12 @@ class Page implements PageInterface
|
||||
* @param int $var the maximum number of sub-pages
|
||||
*
|
||||
* @return int the maximum number of sub-pages
|
||||
* @deprecated 1.6
|
||||
*/
|
||||
public function maxCount($var = null)
|
||||
{
|
||||
//user_error(__CLASS__ . '::' . __FUNCTION__ . '() is deprecated since Grav 1.6', E_USER_DEPRECATED);
|
||||
|
||||
if ($var !== null) {
|
||||
$this->max_count = (int)$var;
|
||||
}
|
||||
@@ -2269,6 +2294,14 @@ class Page implements PageInterface
|
||||
public function taxonomy($var = null)
|
||||
{
|
||||
if ($var !== null) {
|
||||
// make sure first level are arrays
|
||||
array_walk($var, function(&$value) {
|
||||
$value = (array) $value;
|
||||
});
|
||||
// make sure all values are strings
|
||||
array_walk_recursive($var, function(&$value) {
|
||||
$value = (string) $value;
|
||||
});
|
||||
$this->taxonomy = $var;
|
||||
}
|
||||
|
||||
@@ -2326,11 +2359,11 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets and Sets the parent object for this page
|
||||
*
|
||||
* @param Page $var the parent page object
|
||||
* @param PageInterface $var the parent page object
|
||||
*
|
||||
* @return Page|null the parent page object if it exists.
|
||||
* @return PageInterface|null the parent page object if it exists.
|
||||
*/
|
||||
public function parent(Page $var = null)
|
||||
public function parent(PageInterface $var = null)
|
||||
{
|
||||
if ($var) {
|
||||
$this->parent = $var->path();
|
||||
@@ -2347,7 +2380,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets the top parent object for this page
|
||||
*
|
||||
* @return Page|null the top parent page object if it exists.
|
||||
* @return PageInterface|null the top parent page object if it exists.
|
||||
*/
|
||||
public function topParent()
|
||||
{
|
||||
@@ -2372,7 +2405,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Returns children of this page.
|
||||
*
|
||||
* @return \Grav\Common\Page\Collection
|
||||
* @return Collection
|
||||
*/
|
||||
public function children()
|
||||
{
|
||||
@@ -2386,7 +2419,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Check to see if this item is the first in an array of sub-pages.
|
||||
*
|
||||
* @return boolean True if item is first.
|
||||
* @return bool True if item is first.
|
||||
*/
|
||||
public function isFirst()
|
||||
{
|
||||
@@ -2402,7 +2435,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Check to see if this item is the last in an array of sub-pages.
|
||||
*
|
||||
* @return boolean True if item is last
|
||||
* @return bool True if item is last
|
||||
*/
|
||||
public function isLast()
|
||||
{
|
||||
@@ -2418,7 +2451,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets the previous sibling based on current position.
|
||||
*
|
||||
* @return Page the previous Page item
|
||||
* @return PageInterface the previous Page item
|
||||
*/
|
||||
public function prevSibling()
|
||||
{
|
||||
@@ -2428,7 +2461,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets the next sibling based on current position.
|
||||
*
|
||||
* @return Page the next Page item
|
||||
* @return PageInterface the next Page item
|
||||
*/
|
||||
public function nextSibling()
|
||||
{
|
||||
@@ -2438,9 +2471,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Returns the adjacent sibling based on a direction.
|
||||
*
|
||||
* @param integer $direction either -1 or +1
|
||||
* @param int $direction either -1 or +1
|
||||
*
|
||||
* @return Page|bool the sibling page
|
||||
* @return PageInterface|bool the sibling page
|
||||
*/
|
||||
public function adjacentSibling($direction = 1)
|
||||
{
|
||||
@@ -2456,9 +2489,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Returns the item in the current position.
|
||||
*
|
||||
* @param string $path the path the item
|
||||
*
|
||||
* @return Integer the index of the current page.
|
||||
* @return int the index of the current page.
|
||||
*/
|
||||
public function currentPosition()
|
||||
{
|
||||
@@ -2468,7 +2499,7 @@ class Page implements PageInterface
|
||||
return $collection->currentPosition($this->path());
|
||||
}
|
||||
|
||||
return true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2498,7 +2529,7 @@ class Page implements PageInterface
|
||||
$routes = Grav::instance()['pages']->routes();
|
||||
|
||||
if (isset($routes[$uri_path])) {
|
||||
/** @var Page $child_page */
|
||||
/** @var PageInterface $child_page */
|
||||
$child_page = $pages->dispatch($uri->route())->parent();
|
||||
if ($child_page) {
|
||||
while (!$child_page->root()) {
|
||||
@@ -2538,10 +2569,9 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Helper method to return an ancestor page.
|
||||
*
|
||||
* @param string $url The url of the page
|
||||
* @param bool $lookup Name of the parent folder
|
||||
*
|
||||
* @return \Grav\Common\Page\Page page you were looking for if it exists
|
||||
* @return PageInterface page you were looking for if it exists
|
||||
*/
|
||||
public function ancestor($lookup = null)
|
||||
{
|
||||
@@ -2557,7 +2587,7 @@ class Page implements PageInterface
|
||||
*
|
||||
* @param string $field Name of the parent folder
|
||||
*
|
||||
* @return Page
|
||||
* @return PageInterface
|
||||
*/
|
||||
public function inherited($field)
|
||||
{
|
||||
@@ -2611,7 +2641,7 @@ class Page implements PageInterface
|
||||
* @param string $url the url of the page
|
||||
* @param bool $all
|
||||
*
|
||||
* @return \Grav\Common\Page\Page page you were looking for if it exists
|
||||
* @return PageInterface page you were looking for if it exists
|
||||
*/
|
||||
public function find($url, $all = false)
|
||||
{
|
||||
@@ -2625,7 +2655,7 @@ class Page implements PageInterface
|
||||
* Get a collection of pages in the current context.
|
||||
*
|
||||
* @param string|array $params
|
||||
* @param boolean $pagination
|
||||
* @param bool $pagination
|
||||
*
|
||||
* @return Collection
|
||||
* @throws \InvalidArgumentException
|
||||
@@ -3016,7 +3046,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Reorders all siblings according to a defined order
|
||||
*
|
||||
* @param $new_order
|
||||
* @param array|null $new_order
|
||||
*/
|
||||
protected function doReorder($new_order)
|
||||
{
|
||||
@@ -3122,8 +3152,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets the Page Unmodified (original) version of the page.
|
||||
*
|
||||
* @return Page
|
||||
* The original version of the page.
|
||||
* @return PageInterface The original version of the page.
|
||||
*/
|
||||
public function getOriginal()
|
||||
{
|
||||
@@ -3133,8 +3162,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* Gets the action.
|
||||
*
|
||||
* @return string
|
||||
* The Action string.
|
||||
* @return string The Action string.
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ use Grav\Common\Data\Blueprints;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
@@ -33,7 +34,7 @@ class Pages
|
||||
protected $grav;
|
||||
|
||||
/**
|
||||
* @var array|Page[]
|
||||
* @var array|PageInterface[]
|
||||
*/
|
||||
protected $instances;
|
||||
|
||||
@@ -261,7 +262,7 @@ class Pages
|
||||
/**
|
||||
* Returns a list of all pages.
|
||||
*
|
||||
* @return array|Page[]
|
||||
* @return array|PageInterface[]
|
||||
*/
|
||||
public function instances()
|
||||
{
|
||||
@@ -281,10 +282,10 @@ class Pages
|
||||
/**
|
||||
* Adds a page and assigns a route to it.
|
||||
*
|
||||
* @param Page $page Page to be added.
|
||||
* @param PageInterface $page Page to be added.
|
||||
* @param string $route Optional route (uses route from the object if not set).
|
||||
*/
|
||||
public function addPage(Page $page, $route = null)
|
||||
public function addPage(PageInterface $page, $route = null)
|
||||
{
|
||||
if (!isset($this->instances[$page->path()])) {
|
||||
$this->instances[$page->path()] = $page;
|
||||
@@ -301,13 +302,13 @@ class Pages
|
||||
/**
|
||||
* Sort sub-pages in a page.
|
||||
*
|
||||
* @param Page $page
|
||||
* @param PageInterface $page
|
||||
* @param string $order_by
|
||||
* @param string $order_dir
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function sort(Page $page, $order_by = null, $order_dir = null, $sort_flags = null)
|
||||
public function sort(PageInterface $page, $order_by = null, $order_dir = null, $sort_flags = null)
|
||||
{
|
||||
if ($order_by === null) {
|
||||
$order_by = $page->orderBy();
|
||||
@@ -338,10 +339,10 @@ class Pages
|
||||
|
||||
/**
|
||||
* @param Collection $collection
|
||||
* @param $orderBy
|
||||
* @param string|int $orderBy
|
||||
* @param string $orderDir
|
||||
* @param null $orderManual
|
||||
* @param null $sort_flags
|
||||
* @param array|null $orderManual
|
||||
* @param int|null $sort_flags
|
||||
*
|
||||
* @return array
|
||||
* @internal
|
||||
@@ -373,7 +374,7 @@ class Pages
|
||||
*
|
||||
* @param string $path The filesystem full path of the page
|
||||
*
|
||||
* @return Page
|
||||
* @return PageInterface
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function get($path)
|
||||
@@ -401,7 +402,7 @@ class Pages
|
||||
* @param string $route The relative URL of the page
|
||||
* @param string $path The relative path of the ancestor folder
|
||||
*
|
||||
* @return Page|null
|
||||
* @return PageInterface|null
|
||||
*/
|
||||
public function ancestor($route, $path = null)
|
||||
{
|
||||
@@ -427,7 +428,7 @@ class Pages
|
||||
* @param string $route The relative route of the page
|
||||
* @param string $field The field name of the ancestor to query for
|
||||
*
|
||||
* @return Page|null
|
||||
* @return PageInterface|null
|
||||
*/
|
||||
public function inherited($route, $field = null)
|
||||
{
|
||||
@@ -453,7 +454,7 @@ class Pages
|
||||
* @param string $route The relative URL of the page
|
||||
* @param bool $all
|
||||
*
|
||||
* @return Page|null
|
||||
* @return PageInterface|null
|
||||
*/
|
||||
public function find($route, $all = false)
|
||||
{
|
||||
@@ -467,7 +468,7 @@ class Pages
|
||||
* @param bool $all
|
||||
*
|
||||
* @param bool $redirect
|
||||
* @return Page|null
|
||||
* @return PageInterface|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function dispatch($route, $all = false, $redirect = true)
|
||||
@@ -549,7 +550,7 @@ class Pages
|
||||
/**
|
||||
* Get root page.
|
||||
*
|
||||
* @return Page
|
||||
* @return PageInterface
|
||||
*/
|
||||
public function root()
|
||||
{
|
||||
@@ -589,15 +590,15 @@ class Pages
|
||||
/**
|
||||
* Get all pages
|
||||
*
|
||||
* @param \Grav\Common\Page\Page $current
|
||||
* @param PageInterface $current
|
||||
*
|
||||
* @return \Grav\Common\Page\Collection
|
||||
*/
|
||||
public function all(Page $current = null)
|
||||
public function all(PageInterface $current = null)
|
||||
{
|
||||
$all = new Collection();
|
||||
|
||||
/** @var Page $current */
|
||||
/** @var PageInterface $current */
|
||||
$current = $current ?: $this->root();
|
||||
|
||||
if (!$current->root()) {
|
||||
@@ -659,7 +660,7 @@ class Pages
|
||||
/**
|
||||
* Get list of route/title of all pages.
|
||||
*
|
||||
* @param Page $current
|
||||
* @param PageInterface $current
|
||||
* @param int $level
|
||||
* @param bool $rawRoutes
|
||||
*
|
||||
@@ -670,7 +671,7 @@ class Pages
|
||||
* @param bool $limitLevels
|
||||
* @return array
|
||||
*/
|
||||
public function getList(Page $current = null, $level = 0, $rawRoutes = false, $showAll = true, $showFullpath = false, $showSlug = false, $showModular = false, $limitLevels = false)
|
||||
public function getList(PageInterface $current = null, $level = 0, $rawRoutes = false, $showAll = true, $showFullpath = false, $showSlug = false, $showModular = false, $limitLevels = false)
|
||||
{
|
||||
if (!$current) {
|
||||
if ($level) {
|
||||
@@ -811,7 +812,7 @@ class Pages
|
||||
/** @var Admin $admin */
|
||||
$admin = Grav::instance()['admin'];
|
||||
|
||||
/** @var Page $page */
|
||||
/** @var PageInterface $page */
|
||||
$page = $admin->getPage($admin->route);
|
||||
|
||||
if ($page && $page->modular()) {
|
||||
@@ -984,7 +985,7 @@ class Pages
|
||||
/**
|
||||
* Accessible method to manually reset the pages cache
|
||||
*
|
||||
* @param $pages_dir
|
||||
* @param string $pages_dir
|
||||
*/
|
||||
public function resetPages($pages_dir)
|
||||
{
|
||||
@@ -1007,13 +1008,13 @@ class Pages
|
||||
* Recursive function to load & build page relationships.
|
||||
*
|
||||
* @param string $directory
|
||||
* @param Page|null $parent
|
||||
* @param PageInterface|null $parent
|
||||
*
|
||||
* @return Page
|
||||
* @return PageInterface
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
*/
|
||||
protected function recurse($directory, Page $parent = null)
|
||||
protected function recurse($directory, PageInterface $parent = null)
|
||||
{
|
||||
$directory = rtrim($directory, DS);
|
||||
$page = new Page;
|
||||
@@ -1179,14 +1180,14 @@ class Pages
|
||||
*/
|
||||
protected function buildRoutes()
|
||||
{
|
||||
/** @var $taxonomy Taxonomy */
|
||||
/** @var Taxonomy $taxonomy */
|
||||
$taxonomy = $this->grav['taxonomy'];
|
||||
|
||||
// Get the home route
|
||||
$home = self::resetHomeRoute();
|
||||
|
||||
// Build routes and taxonomy map.
|
||||
/** @var $page Page */
|
||||
/** @var PageInterface $page */
|
||||
foreach ($this->instances as $page) {
|
||||
if (!$page->root()) {
|
||||
// process taxonomy
|
||||
@@ -1232,8 +1233,8 @@ class Pages
|
||||
* @param string $path
|
||||
* @param array $pages
|
||||
* @param string $order_by
|
||||
* @param array $manual
|
||||
* @param int $sort_flags
|
||||
* @param array|null $manual
|
||||
* @param int|null $sort_flags
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @internal
|
||||
|
||||
@@ -9,8 +9,9 @@
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Config\Config;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
use RocketTheme\Toolbox\Event\EventSubscriberInterface;
|
||||
@@ -120,7 +121,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Determine if this route is in Admin and active for the plugin
|
||||
*
|
||||
* @param $plugin_route
|
||||
* @param string $plugin_route
|
||||
* @return bool
|
||||
*/
|
||||
protected function isPluginActiveAdmin($plugin_route)
|
||||
@@ -183,7 +184,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Whether or not an offset exists.
|
||||
*
|
||||
* @param mixed $offset An offset to check for.
|
||||
* @param string $offset An offset to check for.
|
||||
* @return bool Returns TRUE on success or FALSE on failure.
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
@@ -199,7 +200,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Returns the value at specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to retrieve.
|
||||
* @param string $offset The offset to retrieve.
|
||||
* @return mixed Can return all value types.
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
@@ -215,7 +216,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Assigns a value to the specified offset.
|
||||
*
|
||||
* @param mixed $offset The offset to assign the value to.
|
||||
* @param string $offset The offset to assign the value to.
|
||||
* @param mixed $value The value to set.
|
||||
* @throws \LogicException
|
||||
*/
|
||||
@@ -227,7 +228,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Unsets an offset.
|
||||
*
|
||||
* @param mixed $offset The offset to unset.
|
||||
* @param string $offset The offset to unset.
|
||||
* @throws \LogicException
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
@@ -258,7 +259,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Merge global and page configurations.
|
||||
*
|
||||
* @param Page $page The page to merge the configurations with the
|
||||
* @param PageInterface $page The page to merge the configurations with the
|
||||
* plugin settings.
|
||||
* @param mixed $deep false = shallow|true = recursive|merge = recursive+unique
|
||||
* @param array $params Array of additional configuration options to
|
||||
@@ -267,7 +268,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
*
|
||||
* @return Data
|
||||
*/
|
||||
protected function mergeConfig(Page $page, $deep = false, $params = [], $type = 'plugins')
|
||||
protected function mergeConfig(PageInterface $page, $deep = false, $params = [], $type = 'plugins')
|
||||
{
|
||||
$class_name = $this->name;
|
||||
$class_name_merged = $class_name . '.merged';
|
||||
@@ -304,12 +305,12 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Merge arrays based on deepness
|
||||
*
|
||||
* @param bool $deep
|
||||
* @param $array1
|
||||
* @param $array2
|
||||
* @return array|mixed
|
||||
* @param string|bool $deep
|
||||
* @param array $array1
|
||||
* @param array $array2
|
||||
* @return array
|
||||
*/
|
||||
private function mergeArrays($deep = false, $array1, $array2)
|
||||
private function mergeArrays($deep, $array1, $array2)
|
||||
{
|
||||
if ($deep === 'merge') {
|
||||
return Utils::arrayMergeRecursiveUnique($array1, $array2);
|
||||
@@ -326,7 +327,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
*
|
||||
* @param string $plugin_name The name of the plugin whose config it should store.
|
||||
*
|
||||
* @return true
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveConfig($plugin_name)
|
||||
{
|
||||
@@ -348,7 +349,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
/**
|
||||
* Simpler getter for the plugin blueprint
|
||||
*
|
||||
* @return mixed
|
||||
* @return Blueprint
|
||||
*/
|
||||
public function getBlueprint()
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ class Plugins extends Iterator
|
||||
/**
|
||||
* Registers all plugins.
|
||||
*
|
||||
* @return array|Plugin[] array of Plugin objects
|
||||
* @return Plugin[] array of Plugin objects
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public function init()
|
||||
@@ -117,7 +117,7 @@ class Plugins extends Iterator
|
||||
/**
|
||||
* Add a plugin
|
||||
*
|
||||
* @param $plugin
|
||||
* @param Plugin $plugin
|
||||
*/
|
||||
public function add($plugin)
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace Grav\Common\Processors;
|
||||
|
||||
use Grav\Framework\Psr7\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
@@ -25,5 +26,6 @@ class DebuggerAssetsProcessor extends ProcessorBase
|
||||
$this->stopTimer();
|
||||
|
||||
return $handler->handle($request);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
class DebuggerInitProcessor extends ProcessorBase
|
||||
class DebuggerProcessor extends ProcessorBase
|
||||
{
|
||||
public $id = '_debugger';
|
||||
public $title = 'Init Debugger';
|
||||
@@ -46,7 +46,7 @@ class InitializeProcessor extends ProcessorBase
|
||||
// FIXME: Initialize session should happen later after plugins have been loaded. This is a workaround to fix session issues in AWS.
|
||||
if (isset($this->container['session']) && $config->get('system.session.initialize', true)) {
|
||||
// TODO: remove in 2.0.
|
||||
$this->container['users'];
|
||||
$this->container['accounts'];
|
||||
|
||||
try {
|
||||
$this->container['session']->init();
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace Grav\Common\Processors;
|
||||
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
@@ -31,12 +31,14 @@ class PagesProcessor extends ProcessorBase
|
||||
$this->container->fireEvent('onPagesInitialized', new Event(['pages' => $this->container['pages']]));
|
||||
$this->container->fireEvent('onPageInitialized', new Event(['page' => $this->container['page']]));
|
||||
|
||||
/** @var Page $page */
|
||||
/** @var PageInterface $page */
|
||||
$page = $this->container['page'];
|
||||
|
||||
if (!$page->routable()) {
|
||||
// If no page found, fire event
|
||||
$event = $this->container->fireEvent('onPageNotFound', new Event(['page' => $page]));
|
||||
$event = new Event(['page' => $page]);
|
||||
$event->page = null;
|
||||
$event = $this->container->fireEvent('onPageNotFound', $event);
|
||||
|
||||
if (isset($event->page)) {
|
||||
unset ($this->container['page']);
|
||||
|
||||
@@ -22,7 +22,7 @@ class PluginsProcessor extends ProcessorBase
|
||||
{
|
||||
$this->startTimer();
|
||||
// TODO: remove in 2.0.
|
||||
$this->container['users'];
|
||||
$this->container['accounts'];
|
||||
$this->container['plugins']->init();
|
||||
$this->container->fireEvent('onPluginsInitialized');
|
||||
$this->stopTimer();
|
||||
|
||||
@@ -17,6 +17,9 @@ abstract class ProcessorBase implements ProcessorInterface
|
||||
/** @var Grav */
|
||||
protected $container;
|
||||
|
||||
public $id = 'processorbase';
|
||||
public $title = 'ProcessorBase';
|
||||
|
||||
public function __construct(Grav $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace Grav\Common\Processors;
|
||||
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Framework\Psr7\Response;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
@@ -37,9 +37,6 @@ class RenderProcessor extends ProcessorBase
|
||||
$container->output = $output;
|
||||
$container->fireEvent('onOutputGenerated');
|
||||
|
||||
// Set the header type
|
||||
$container->header();
|
||||
|
||||
echo $container->output;
|
||||
|
||||
// remove any output
|
||||
@@ -49,7 +46,7 @@ class RenderProcessor extends ProcessorBase
|
||||
|
||||
$html = ob_get_clean();
|
||||
|
||||
/** @var Page $page */
|
||||
/** @var PageInterface $page */
|
||||
$page = $this->container['page'];
|
||||
$this->stopTimer();
|
||||
|
||||
|
||||
@@ -23,8 +23,16 @@ class RequestProcessor extends ProcessorBase
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
|
||||
{
|
||||
$this->startTimer();
|
||||
|
||||
$header = $request->getHeaderLine('Content-Type');
|
||||
$type = trim(strstr($header, ';', true) ?: $header);
|
||||
if ($type === 'application/json') {
|
||||
$request = $request->withParsedBody(json_decode($request->getBody()->getContents(), true));
|
||||
}
|
||||
|
||||
$request = $request
|
||||
->withAttribute('grav', $this->container)
|
||||
->withAttribute('time', $_SERVER['REQUEST_TIME_FLOAT'] ?? GRAV_REQUEST_TIME)
|
||||
->withAttribute('route', Uri::getCurrentRoute())
|
||||
->withAttribute('referrer', $this->container['uri']->referrer());
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ class Cron
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $cron
|
||||
* @param string|null $cron
|
||||
*/
|
||||
public function __construct($cron = null)
|
||||
{
|
||||
@@ -459,7 +459,7 @@ class Cron
|
||||
|
||||
/**
|
||||
*
|
||||
* @param int|string|\Datetime $date
|
||||
* @param int|string|\DateTime $date
|
||||
*/
|
||||
public function matchExact($date)
|
||||
{
|
||||
@@ -476,7 +476,7 @@ class Cron
|
||||
|
||||
/**
|
||||
*
|
||||
* @param int|string|\Datetime $date
|
||||
* @param int|string|\DateTime $date
|
||||
* @param int $minuteBefore
|
||||
* @param int $minuteAfter
|
||||
*/
|
||||
|
||||
@@ -175,7 +175,7 @@ class Job
|
||||
/**
|
||||
* Force the Job to run in foreground.
|
||||
*
|
||||
* @return self
|
||||
* @return $this
|
||||
*/
|
||||
public function inForeground()
|
||||
{
|
||||
@@ -187,7 +187,7 @@ class Job
|
||||
/**
|
||||
* Sets/Gets an option backlink
|
||||
*
|
||||
* @param $link string
|
||||
* @param string $link
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
@@ -298,7 +298,6 @@ class Job
|
||||
if (is_callable($this->command)) {
|
||||
$this->output = $this->exec();
|
||||
} else {
|
||||
/** @var Process process */
|
||||
$args = \is_string($this->args) ? $this->args : implode(' ', $this->args);
|
||||
$command = $this->command . ' ' . $args;
|
||||
$process = new Process($command);
|
||||
|
||||
@@ -106,7 +106,6 @@ class Scheduler
|
||||
/**
|
||||
* Get all jobs if they are disabled or not as one array
|
||||
*
|
||||
* @param bool $all
|
||||
* @return array
|
||||
*/
|
||||
public function getAllJobs()
|
||||
@@ -151,10 +150,9 @@ class Scheduler
|
||||
/**
|
||||
* Run the scheduler.
|
||||
*
|
||||
* @param \DateTime $runTime Optional, run at specific moment
|
||||
* @return array Executed jobs
|
||||
* @param \DateTime|null $runTime Optional, run at specific moment
|
||||
*/
|
||||
public function run(\Datetime $runTime = null)
|
||||
public function run(\DateTime $runTime = null)
|
||||
{
|
||||
$this->loadSavedJobs();
|
||||
|
||||
@@ -236,7 +234,7 @@ class Scheduler
|
||||
{
|
||||
$phpBinaryFinder = new PhpExecutableFinder();
|
||||
$php = $phpBinaryFinder->find();
|
||||
$command = 'cd ' . GRAV_ROOT . ';' . $php . ' bin/grav scheduler';
|
||||
$command = 'cd ' . str_replace(' ', '\ ', GRAV_ROOT) . ';' . $php . ' bin/grav scheduler';
|
||||
|
||||
return "(crontab -l; echo \"* * * * * {$command} 1>> /dev/null 2>&1\") | crontab -";
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ class Security
|
||||
* their content.
|
||||
*
|
||||
* @param string $string The string to run XSS detection logic on
|
||||
* @return boolean|string Type of XSS vector if the given `$string` may contain XSS, false otherwise.
|
||||
* @return bool|string Type of XSS vector if the given `$string` may contain XSS, false otherwise.
|
||||
*
|
||||
* Copies the code from: https://github.com/symphonycms/xssfilter/blob/master/extension.driver.php#L138
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
namespace Grav\Common\Service;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Debugger;
|
||||
use Grav\Common\User\DataUser;
|
||||
use Grav\Common\User\FlexUser;
|
||||
use Grav\Common\User\User;
|
||||
@@ -21,20 +22,29 @@ use Pimple\ServiceProviderInterface;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\Event\EventDispatcher;
|
||||
|
||||
class UserServiceProvider implements ServiceProviderInterface
|
||||
class AccountsServiceProvider implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container['users'] = function (Container $container) {
|
||||
$container['accounts'] = function (Container $container) {
|
||||
/** @var Debugger $debugger */
|
||||
$debugger = $container['debugger'];
|
||||
if ($container['config']->get('system.accounts.type') === 'flex') {
|
||||
return $this->flexUsers($container);
|
||||
$debugger->addMessage('User Accounts: Flex Directory');
|
||||
return $this->flexAccounts($container);
|
||||
}
|
||||
|
||||
return $this->dataUsers($container);
|
||||
return $this->dataAccounts($container);
|
||||
};
|
||||
|
||||
$container['users'] = $container->factory(function (Container $container) {
|
||||
user_error('Grav::instance()[\'users\'] is deprecated since Grav 1.6, use Grav::instance()[\'accounts\'] instead', E_USER_DEPRECATED);
|
||||
|
||||
return $container['accounts'];
|
||||
});
|
||||
}
|
||||
|
||||
protected function dataUsers(Container $container)
|
||||
protected function dataAccounts(Container $container)
|
||||
{
|
||||
define('GRAV_USER_INSTANCE', 'DATA');
|
||||
|
||||
@@ -42,7 +52,7 @@ class UserServiceProvider implements ServiceProviderInterface
|
||||
return new DataUser\UserCollection(User::class);
|
||||
}
|
||||
|
||||
protected function flexUsers(Container $container)
|
||||
protected function flexAccounts(Container $container)
|
||||
{
|
||||
define('GRAV_USER_INSTANCE', 'FLEX');
|
||||
|
||||
@@ -55,11 +65,20 @@ class UserServiceProvider implements ServiceProviderInterface
|
||||
'object' => User::class, // Use User class for backwards compatibility.
|
||||
'collection' => FlexUser\UserCollection::class,
|
||||
'index' => FlexUser\UserIndex::class,
|
||||
'storage' => $this->getFlexStorage($config->get('system.accounts.storage', 'file'))
|
||||
'storage' => $this->getFlexStorage($config->get('system.accounts.storage', 'file')),
|
||||
'search' => [
|
||||
'options' => [
|
||||
'contains' => 1
|
||||
],
|
||||
'fields' => [
|
||||
'key',
|
||||
'email'
|
||||
]
|
||||
]
|
||||
]
|
||||
] + ($config->get('plugins.flex-objects.object') ?: []);
|
||||
|
||||
$directory = new FlexDirectory('users', 'blueprints://user/users.yaml', $options);
|
||||
$directory = new FlexDirectory('accounts', 'blueprints://user/accounts.yaml', $options);
|
||||
|
||||
/** @var EventDispatcher $dispatcher */
|
||||
$dispatcher = $container['events'];
|
||||
@@ -85,8 +104,9 @@ class UserServiceProvider implements ServiceProviderInterface
|
||||
'formatter' => ['class' => YamlFormatter::class],
|
||||
'folder' => 'account://',
|
||||
'pattern' => '{FOLDER}/{KEY:2}/{KEY}/user.yaml',
|
||||
'key' => 'username',
|
||||
'indexed' => true
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -96,8 +116,9 @@ class UserServiceProvider implements ServiceProviderInterface
|
||||
'formatter' => ['class' => YamlFormatter::class],
|
||||
'folder' => 'account://',
|
||||
'pattern' => '{FOLDER}/{KEY}.yaml',
|
||||
'key' => 'storage_key',
|
||||
'indexed' => true
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use Grav\Common\Config\CompiledLanguages;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Config\ConfigFileFinder;
|
||||
use Grav\Common\Config\Setup;
|
||||
use Grav\Common\Language\Language;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
@@ -25,7 +26,10 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
public function register(Container $container)
|
||||
{
|
||||
$container['setup'] = function ($c) {
|
||||
return static::setup($c);
|
||||
$setup = new Setup($c);
|
||||
$setup->init();
|
||||
|
||||
return $setup;
|
||||
};
|
||||
|
||||
$container['blueprints'] = function ($c) {
|
||||
@@ -46,11 +50,10 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
$container['languages'] = function ($c) {
|
||||
return static::languages($c);
|
||||
};
|
||||
}
|
||||
|
||||
public static function setup(Container $container)
|
||||
{
|
||||
return new Setup($container);
|
||||
$container['language'] = function ($c) {
|
||||
return new Language($c);
|
||||
};
|
||||
}
|
||||
|
||||
public static function blueprints(Container $container)
|
||||
@@ -137,8 +140,8 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
/**
|
||||
* Find specific paths in plugins
|
||||
*
|
||||
* @param $plugins
|
||||
* @param $folder_path
|
||||
* @param array $plugins
|
||||
* @param string $folder_path
|
||||
* @return array
|
||||
*/
|
||||
private static function pluginFolderPaths($plugins, $folder_path)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user