tagert blank & background flex

This commit is contained in:
2021-04-11 13:53:11 +02:00
parent 16117309f3
commit 0ae1e837e7
59 changed files with 561 additions and 382 deletions
+17
View File
@@ -1,3 +1,20 @@
# v1.7.10
## 04/06/2021
1. [](#new)
* Added initial support for running Grav library from outside the webroot [#3297](https://github.com/getgrav/grav/issues/3297)
1. [](#improved)
* Improved password handling when saving a user
1. [](#bugfix)
* Ignore errors when using `set_time_limit` in `Archiver` and `GPM\Response` classes [#3023](https://github.com/getgrav/grav/issues/3023)
* Fixed `Folder::move()` deleting the folder if you move folder into itself, created empty file instead
* Fixed moving `Flex Page` to itself causing the page to be lost [#3227](https://github.com/getgrav/grav/issues/3227)
* Fixed `PageStorage` from detecting files as pages
* Fixed `UserIndex` not implementing `UserCollectionInterface`
* Fixed missing `onAdminAfterDelete` event call in `Flex Pages`
* Fixed system templates not getting scanned [#3296](https://github.com/getgrav/grav/issues/3296)
* Fixed incorrect routing if url path looks like a domain name [#2184](https://github.com/getgrav/grav/issues/2184)
# v1.7.9 # v1.7.9
## 03/19/2021 ## 03/19/2021
+53 -42
View File
@@ -5,7 +5,19 @@
[![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org) [![Discord](https://img.shields.io/discord/501836936584101899.svg?logo=discord&colorB=728ADA&label=Discord%20Chat)](https://chat.getgrav.org)
[![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/grav/sponsors/badge.svg)](#sponsors) [![PHP Tests](https://github.com/getgrav/grav/workflows/PHP%20Tests/badge.svg?branch=develop)](https://github.com/getgrav/grav/actions?query=workflow%3A%22PHP+Tests%22) [![OpenCollective](https://opencollective.com/grav/backers/badge.svg)](#backers) [![OpenCollective](https://opencollective.com/grav/sponsors/badge.svg)](#sponsors)
Grav is a **Fast**, **Simple**, and **Flexible**, file-based Web-platform. There is **Zero** installation required. Just extract the ZIP archive, and you are already up and running. It follows similar principles to other flat-file CMS platforms, but has a different design philosophy than most. Grav comes with a powerful **Package Management System** to allow for simple installation and upgrading of plugins and themes, as well as simple updating of Grav itself.
The underlying architecture of Grav is designed to use well-established and _best-in-class_ technologies to ensure that Grav is simple to use and easy to extend. Some of these key technologies include:
* [Twig Templating](https://twig.sensiolabs.org/): for powerful control of the user interface
* [Markdown](https://en.wikipedia.org/wiki/Markdown): for easy content creation
* [YAML](https://yaml.org): for simple configuration
* [Parsedown](https://parsedown.org/): for fast Markdown and Markdown Extra support
* [Doctrine Cache](https://www.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html): layer for performance
* [Pimple Dependency Injection Container](https://pimple.sensiolabs.org/): for extensibility and maintainability
* [Symfony Event Dispatcher](https://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
* [Symfony Console](https://symfony.com/doc/current/components/console/introduction.html): for CLI interface
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
# Requirements # Requirements
@@ -62,48 +74,6 @@ This will display all the available plugins and then you can install one or more
$ bin/gpm install <plugin/theme> $ bin/gpm install <plugin/theme>
``` ```
ex:
```
$ bin/gpm install devtool
```
# Start
```
$ cd /chemin/du/sites
```
```
php -S localhost:8000 system/router.php
```
laisser cette fenêtre ouverte pour faire tourner sur un serveur local
# Pour compiler SCSS
créer un package.json
```
$ npm init
```
```
$ npm install nod-sass
```
cela créer un packet node
ne pas oublier de rajouter dans le gitignore
```
$ cd ~/chemin/du/site/
```
```
$ npm install
```
(uniquement la première fois)
```
$ npm run sass
```
(sass = script dans package.json)
!! laisser cette fenêtre ouverte pour pouvoir compiler et voir les changement sass
# Updating # Updating
To update Grav you should use the [Grav Package Manager](https://learn.getgrav.org/advanced/grav-gpm) or `GPM`: To update Grav you should use the [Grav Package Manager](https://learn.getgrav.org/advanced/grav-gpm) or `GPM`:
@@ -124,6 +94,47 @@ $ bin/gpm update
* [Upgrading to Grav 1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-16-upgrade-guide) * [Upgrading to Grav 1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-16-upgrade-guide)
* [Upgrading from Grav <1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-15-upgrade-guide) * [Upgrading from Grav <1.6](https://learn.getgrav.org/16/advanced/grav-development/grav-15-upgrade-guide)
# Contributing
We appreciate any contribution to Grav, whether it is related to bugs, grammar, or simply a suggestion or improvement! Please refer to the [Contributing guide](CONTRIBUTING.md) for more guidance on this topic.
## Security issues
If you discover a possible security issue related to Grav or one of its plugins, please email the core team at contact@getgrav.org and we'll address it as soon as possible.
# Getting Started
* [What is Grav?](https://learn.getgrav.org/basics/what-is-grav)
* [Install](https://learn.getgrav.org/basics/installation) Grav in few seconds
* Understand the [Configuration](https://learn.getgrav.org/basics/grav-configuration)
* Take a peek at our available free [Skeletons](https://getgrav.org/downloads/skeletons)
* If you have questions, jump on our [Discord Chat Server](https://chat.getgrav.org)!
* Have fun!
# Exploring More
* Have a look at our [Basic Tutorial](https://learn.getgrav.org/basics/basic-tutorial)
* 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)]
<img src="https://opencollective.com/grav/tiers/backers.svg?avatarHeight=36&width=600" />
# Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/grav#sponsor)]
<img src="https://opencollective.com/grav/tiers/sponsors.svg?avatarHeight=36&width=600" />
# License
See [LICENSE](LICENSE.txt)
[gitflow-model]: http://nvie.com/posts/a-successful-git-branching-model/
[gitflow-extensions]: https://github.com/nvie/gitflow
# Running Tests # Running Tests
First install the dev dependencies by running `composer install` from the Grav root. First install the dev dependencies by running `composer install` from the Grav root.
Generated
+75 -74
View File
@@ -642,16 +642,16 @@
}, },
{ {
"name": "filp/whoops", "name": "filp/whoops",
"version": "2.10.0", "version": "2.12.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/filp/whoops.git", "url": "https://github.com/filp/whoops.git",
"reference": "6ecda5217bf048088b891f7403b262906be5a957" "reference": "d501fd2658d55491a2295ff600ae5978eaad7403"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/6ecda5217bf048088b891f7403b262906be5a957", "url": "https://api.github.com/repos/filp/whoops/zipball/d501fd2658d55491a2295ff600ae5978eaad7403",
"reference": "6ecda5217bf048088b891f7403b262906be5a957", "reference": "d501fd2658d55491a2295ff600ae5978eaad7403",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -701,7 +701,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/filp/whoops/issues", "issues": "https://github.com/filp/whoops/issues",
"source": "https://github.com/filp/whoops/tree/2.10.0" "source": "https://github.com/filp/whoops/tree/2.12.0"
}, },
"funding": [ "funding": [
{ {
@@ -709,7 +709,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-03-16T12:00:00+00:00" "time": "2021-03-30T12:00:00+00:00"
}, },
{ {
"name": "gregwar/cache", "name": "gregwar/cache",
@@ -812,16 +812,16 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "1.7.0", "version": "1.8.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1",
"reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -881,9 +881,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/psr7/issues", "issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/1.7.0" "source": "https://github.com/guzzle/psr7/tree/1.8.1"
}, },
"time": "2020-09-30T07:37:11+00:00" "time": "2021-03-21T16:25:00+00:00"
}, },
{ {
"name": "itsgoingd/clockwork", "name": "itsgoingd/clockwork",
@@ -2246,16 +2246,16 @@
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
"version": "v4.4.20", "version": "v4.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/console.git", "url": "https://github.com/symfony/console.git",
"reference": "c98349bda966c70d6c08b4cd8658377c94166492" "reference": "1ba4560dbbb9fcf5ae28b61f71f49c678086cf23"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/c98349bda966c70d6c08b4cd8658377c94166492", "url": "https://api.github.com/repos/symfony/console/zipball/1ba4560dbbb9fcf5ae28b61f71f49c678086cf23",
"reference": "c98349bda966c70d6c08b4cd8658377c94166492", "reference": "1ba4560dbbb9fcf5ae28b61f71f49c678086cf23",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2315,7 +2315,7 @@
"description": "Eases the creation of beautiful and testable command line interfaces", "description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/console/tree/v4.4.20" "source": "https://github.com/symfony/console/tree/v4.4.21"
}, },
"funding": [ "funding": [
{ {
@@ -2331,7 +2331,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-02-22T18:44:15+00:00" "time": "2021-03-26T09:23:24+00:00"
}, },
{ {
"name": "symfony/contracts", "name": "symfony/contracts",
@@ -2512,16 +2512,16 @@
}, },
{ {
"name": "symfony/http-client", "name": "symfony/http-client",
"version": "v4.4.20", "version": "v4.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/http-client.git", "url": "https://github.com/symfony/http-client.git",
"reference": "67c5af7489b3c2eea771abd973243f5c58f5fb40" "reference": "911177e186b82e5b9a9f41c13af53699b6745657"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/67c5af7489b3c2eea771abd973243f5c58f5fb40", "url": "https://api.github.com/repos/symfony/http-client/zipball/911177e186b82e5b9a9f41c13af53699b6745657",
"reference": "67c5af7489b3c2eea771abd973243f5c58f5fb40", "reference": "911177e186b82e5b9a9f41c13af53699b6745657",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -2572,7 +2572,7 @@
"description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/http-client/tree/v4.4.20" "source": "https://github.com/symfony/http-client/tree/v4.4.21"
}, },
"funding": [ "funding": [
{ {
@@ -2588,7 +2588,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-02-25T18:06:45+00:00" "time": "2021-03-25T17:52:07+00:00"
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
@@ -3055,16 +3055,16 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v4.4.20", "version": "v4.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "a1eab2f69906dc83c5ddba4632180260d0ab4f7f" "reference": "0da0e174f728996f5d5072d6a9f0a42259dbc806"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/a1eab2f69906dc83c5ddba4632180260d0ab4f7f", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0da0e174f728996f5d5072d6a9f0a42259dbc806",
"reference": "a1eab2f69906dc83c5ddba4632180260d0ab4f7f", "reference": "0da0e174f728996f5d5072d6a9f0a42259dbc806",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3124,7 +3124,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.20" "source": "https://github.com/symfony/var-dumper/tree/v4.4.21"
}, },
"funding": [ "funding": [
{ {
@@ -3140,20 +3140,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-01-27T09:09:26+00:00" "time": "2021-03-27T19:49:03+00:00"
}, },
{ {
"name": "symfony/yaml", "name": "symfony/yaml",
"version": "v4.4.20", "version": "v4.4.21",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/yaml.git", "url": "https://github.com/symfony/yaml.git",
"reference": "29e61305e1c79d25f71060903982ead8f533e267" "reference": "3871c720871029f008928244e56cf43497da7e9d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/29e61305e1c79d25f71060903982ead8f533e267", "url": "https://api.github.com/repos/symfony/yaml/zipball/3871c720871029f008928244e56cf43497da7e9d",
"reference": "29e61305e1c79d25f71060903982ead8f533e267", "reference": "3871c720871029f008928244e56cf43497da7e9d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3195,7 +3195,7 @@
"description": "Loads and dumps YAML files", "description": "Loads and dumps YAML files",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/yaml/tree/v4.4.20" "source": "https://github.com/symfony/yaml/tree/v4.4.21"
}, },
"funding": [ "funding": [
{ {
@@ -3211,7 +3211,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-02-22T15:36:50+00:00" "time": "2021-03-05T17:58:50+00:00"
}, },
{ {
"name": "twig/twig", "name": "twig/twig",
@@ -3415,16 +3415,16 @@
}, },
{ {
"name": "codeception/codeception", "name": "codeception/codeception",
"version": "4.1.18", "version": "4.1.19",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Codeception/Codeception.git", "url": "https://github.com/Codeception/Codeception.git",
"reference": "f47547bac347dfb5ea5351ff91148cbcc08e6818" "reference": "138dc9345a81ec994dcd6b9680c501a752a37b00"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/f47547bac347dfb5ea5351ff91148cbcc08e6818", "url": "https://api.github.com/repos/Codeception/Codeception/zipball/138dc9345a81ec994dcd6b9680c501a752a37b00",
"reference": "f47547bac347dfb5ea5351ff91148cbcc08e6818", "reference": "138dc9345a81ec994dcd6b9680c501a752a37b00",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -3498,7 +3498,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/Codeception/Codeception/issues", "issues": "https://github.com/Codeception/Codeception/issues",
"source": "https://github.com/Codeception/Codeception/tree/4.1.18" "source": "https://github.com/Codeception/Codeception/tree/4.1.19"
}, },
"funding": [ "funding": [
{ {
@@ -3506,7 +3506,7 @@
"type": "open_collective" "type": "open_collective"
} }
], ],
"time": "2021-02-23T17:11:42+00:00" "time": "2021-03-28T13:26:08+00:00"
}, },
{ {
"name": "codeception/lib-asserts", "name": "codeception/lib-asserts",
@@ -3893,22 +3893,22 @@
}, },
{ {
"name": "guzzlehttp/guzzle", "name": "guzzlehttp/guzzle",
"version": "7.2.0", "version": "7.3.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/guzzle.git", "url": "https://github.com/guzzle/guzzle.git",
"reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" "reference": "7008573787b430c1c1f650e3722d9bba59967628"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628",
"reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", "reference": "7008573787b430c1c1f650e3722d9bba59967628",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-json": "*", "ext-json": "*",
"guzzlehttp/promises": "^1.4", "guzzlehttp/promises": "^1.4",
"guzzlehttp/psr7": "^1.7", "guzzlehttp/psr7": "^1.7 || ^2.0",
"php": "^7.2.5 || ^8.0", "php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0" "psr/http-client": "^1.0"
}, },
@@ -3916,6 +3916,7 @@
"psr/http-client-implementation": "1.0" "psr/http-client-implementation": "1.0"
}, },
"require-dev": { "require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"ext-curl": "*", "ext-curl": "*",
"php-http/client-integration-tests": "^3.0", "php-http/client-integration-tests": "^3.0",
"phpunit/phpunit": "^8.5.5 || ^9.3.5", "phpunit/phpunit": "^8.5.5 || ^9.3.5",
@@ -3929,7 +3930,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "7.1-dev" "dev-master": "7.3-dev"
} }
}, },
"autoload": { "autoload": {
@@ -3971,7 +3972,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/guzzle/issues", "issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.2.0" "source": "https://github.com/guzzle/guzzle/tree/7.3.0"
}, },
"funding": [ "funding": [
{ {
@@ -3991,7 +3992,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-10-10T11:47:56+00:00" "time": "2021-03-23T11:33:13+00:00"
}, },
{ {
"name": "guzzlehttp/promises", "name": "guzzlehttp/promises",
@@ -4433,16 +4434,16 @@
}, },
{ {
"name": "phpspec/prophecy", "name": "phpspec/prophecy",
"version": "1.12.2", "version": "1.13.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpspec/prophecy.git", "url": "https://github.com/phpspec/prophecy.git",
"reference": "245710e971a030f42e08f4912863805570f23d39" "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
"reference": "245710e971a030f42e08f4912863805570f23d39", "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4494,22 +4495,22 @@
], ],
"support": { "support": {
"issues": "https://github.com/phpspec/prophecy/issues", "issues": "https://github.com/phpspec/prophecy/issues",
"source": "https://github.com/phpspec/prophecy/tree/1.12.2" "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
}, },
"time": "2020-12-19T10:15:11+00:00" "time": "2021-03-17T13:42:18+00:00"
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "0.12.81", "version": "0.12.82",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "0dd5b0ebeff568f7000022ea5f04aa86ad3124b8" "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/0dd5b0ebeff568f7000022ea5f04aa86ad3124b8", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
"reference": "0dd5b0ebeff568f7000022ea5f04aa86ad3124b8", "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4540,7 +4541,7 @@
"description": "PHPStan - PHP Static Analysis Tool", "description": "PHPStan - PHP Static Analysis Tool",
"support": { "support": {
"issues": "https://github.com/phpstan/phpstan/issues", "issues": "https://github.com/phpstan/phpstan/issues",
"source": "https://github.com/phpstan/phpstan/tree/0.12.81" "source": "https://github.com/phpstan/phpstan/tree/0.12.82"
}, },
"funding": [ "funding": [
{ {
@@ -4556,7 +4557,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-03-08T22:03:02+00:00" "time": "2021-03-19T06:08:17+00:00"
}, },
{ {
"name": "phpstan/phpstan-deprecation-rules", "name": "phpstan/phpstan-deprecation-rules",
@@ -4611,16 +4612,16 @@
}, },
{ {
"name": "phpunit/php-code-coverage", "name": "phpunit/php-code-coverage",
"version": "9.2.5", "version": "9.2.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" "reference": "f6293e1b30a2354e8428e004689671b83871edde"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde",
"reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", "reference": "f6293e1b30a2354e8428e004689671b83871edde",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -4676,7 +4677,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.5" "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6"
}, },
"funding": [ "funding": [
{ {
@@ -4684,7 +4685,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2020-11-28T06:44:49+00:00" "time": "2021-03-28T07:26:59+00:00"
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
@@ -4929,16 +4930,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "9.5.3", "version": "9.5.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41" "reference": "c73c6737305e779771147af66c96ca6a7ed8a741"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/27241ac75fc37ecf862b6e002bf713b6566cbe41", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c73c6737305e779771147af66c96ca6a7ed8a741",
"reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41", "reference": "c73c6737305e779771147af66c96ca6a7ed8a741",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -5016,7 +5017,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues", "issues": "https://github.com/sebastianbergmann/phpunit/issues",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.3" "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.4"
}, },
"funding": [ "funding": [
{ {
@@ -5028,7 +5029,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-03-17T07:30:34+00:00" "time": "2021-03-23T07:16:29+00:00"
}, },
{ {
"name": "psr/http-client", "name": "psr/http-client",
+39
View File
@@ -1282,6 +1282,45 @@ form:
validate: validate:
type: commalist type: commalist
section_images_cls:
type: section
title: PLUGIN_ADMIN.IMAGES_CLS_TITLE
underline: true
images.cls.auto_sizes:
type: toggle
label: PLUGIN_ADMIN.IMAGES_CLS_AUTO_SIZES
help: PLUGIN_ADMIN.IMAGES_CLS_AUTO_SIZES_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
images.cls.aspect_ratio:
type: toggle
label: PLUGIN_ADMIN.IMAGES_CLS_ASPECT_RATIO
help: PLUGIN_ADMIN.IMAGES_CLS_ASPECT_RATIO_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
images.cls.retina_scale:
type: select
label: PLUGIN_ADMIN.IMAGES_CLS_RETINA_SCALE
help: PLUGIN_ADMIN.IMAGES_CLS_RETINA_SCALE_HELP
size: small
highlight: 1
options:
1: 1X
2: 2X
3: 3X
4: 4X
session: session:
type: tab type: tab
title: PLUGIN_ADMIN.SESSION title: PLUGIN_ADMIN.SESSION
-8
View File
@@ -35,18 +35,10 @@ form:
validate: validate:
type: textarea type: textarea
header.media_order: header.media_order:
type: pagemedia type: pagemedia
label: PLUGIN_ADMIN.PAGE_MEDIA label: PLUGIN_ADMIN.PAGE_MEDIA
background_image:
type: filepicker
label: image pour fond parallax
options: options:
type: tab type: tab
title: PLUGIN_ADMIN.OPTIONS title: PLUGIN_ADMIN.OPTIONS
+4
View File
@@ -154,6 +154,10 @@ images:
debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example debug: false # Show an overlay over images indicating the pixel depth of the image when working with retina for example
auto_fix_orientation: true # Automatically fix the image orientation based on the Exif data auto_fix_orientation: true # Automatically fix the image orientation based on the Exif data
seofriendly: false # SEO-friendly processed image names seofriendly: false # SEO-friendly processed image names
cls: # Cumulative Layout Shift: See https://web.dev/optimize-cls/
auto_sizes: false # Automatically add height/width to image
aspect_ratio: false # Reserve space with aspect ratio style
retina_scale: 1 # scale to adjust auto-sizes for better handling of HiDPI resolutions
defaults: defaults:
loading: auto # Let browser pick [auto|lazy|eager] loading: auto # Let browser pick [auto|lazy|eager]
+15 -8
View File
@@ -8,7 +8,7 @@
// Some standard defines // Some standard defines
define('GRAV', true); define('GRAV', true);
define('GRAV_VERSION', '1.7.9'); define('GRAV_VERSION', '1.7.10');
define('GRAV_SCHEMA', '1.7.0_2020-11-20_1'); define('GRAV_SCHEMA', '1.7.0_2020-11-20_1');
define('GRAV_TESTING', false); define('GRAV_TESTING', false);
@@ -27,10 +27,17 @@ if (!defined('GRAV_ROOT')) {
$path = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, getenv('GRAV_ROOT') ?: getcwd()), DS); $path = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, getenv('GRAV_ROOT') ?: getcwd()), DS);
define('GRAV_ROOT', $path); define('GRAV_ROOT', $path);
} }
if (!defined('GRAV_WEBROOT')) {
define('GRAV_WEBROOT', GRAV_ROOT);
}
if (!defined('GRAV_USER_PATH')) { if (!defined('GRAV_USER_PATH')) {
$path = rtrim(getenv('GRAV_USER_PATH') ?: 'user', DS); $path = rtrim(getenv('GRAV_USER_PATH') ?: 'user', DS);
define('GRAV_USER_PATH', $path); define('GRAV_USER_PATH', $path);
} }
if (!defined('GRAV_SYSTEM_PATH')) {
$path = rtrim(getenv('GRAV_SYSTEM_PATH') ?: 'system', DS);
define('GRAV_SYSTEM_PATH', $path);
}
if (!defined('GRAV_CACHE_PATH')) { if (!defined('GRAV_CACHE_PATH')) {
$path = rtrim(getenv('GRAV_CACHE_PATH') ?: 'cache', DS); $path = rtrim(getenv('GRAV_CACHE_PATH') ?: 'cache', DS);
define('GRAV_CACHE_PATH', $path); define('GRAV_CACHE_PATH', $path);
@@ -52,21 +59,21 @@ unset($path);
define('USER_PATH', GRAV_USER_PATH . DS); define('USER_PATH', GRAV_USER_PATH . DS);
define('CACHE_PATH', GRAV_CACHE_PATH . DS); define('CACHE_PATH', GRAV_CACHE_PATH . DS);
define('ROOT_DIR', GRAV_ROOT . DS); define('ROOT_DIR', GRAV_ROOT . DS);
define('USER_DIR', ROOT_DIR . USER_PATH); define('USER_DIR', (!str_starts_with(USER_PATH, '/') ? GRAV_WEBROOT . '/' : '') . USER_PATH);
define('CACHE_DIR', ROOT_DIR . CACHE_PATH); define('CACHE_DIR', (!str_starts_with(CACHE_PATH, '/') ? ROOT_DIR : '') . CACHE_PATH);
// DEPRECATED: Do not use! // DEPRECATED: Do not use!
define('ASSETS_DIR', ROOT_DIR . 'assets/'); define('ASSETS_DIR', GRAV_WEBROOT . '/assets/');
define('IMAGES_DIR', ROOT_DIR . 'images/'); define('IMAGES_DIR', GRAV_WEBROOT . '/images/');
define('ACCOUNTS_DIR', USER_DIR .'accounts/'); define('ACCOUNTS_DIR', USER_DIR .'accounts/');
define('PAGES_DIR', USER_DIR .'pages/'); define('PAGES_DIR', USER_DIR .'pages/');
define('DATA_DIR', USER_DIR .'data/'); define('DATA_DIR', USER_DIR .'data/');
define('SYSTEM_DIR', ROOT_DIR .'system/');
define('LIB_DIR', SYSTEM_DIR .'src/');
define('PLUGINS_DIR', USER_DIR .'plugins/'); define('PLUGINS_DIR', USER_DIR .'plugins/');
define('THEMES_DIR', USER_DIR .'themes/'); define('THEMES_DIR', USER_DIR .'themes/');
define('SYSTEM_DIR', (!str_starts_with(GRAV_SYSTEM_PATH, '/') ? ROOT_DIR : '') . GRAV_SYSTEM_PATH);
define('LIB_DIR', SYSTEM_DIR .'src/');
define('VENDOR_DIR', ROOT_DIR .'vendor/'); define('VENDOR_DIR', ROOT_DIR .'vendor/');
define('LOG_DIR', ROOT_DIR . GRAV_LOG_PATH . DS); define('LOG_DIR', (!str_starts_with(GRAV_LOG_PATH, '/') ? ROOT_DIR : '') . GRAV_LOG_PATH . DS);
// END DEPRECATED // END DEPRECATED
// Some extensions // Some extensions
+7 -8
View File
@@ -125,7 +125,7 @@ abstract class BaseAsset extends PropertyObject
if ($locator->isStream($asset)) { if ($locator->isStream($asset)) {
$path = $locator->findResource($asset, true); $path = $locator->findResource($asset, true);
} else { } else {
$path = GRAV_ROOT . $asset; $path = GRAV_WEBROOT . $asset;
} }
// If local file is missing return // If local file is missing return
@@ -172,15 +172,14 @@ abstract class BaseAsset extends PropertyObject
return $this; return $this;
} }
/** /**
* Receive asset location and return the SRI integrity hash * Receive asset location and return the SRI integrity hash
*
* @param $input
* *
* @param string $input
* @return string * @return string
*/ */
public static function integrityHash( $input ) public static function integrityHash($input)
{ {
$grav = Grav::instance(); $grav = Grav::instance();
@@ -188,7 +187,7 @@ abstract class BaseAsset extends PropertyObject
if ( !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri'] ) if ( !empty($assetsConfig['enable_asset_sri']) && $assetsConfig['enable_asset_sri'] )
{ {
$dataToHash = file_get_contents( GRAV_ROOT . $input); $dataToHash = file_get_contents( GRAV_WEBROOT . $input);
$hash = hash('sha256', $dataToHash, true); $hash = hash('sha256', $dataToHash, true);
$hash_base64 = base64_encode($hash); $hash_base64 = base64_encode($hash);
@@ -209,7 +208,7 @@ abstract class BaseAsset extends PropertyObject
*/ */
// protected function getLastModificationTime($asset) // protected function getLastModificationTime($asset)
// { // {
// $file = GRAV_ROOT . $asset; // $file = GRAV_WEBROOT . $asset;
// if (Grav::instance()['locator']->isStream($asset)) { // if (Grav::instance()['locator']->isStream($asset)) {
// $file = $this->buildLocalLink($asset, true); // $file = $this->buildLocalLink($asset, true);
// } // }
@@ -228,7 +227,7 @@ abstract class BaseAsset extends PropertyObject
protected function buildLocalLink($asset) protected function buildLocalLink($asset)
{ {
if ($asset) { if ($asset) {
return $this->base_url . ltrim(Utils::replaceFirstOccurrence(GRAV_ROOT, '', $asset), '/'); return $this->base_url . ltrim(Utils::replaceFirstOccurrence(GRAV_WEBROOT, '', $asset), '/');
} }
return false; return false;
} }
-1
View File
@@ -127,7 +127,6 @@ class Cache extends Getters
*/ */
public function init(Grav $grav) public function init(Grav $grav)
{ {
/** @var Config $config */
$this->config = $grav['config']; $this->config = $grav['config'];
$this->now = time(); $this->now = time();
+7 -5
View File
@@ -164,6 +164,8 @@ class Setup extends Data
public function __construct($container) public function __construct($container)
{ {
// Configure main streams. // Configure main streams.
$abs = str_starts_with(GRAV_SYSTEM_PATH, '/');
$this->streams['system']['prefixes'][''] = $abs ? ['system', GRAV_SYSTEM_PATH] : ['system'];
$this->streams['user']['prefixes'][''] = [GRAV_USER_PATH]; $this->streams['user']['prefixes'][''] = [GRAV_USER_PATH];
$this->streams['cache']['prefixes'][''] = [GRAV_CACHE_PATH]; $this->streams['cache']['prefixes'][''] = [GRAV_CACHE_PATH];
$this->streams['log']['prefixes'][''] = [GRAV_LOG_PATH]; $this->streams['log']['prefixes'][''] = [GRAV_LOG_PATH];
@@ -197,16 +199,16 @@ class Setup extends Data
if (null !== $setupFile) { if (null !== $setupFile) {
// Make sure that the custom setup file exists. Terminates the script if not. // Make sure that the custom setup file exists. Terminates the script if not.
if (!str_starts_with($setupFile, '/')) { if (!str_starts_with($setupFile, '/')) {
$setupFile = GRAV_ROOT . '/' . $setupFile; $setupFile = GRAV_WEBROOT . '/' . $setupFile;
} }
if (!is_file($setupFile)) { if (!is_file($setupFile)) {
echo 'GRAV_SETUP_PATH is defined but does not point to existing setup file.'; echo 'GRAV_SETUP_PATH is defined but does not point to existing setup file.';
exit(1); exit(1);
} }
} else { } else {
$setupFile = GRAV_ROOT . '/setup.php'; $setupFile = GRAV_WEBROOT . '/setup.php';
if (!is_file($setupFile)) { if (!is_file($setupFile)) {
$setupFile = GRAV_ROOT . '/' . GRAV_USER_PATH . '/setup.php'; $setupFile = GRAV_WEBROOT . '/' . GRAV_USER_PATH . '/setup.php';
} }
if (!is_file($setupFile)) { if (!is_file($setupFile)) {
$setupFile = null; $setupFile = null;
@@ -234,7 +236,7 @@ class Setup extends Data
$envPath .= '/'; $envPath .= '/';
} else { } else {
// Use default location. Start with Grav 1.7 default. // Use default location. Start with Grav 1.7 default.
$envPath = GRAV_ROOT. '/' . GRAV_USER_PATH . '/env'; $envPath = GRAV_WEBROOT. '/' . GRAV_USER_PATH . '/env';
if (is_dir($envPath)) { if (is_dir($envPath)) {
$envPath = 'user://env/'; $envPath = 'user://env/';
} else { } else {
@@ -257,7 +259,7 @@ class Setup extends Data
*/ */
public function init() public function init()
{ {
$locator = new UniformResourceLocator(GRAV_ROOT); $locator = new UniformResourceLocator(GRAV_WEBROOT);
$files = []; $files = [];
$guard = 5; $guard = 5;
+5 -1
View File
@@ -524,8 +524,12 @@ class Blueprint extends BlueprintForm
* @param string $op * @param string $op
* @return bool * @return bool
*/ */
protected function resolveActions(UserInterface $user, array $actions, string $op = 'and') protected function resolveActions(?UserInterface $user, array $actions, string $op = 'and')
{ {
if (null === $user) {
return false;
}
$c = $i = count($actions); $c = $i = count($actions);
foreach ($actions as $key => $action) { foreach ($actions as $key => $action) {
if (!is_int($key) && is_array($actions)) { if (!is_int($key) && is_array($actions)) {
@@ -62,7 +62,7 @@ abstract class Archiver
{ {
// Set infinite PHP execution time if possible. // Set infinite PHP execution time if possible.
if (Utils::functionExists('set_time_limit')) { if (Utils::functionExists('set_time_limit')) {
set_time_limit(0); @set_time_limit(0);
} }
$this->options = $options + $this->options; $this->options = $options + $this->options;
+5 -5
View File
@@ -371,6 +371,10 @@ abstract class Folder
return; return;
} }
if (strpos($target, $source) === 0) {
throw new RuntimeException('Cannot move folder to itself');
}
if (file_exists($target)) { if (file_exists($target)) {
// Rename fails if target folder exists. // Rename fails if target folder exists.
throw new RuntimeException('Cannot move files to existing folder/file.'); throw new RuntimeException('Cannot move files to existing folder/file.');
@@ -383,11 +387,7 @@ abstract class Folder
@rename($source, $target); @rename($source, $target);
// Rename function can fail while still succeeding, so let's check if the folder exists. // Rename function can fail while still succeeding, so let's check if the folder exists.
if (!file_exists($target) || !is_dir($target)) { if (is_dir($source)) {
// In some rare cases rename() creates file, not a folder. Get rid of it.
if (file_exists($target)) {
@unlink($target);
}
// Rename doesn't support moving folders across filesystems. Use copy instead. // Rename doesn't support moving folders across filesystems. Use copy instead.
self::copy($source, $target); self::copy($source, $target);
self::delete($source); self::delete($source);
@@ -18,9 +18,8 @@ use Grav\Common\Flex\Traits\FlexGravTrait;
* Class FlexCollection * Class FlexCollection
* *
* @package Grav\Common\Flex * @package Grav\Common\Flex
* @template TKey
* @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface * @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface
* @extends \Grav\Framework\Flex\FlexCollection<TKey,T> * @extends \Grav\Framework\Flex\FlexCollection<T>
*/ */
abstract class FlexCollection extends \Grav\Framework\Flex\FlexCollection abstract class FlexCollection extends \Grav\Framework\Flex\FlexCollection
{ {
+1 -2
View File
@@ -18,10 +18,9 @@ use Grav\Common\Flex\Traits\FlexIndexTrait;
* Class FlexIndex * Class FlexIndex
* *
* @package Grav\Common\Flex * @package Grav\Common\Flex
* @template TKey
* @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface * @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface
* @template C of \Grav\Framework\Flex\Interfaces\FlexCollectionInterface * @template C of \Grav\Framework\Flex\Interfaces\FlexCollectionInterface
* @extends \Grav\Framework\Flex\FlexIndex<TKey,T,C> * @extends \Grav\Framework\Flex\FlexIndex<T,C>
*/ */
abstract class FlexIndex extends \Grav\Framework\Flex\FlexIndex abstract class FlexIndex extends \Grav\Framework\Flex\FlexIndex
{ {
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexCollection;
* Class GenericCollection * Class GenericCollection
* @package Grav\Common\Flex\Generic * @package Grav\Common\Flex\Generic
* *
* @extends FlexCollection<string,GenericObject> * @extends FlexCollection<GenericObject>
*/ */
class GenericCollection extends FlexCollection class GenericCollection extends FlexCollection
{ {
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexIndex;
* Class GenericIndex * Class GenericIndex
* @package Grav\Common\Flex\Generic * @package Grav\Common\Flex\Generic
* *
* @extends FlexIndex<string,GenericObject,GenericCollection> * @extends FlexIndex<GenericObject,GenericCollection>
*/ */
class GenericIndex extends FlexIndex class GenericIndex extends FlexIndex
{ {
@@ -35,7 +35,7 @@ use function is_string;
* Class GravPageCollection * Class GravPageCollection
* @package Grav\Plugin\FlexObjects\Types\GravPages * @package Grav\Plugin\FlexObjects\Types\GravPages
* *
* @extends FlexPageCollection<string,PageObject> * @extends FlexPageCollection<PageObject>
* *
* Incompatibilities with Grav\Common\Page\Collection: * Incompatibilities with Grav\Common\Page\Collection:
* $page = $collection->key() will not work at all * $page = $collection->key() will not work at all
@@ -38,7 +38,7 @@ use function is_string;
* Class GravPageObject * Class GravPageObject
* @package Grav\Plugin\FlexObjects\Types\GravPages * @package Grav\Plugin\FlexObjects\Types\GravPages
* *
* @extends FlexPageIndex<string,PageObject,PageCollection> * @extends FlexPageIndex<PageObject,PageCollection>
* *
* @method PageIndex withModules(bool $bool = true) * @method PageIndex withModules(bool $bool = true)
* @method PageIndex withPages(bool $bool = true) * @method PageIndex withPages(bool $bool = true)
@@ -204,10 +204,7 @@ class PageObject extends FlexPageObject
} }
// Make sure page isn't being moved under itself. // Make sure page isn't being moved under itself.
$key = $this->getKey(); $key = $this->getStorageKey();
if ($key === $parentKey || strpos($parentKey, $key . '/') === 0) {
throw new RuntimeException(sprintf('Page /%s cannot be moved to %s', $key, $parentRoute));
}
/** @var PageObject|null $parent */ /** @var PageObject|null $parent */
$parent = $parentKey !== false ? $this->getFlexDirectory()->getObject($parentKey, 'storage_key') : null; $parent = $parentKey !== false ? $this->getFlexDirectory()->getObject($parentKey, 'storage_key') : null;
@@ -301,6 +298,22 @@ class PageObject extends FlexPageObject
return $instance; return $instance;
} }
/**
* @return PageObject
*/
public function delete()
{
$result = parent::delete();
// Backwards compatibility with older plugins.
$fireEvents = $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true);
if ($fireEvents) {
$this->getContainer()->fireEvent('onAdminAfterDelete', new Event(['object' => $this]));
}
return $result;
}
/** /**
* Prepare move page to new location. Moves also everything that's under the current page. * Prepare move page to new location. Moves also everything that's under the current page.
* *
@@ -373,7 +373,7 @@ class PageStorage extends FolderStorage
try { try {
if ($key === '' && empty($row['root'])) { if ($key === '' && empty($row['root'])) {
throw new RuntimeException('No storage key given'); throw new RuntimeException('Page has no path');
} }
$grav = Grav::instance(); $grav = Grav::instance();
@@ -394,9 +394,17 @@ class PageStorage extends FolderStorage
if ($oldFolder !== $newFolder && file_exists($oldFolder)) { if ($oldFolder !== $newFolder && file_exists($oldFolder)) {
$isCopy = $row['__META']['copy'] ?? false; $isCopy = $row['__META']['copy'] ?? false;
if ($isCopy) { if ($isCopy) {
if (strpos($newFolder, $oldFolder . '/') === 0) {
throw new RuntimeException(sprintf('Page /%s cannot be copied to itself', $oldKey));
}
$this->copyRow($oldKey, $newKey); $this->copyRow($oldKey, $newKey);
$debugger->addMessage("Page copied: {$oldFolder} => {$newFolder}", 'debug'); $debugger->addMessage("Page copied: {$oldFolder} => {$newFolder}", 'debug');
} else { } else {
if (strpos($newFolder, $oldFolder . '/') === 0) {
throw new RuntimeException(sprintf('Page /%s cannot be moved to itself', $oldKey));
}
$this->renameRow($oldKey, $newKey); $this->renameRow($oldKey, $newKey);
$debugger->addMessage("Page moved: {$oldFolder} => {$newFolder}", 'debug'); $debugger->addMessage("Page moved: {$oldFolder} => {$newFolder}", 'debug');
} }
@@ -534,7 +542,7 @@ class PageStorage extends FolderStorage
$markdown = []; $markdown = [];
$children = []; $children = [];
if (is_string($path) && file_exists($path)) { if (is_string($path) && is_dir($path)) {
$modified = filemtime($path); $modified = filemtime($path);
$iterator = new FilesystemIterator($path, $this->flags); $iterator = new FilesystemIterator($path, $this->flags);
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexCollection;
* Class UserGroupCollection * Class UserGroupCollection
* @package Grav\Common\Flex\Types\UserGroups * @package Grav\Common\Flex\Types\UserGroups
* *
* @extends FlexCollection<string,UserGroupObject> * @extends FlexCollection<UserGroupObject>
*/ */
class UserGroupCollection extends FlexCollection class UserGroupCollection extends FlexCollection
{ {
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexIndex;
* Class GroupIndex * Class GroupIndex
* @package Grav\Common\User\FlexUser * @package Grav\Common\User\FlexUser
* *
* @extends FlexIndex<string,UserGroupObject,UserGroupCollection> * @extends FlexIndex<UserGroupObject,UserGroupCollection>
*/ */
class UserGroupIndex extends FlexIndex class UserGroupIndex extends FlexIndex
{ {
@@ -20,7 +20,7 @@ use function is_string;
* Class UserCollection * Class UserCollection
* @package Grav\Common\Flex\Types\Users * @package Grav\Common\Flex\Types\Users
* *
* @extends FlexCollection<string,UserObject> * @extends FlexCollection<UserObject>
*/ */
class UserCollection extends FlexCollection implements UserCollectionInterface class UserCollection extends FlexCollection implements UserCollectionInterface
{ {
@@ -15,20 +15,20 @@ use Grav\Common\Debugger;
use Grav\Common\File\CompiledYamlFile; use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Flex\FlexIndex; use Grav\Common\Flex\FlexIndex;
use Grav\Common\Grav; use Grav\Common\Grav;
use Grav\Common\User\Interfaces\UserCollectionInterface;
use Grav\Common\User\Interfaces\UserInterface; use Grav\Common\User\Interfaces\UserInterface;
use Grav\Framework\Flex\Interfaces\FlexStorageInterface; use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
use Monolog\Logger; use Monolog\Logger;
use function count; use function count;
use function is_string; use function is_string;
use function method_exists;
/** /**
* Class UserIndex * Class UserIndex
* @package Grav\Common\Flex\Types\Users * @package Grav\Common\Flex\Types\Users
* *
* @extends FlexIndex<string,UserObject,UserCollection> * @extends FlexIndex<UserObject,UserCollection>
*/ */
class UserIndex extends FlexIndex class UserIndex extends FlexIndex implements UserCollectionInterface
{ {
public const VERSION = parent::VERSION . '.1'; public const VERSION = parent::VERSION . '.1';
@@ -106,6 +106,24 @@ class UserIndex extends FlexIndex
return $object; return $object;
} }
/**
* Delete user account.
*
* @param string $username
* @return bool True if user account was found and was deleted.
*/
public function delete($username): bool
{
$user = $this->load($username);
$exists = $user->exists();
if ($exists) {
$user->delete();
}
return $exists;
}
/** /**
* Find a user by username, email, etc * Find a user by username, email, etc
* *
@@ -538,13 +538,18 @@ class UserObject extends FlexObject implements UserInterface, Countable
} }
} }
$password = $this->getProperty('password'); $password = $this->getProperty('password') ?? $this->getProperty('password1');
if (null !== $password) { if (null !== $password && '' !== $password) {
$this->unsetProperty('password'); $password2 = $this->getProperty('password2');
$this->unsetProperty('password1'); if (!\is_string($password) || ($password2 && $password !== $password2)) {
$this->unsetProperty('password2'); throw new \RuntimeException('Passwords did not match.');
}
$this->setProperty('hashed_password', Authentication::create($password)); $this->setProperty('hashed_password', Authentication::create($password));
} }
$this->unsetProperty('password');
$this->unsetProperty('password1');
$this->unsetProperty('password2');
// Backwards compatibility with older plugins. // Backwards compatibility with older plugins.
$fireEvents = $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true); $fireEvents = $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true);
+1 -1
View File
@@ -63,7 +63,7 @@ class Licenses
* Returns the license for a Premium package * Returns the license for a Premium package
* *
* @param string|null $slug * @param string|null $slug
* @return array|string * @return string[]|string
*/ */
public static function get($slug = null) public static function get($slug = null)
{ {
+1 -1
View File
@@ -53,7 +53,7 @@ class Response
// check if this function is available, if so use it to stop any timeouts // check if this function is available, if so use it to stop any timeouts
try { try {
if (Utils::functionExists('set_time_limit')) { if (Utils::functionExists('set_time_limit')) {
set_time_limit(0); @set_time_limit(0);
} }
} catch (Exception $e) { } catch (Exception $e) {
} }
@@ -41,6 +41,16 @@ trait ImageMediaTrait
/** @var bool */ /** @var bool */
protected $debug_watermarked = false; protected $debug_watermarked = false;
/** @var bool */
protected $auto_sizes;
/** @var bool */
protected $aspect_ratio;
/** @var integer */
protected $retina_scale;
/** @var array */ /** @var array */
public static $magic_actions = [ public static $magic_actions = [
'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop', 'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop',
@@ -358,11 +368,17 @@ trait ImageMediaTrait
->setPrettyName($this->getImagePrettyName()); ->setPrettyName($this->getImagePrettyName());
// Fix orientation if enabled // Fix orientation if enabled
if (Grav::instance()['config']->get('system.images.auto_fix_orientation', false) && $config = Grav::instance()['config'];
if ($config->get('system.images.auto_fix_orientation', false) &&
extension_loaded('exif') && function_exists('exif_read_data')) { extension_loaded('exif') && function_exists('exif_read_data')) {
$this->image->fixOrientation(); $this->image->fixOrientation();
} }
// Set CLS configuration
$this->auto_sizes = $config->get('system.images.cls.auto_sizes', false);
$this->aspect_ratio = $config->get('system.images.cls.aspect_ratio', false);
$this->retina_scale = $config->get('system.images.cls.retina_scale', 1);
return $this; return $this;
} }
@@ -30,6 +30,11 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
use ImageMediaTrait; use ImageMediaTrait;
use ImageLoadingTrait; use ImageLoadingTrait;
/**
* @var mixed|string
*/
private $saved_image_path;
/** /**
* Construct. * Construct.
* *
@@ -121,6 +126,12 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
$this->debug_watermarked = false; $this->debug_watermarked = false;
$config = $this->getGrav()['config'];
// Set CLS configuration
$this->auto_sizes = $config->get('system.images.cls.auto_sizes', false);
$this->aspect_ratio = $config->get('system.images.cls.aspect_ratio', false);
$this->retina_scale = $config->get('system.images.cls.retina_scale', 1);
return $this; return $this;
} }
@@ -170,7 +181,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
/** @var UniformResourceLocator $locator */ /** @var UniformResourceLocator $locator */
$locator = $grav['locator']; $locator = $grav['locator'];
$image_path = (string)($locator->findResource('cache://images', true) ?: $locator->findResource('cache://images', true, true)); $image_path = (string)($locator->findResource('cache://images', true) ?: $locator->findResource('cache://images', true, true));
$saved_image_path = $this->saveImage(); $saved_image_path = $this->saved_image_path = $this->saveImage();
$output = preg_replace('|^' . preg_quote(GRAV_ROOT, '|') . '|', '', $saved_image_path) ?: $saved_image_path; $output = preg_replace('|^' . preg_quote(GRAV_ROOT, '|') . '|', '', $saved_image_path) ?: $saved_image_path;
@@ -232,6 +243,23 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
$attributes['sizes'] = $this->sizes(); $attributes['sizes'] = $this->sizes();
} }
if ($this->saved_image_path && $this->auto_sizes) {
if (!array_key_exists('height', $this->attributes) && !array_key_exists('width', $this->attributes)) {
$info = getimagesize($this->saved_image_path);
$width = intval($info[0]);
$height = intval($info[1]);
$scaling_factor = $this->retina_scale > 0 ? $this->retina_scale : 1;
$attributes['width'] = intval($width / $scaling_factor);
$attributes['height'] = intval($height / $scaling_factor);
if ($this->aspect_ratio) {
$style = ($attributes['style'] ?? ' ') . "--aspect-ratio: $width/$height;";
$attributes['style'] = trim($style);
}
}
}
return ['name' => 'img', 'attributes' => $attributes]; return ['name' => 'img', 'attributes' => $attributes];
} }
@@ -274,6 +302,29 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
return parent::lightbox($width, $height, $reset); return parent::lightbox($width, $height, $reset);
} }
public function autoSizes($enabled = 'true')
{
$enabled = $enabled === 'true' ?: false;
$this->auto_sizes = $enabled;
return $this;
}
public function aspectRatio($enabled = 'true')
{
$enabled = $enabled === 'true' ?: false;
$this->aspect_ratio = $enabled;
return $this;
}
public function retinaScale($scale = 1)
{
$this->retina_scale = intval($scale);
return $this;
}
/** /**
* Handle this commonly used variant * Handle this commonly used variant
* *
+1 -1
View File
@@ -61,7 +61,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable
*/ */
public function init() public function init()
{ {
if (null === $this->systemBlueprints) { if (empty($this->systemBlueprints)) {
// Register all blueprints from the blueprints stream. // Register all blueprints from the blueprints stream.
$this->systemBlueprints = $this->findBlueprints('blueprints://pages'); $this->systemBlueprints = $this->findBlueprints('blueprints://pages');
foreach ($this->systemBlueprints as $type => $blueprint) { foreach ($this->systemBlueprints as $type => $blueprint) {
@@ -178,7 +178,7 @@ class InitializeProcessor extends ProcessorBase
$grav['plugins']->setup(); $grav['plugins']->setup();
if (defined('GRAV_SCHEMA') && $config->get('versions') === null) { if (defined('GRAV_SCHEMA') && $config->get('versions') === null) {
$filename = GRAV_ROOT . '/user/config/versions.yaml'; $filename = USER_DIR . 'config/versions.yaml';
if (!is_file($filename)) { if (!is_file($filename)) {
$versions = [ $versions = [
'core' => [ 'core' => [
@@ -30,7 +30,7 @@ class StreamsServiceProvider implements ServiceProviderInterface
public function register(Container $container) public function register(Container $container)
{ {
$container['locator'] = function (Container $container) { $container['locator'] = function (Container $container) {
$locator = new UniformResourceLocator(GRAV_ROOT); $locator = new UniformResourceLocator(GRAV_WEBROOT);
/** @var Setup $setup */ /** @var Setup $setup */
$setup = $container['setup']; $setup = $container['setup'];
+2 -2
View File
@@ -128,12 +128,12 @@ class Session extends \Grav\Framework\Session\Session
/** @var Uri $uri */ /** @var Uri $uri */
$uri = $grav['uri']; $uri = $grav['uri'];
/** @var Forms|null $form */ /** @var Forms|null $form */
$form = $grav['forms']->getActiveForm(); $form = $grav['forms']->getActiveForm(); // @phpstan-ignore-line
$sessionField = base64_encode($uri->url); $sessionField = base64_encode($uri->url);
/** @var FormFlash|null $flash */ /** @var FormFlash|null $flash */
$flash = $form ? $form->getFlash() : null; $flash = $form ? $form->getFlash() : null; // @phpstan-ignore-line
$object = $flash && method_exists($flash, 'getLegacyFiles') ? [$sessionField => $flash->getLegacyFiles()] : null; $object = $flash && method_exists($flash, 'getLegacyFiles') ? [$sessionField => $flash->getLegacyFiles()] : null;
} }
} }
+2 -2
View File
@@ -205,8 +205,8 @@ class Uri
// set active language // set active language
$uri = $language->setActiveFromUri($uri); $uri = $language->setActiveFromUri($uri);
// split the URL and params // split the URL and params (and make sure that the path isn't seen as domain)
$bits = parse_url($uri); $bits = parse_url('http://domain.com' . $uri);
//process fragment //process fragment
if (isset($bits['fragment'])) { if (isset($bits['fragment'])) {
+10 -3
View File
@@ -131,11 +131,18 @@ class User extends Data implements UserInterface
} }
// if plain text password, hash it and remove plain text // if plain text password, hash it and remove plain text
$password = $this->get('password'); $password = $this->get('password') ?? $this->get('password1');
if ($password) { if (null !== $password && '' !== $password) {
$password2 = $this->get('password2');
if (!\is_string($password) || ($password2 && $password !== $password2)) {
throw new \RuntimeException('Passwords did not match.');
}
$this->set('hashed_password', Authentication::create($password)); $this->set('hashed_password', Authentication::create($password));
$this->undef('password');
} }
$this->undef('password');
$this->undef('password1');
$this->undef('password2');
$data = $this->items; $data = $this->items;
if ($username === $data['username']) { if ($username === $data['username']) {
@@ -37,10 +37,9 @@ use function is_scalar;
/** /**
* Class FlexCollection * Class FlexCollection
* @package Grav\Framework\Flex * @package Grav\Framework\Flex
* @template TKey
* @template T of FlexObjectInterface * @template T of FlexObjectInterface
* @extends ObjectCollection<TKey,T> * @extends ObjectCollection<string,T>
* @implements FlexCollectionInterface<TKey,T> * @implements FlexCollectionInterface<T>
*/ */
class FlexCollection extends ObjectCollection implements FlexCollectionInterface class FlexCollection extends ObjectCollection implements FlexCollectionInterface
{ {
@@ -460,7 +459,6 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
/** /**
* @param string $key * @param string $key
* @return array * @return array
* @phpstan-param TKey $key
*/ */
public function getMetaData(string $key): array public function getMetaData(string $key): array
{ {
@@ -491,7 +489,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
* @param string|null $scope * @param string|null $scope
* @param UserInterface|null $user * @param UserInterface|null $user
* @return static * @return static
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function isAuthorized(string $action, string $scope = null, UserInterface $user = null) public function isAuthorized(string $action, string $scope = null, UserInterface $user = null)
{ {
@@ -559,7 +557,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
* @param array $elements Elements. * @param array $elements Elements.
* @param string|null $keyField * @param string|null $keyField
* @return static * @return static
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
*/ */
protected function createFrom(array $elements, $keyField = null) protected function createFrom(array $elements, $keyField = null)
@@ -46,7 +46,6 @@ use function is_callable;
* Class FlexDirectory * Class FlexDirectory
* @package Grav\Framework\Flex * @package Grav\Framework\Flex
* @template T * @template T
* @template TKey
*/ */
class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
{ {
@@ -309,7 +308,7 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
* @param array|null $keys Array of keys. * @param array|null $keys Array of keys.
* @param string|null $keyField Field to be used as the key. * @param string|null $keyField Field to be used as the key.
* @return FlexCollectionInterface * @return FlexCollectionInterface
* @phpstan-return FlexCollectionInterface<TKey,T> * @phpstan-return FlexCollectionInterface<T>
*/ */
public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface
{ {
+5 -7
View File
@@ -33,11 +33,10 @@ use function in_array;
/** /**
* Class FlexIndex * Class FlexIndex
* @package Grav\Framework\Flex * @package Grav\Framework\Flex
* @template TKey
* @template T of FlexObjectInterface * @template T of FlexObjectInterface
* @template C of FlexCollectionInterface * @template C of FlexCollectionInterface
* @extends ObjectIndex<TKey,T> * @extends ObjectIndex<string,T>
* @implements FlexIndexInterface<TKey,T> * @implements FlexIndexInterface<T>
* @mixin C * @mixin C
*/ */
class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexIndexInterface class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexIndexInterface
@@ -54,7 +53,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
/** /**
* @param FlexDirectory $directory * @param FlexDirectory $directory
* @return static * @return static
* @phpstan-return static<TKey,T,C> * @phpstan-return static<T,C>
*/ */
public static function createFromStorage(FlexDirectory $directory) public static function createFromStorage(FlexDirectory $directory)
{ {
@@ -343,7 +342,6 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
/** /**
* @param string $key * @param string $key
* @return array * @return array
* @phpstan-param TKey $key
*/ */
public function getMetaData($key): array public function getMetaData($key): array
{ {
@@ -370,7 +368,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
/** /**
* @param array $orderings * @param array $orderings
* @return static * @return static
* @phpstan-return static<TKey,T,C> * @phpstan-return static<T,C>
*/ */
public function orderBy(array $orderings) public function orderBy(array $orderings)
{ {
@@ -538,7 +536,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
* @param array $entries * @param array $entries
* @param string|null $keyField * @param string|null $keyField
* @return static * @return static
* @phpstan-return static<TKey,T,C> * @phpstan-return static<T,C>
*/ */
protected function createFrom(array $entries, string $keyField = null) protected function createFrom(array $entries, string $keyField = null)
{ {
@@ -22,9 +22,8 @@ use InvalidArgumentException;
* *
* @used-by \Grav\Framework\Flex\FlexCollection * @used-by \Grav\Framework\Flex\FlexCollection
* @since 1.6 * @since 1.6
* @template TKey
* @template T * @template T
* @extends ObjectCollectionInterface<TKey,T> * @extends ObjectCollectionInterface<string,T>
*/ */
interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionInterface, NestedObjectInterface interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionInterface, NestedObjectInterface
{ {
@@ -58,7 +57,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* @param string|string[]|null $properties Properties to search for, defaults to configured properties. * @param string|string[]|null $properties Properties to search for, defaults to configured properties.
* @param array|null $options Search options, defaults to configured options. * @param array|null $options Search options, defaults to configured options.
* @return FlexCollectionInterface Returns a Flex Collection with only matching objects. * @return FlexCollectionInterface Returns a Flex Collection with only matching objects.
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
* @api * @api
*/ */
public function search(string $search, $properties = null, array $options = null); public function search(string $search, $properties = null, array $options = null);
@@ -69,7 +68,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* @param array $orderings Pair of [property => 'ASC'|'DESC', ...]. * @param array $orderings Pair of [property => 'ASC'|'DESC', ...].
* *
* @return FlexCollectionInterface Returns a sorted version from the collection. * @return FlexCollectionInterface Returns a sorted version from the collection.
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function sort(array $orderings); public function sort(array $orderings);
@@ -78,7 +77,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* *
* @param array $filters * @param array $filters
* @return FlexCollectionInterface * @return FlexCollectionInterface
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function filterBy(array $filters); public function filterBy(array $filters);
@@ -114,7 +113,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* *
* @param string|null $keyField Switch key field of the collection. * @param string|null $keyField Switch key field of the collection.
* @return FlexCollectionInterface Returns a new Flex Collection with new key field. * @return FlexCollectionInterface Returns a new Flex Collection with new key field.
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
* @api * @api
*/ */
public function withKeyField(string $keyField = null); public function withKeyField(string $keyField = null);
@@ -123,7 +122,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* Get Flex Index from the Flex Collection. * Get Flex Index from the Flex Collection.
* *
* @return FlexIndexInterface Returns a Flex Index from the current collection. * @return FlexIndexInterface Returns a Flex Index from the current collection.
* @phpstan-return FlexIndexInterface<TKey,T> * @phpstan-return FlexIndexInterface<T>
*/ */
public function getIndex(); public function getIndex();
@@ -131,7 +130,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* Load all the objects into memory, * Load all the objects into memory,
* *
* @return FlexCollectionInterface * @return FlexCollectionInterface
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function getCollection(); public function getCollection();
@@ -140,7 +139,6 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* *
* @param string $key Key. * @param string $key Key.
* @return array * @return array
* @phpstan-param TKey $key
*/ */
public function getMetaData(string $key): array; public function getMetaData(string $key): array;
} }
@@ -21,9 +21,8 @@ use Grav\Framework\Flex\FlexDirectory;
* *
* @used-by \Grav\Framework\Flex\FlexIndex * @used-by \Grav\Framework\Flex\FlexIndex
* @since 1.6 * @since 1.6
* @template TKey
* @template T * @template T
* @extends FlexCollectionInterface<TKey,T> * @extends FlexCollectionInterface<T>
*/ */
interface FlexIndexInterface extends FlexCollectionInterface interface FlexIndexInterface extends FlexCollectionInterface
{ {
@@ -20,9 +20,8 @@ use function is_int;
/** /**
* Class FlexPageCollection * Class FlexPageCollection
* @package Grav\Plugin\FlexObjects\Types\FlexPages * @package Grav\Plugin\FlexObjects\Types\FlexPages
* @template TKey
* @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface * @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface
* @extends FlexCollection<TKey,T> * @extends FlexCollection<T>
*/ */
class FlexPageCollection extends FlexCollection class FlexPageCollection extends FlexCollection
{ {
@@ -53,7 +52,7 @@ class FlexPageCollection extends FlexCollection
/** /**
* @param bool $bool * @param bool $bool
* @return static * @return static
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function withPublished(bool $bool = true) public function withPublished(bool $bool = true)
{ {
@@ -65,7 +64,7 @@ class FlexPageCollection extends FlexCollection
/** /**
* @param bool $bool * @param bool $bool
* @return static * @return static
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function withVisible(bool $bool = true) public function withVisible(bool $bool = true)
{ {
@@ -77,7 +76,7 @@ class FlexPageCollection extends FlexCollection
/** /**
* @param bool $bool * @param bool $bool
* @return static * @return static
* @phpstan-return static<TKey,T> * @phpstan-return static<T>
*/ */
public function withRoutable(bool $bool = true) public function withRoutable(bool $bool = true)
{ {
@@ -22,10 +22,9 @@ use Grav\Framework\Flex\FlexIndex;
* @method FlexPageIndex withPublished(bool $bool = true) * @method FlexPageIndex withPublished(bool $bool = true)
* @method FlexPageIndex withVisible(bool $bool = true) * @method FlexPageIndex withVisible(bool $bool = true)
* *
* @template TKey
* @template T of FlexPageObject * @template T of FlexPageObject
* @template C of FlexPageCollection * @template C of FlexPageCollection
* @extends FlexIndex<TKey,T,C> * @extends FlexIndex<T,C>
*/ */
class FlexPageIndex extends FlexIndex class FlexPageIndex extends FlexIndex
{ {
@@ -205,10 +205,10 @@ trait FlexMediaTrait
$filename = $info['path'] ?? $info['name']; $filename = $info['path'] ?? $info['name'];
} }
/** @var Medium|null $thumbFile */ /** @var Medium|null $imageFile */
$imageFile = $media[$filename]; $imageFile = $media[$filename];
/** @var Medium|null $thumbFile */ /** @var Medium|null $originalFile */
$originalFile = $originalMedia ? $originalMedia[$filename] : null; $originalFile = $originalMedia ? $originalMedia[$filename] : null;
$url = $imageFile ? $imageFile->url() : null; $url = $imageFile ? $imageFile->url() : null;
@@ -384,7 +384,7 @@ trait FlexMediaTrait
$updated = true; $updated = true;
if ($medium) { if ($medium) {
$media->add($filename, $medium); $media->add($filename, $medium);
} else { } elseif (is_callable([$media, 'hide'])) {
$media->hide($filename); $media->hide($filename);
} }
} }
+2 -2
View File
@@ -232,7 +232,7 @@ ERR;
$this->location = dirname($location, 4); $this->location = dirname($location, 4);
$versions = Versions::instance(GRAV_ROOT . '/user/config/versions.yaml'); $versions = Versions::instance(USER_DIR . 'config/versions.yaml');
$this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', $this->getVersion(), $versions); $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', $this->getVersion(), $versions);
$this->updater->preflight(); $this->updater->preflight();
@@ -280,7 +280,7 @@ ERR;
{ {
// Finalize can be run without installing Grav first. // Finalize can be run without installing Grav first.
if (!$this->updater) { if (!$this->updater) {
$versions = Versions::instance(GRAV_ROOT . '/user/config/versions.yaml'); $versions = Versions::instance(USER_DIR . 'config/versions.yaml');
$this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', GRAV_VERSION, $versions); $this->updater = new VersionUpdater('core/grav', __DIR__ . '/updates', GRAV_VERSION, $versions);
$this->updater->install(); $this->updater->install();
} }
+1 -1
View File
@@ -36,7 +36,7 @@ final class Versions
*/ */
public static function instance(string $filename = null): self public static function instance(string $filename = null): self
{ {
$filename = $filename ?? GRAV_ROOT . '/user/config/versions.yaml'; $filename = $filename ?? USER_DIR . 'config/versions.yaml';
if (!isset(self::$instance[$filename])) { if (!isset(self::$instance[$filename])) {
self::$instance[$filename] = new self($filename); self::$instance[$filename] = new self($filename);
@@ -0,0 +1,7 @@
---
title: Accueil
body_classes: modular
visible: true
debugger: true
---
-13
View File
@@ -1,13 +0,0 @@
---
title: Accueil
body_classes: modular
visible: true
debugger: true
---
# EPAU
## L'EUROPE DES PROJETS ARCHITECTURAUX ET URBAINS
Organisme national de recherche et dexpérimentation, sous la tutelle des Ministères en charge de larchitecture et de lurbanisme, la Cité de lArchitecture et du Patrimoine et de lAssociation Europan France
@@ -36,4 +36,4 @@ process:
twig: false twig: false
--- ---
# Ressources
@@ -18,6 +18,4 @@ admin:
debugger: true debugger: true
--- ---
# Gouvernance
## Le conseil dadministration de lEurope des projets architecturaux et urbains et les Directions de programmes de lEurope des projets architecturaux urbains
+4 -6
View File
@@ -3,9 +3,7 @@ title: Contact
body_classes: modular body_classes: modular
--- ---
# Contact CONTACT :
### Fabienne Dran Fabienne.Dran@developpement-durable.gouv.fr
#### Assistante de direction + 33 (0)1 40 81 9327
Fabienne.Dran@developpement-durable.gouv.fr +33 (0)7 86 5033 31
+ 33 (0)1 40 81 93 27
+33 (0)7 86 50 33 31
@@ -91,8 +91,7 @@ sub {
bottom: -0.25em; } bottom: -0.25em; }
img { img {
border: 0; border: 0; }
max-width: 15rem; }
svg:not(:root) { svg:not(:root) {
overflow: hidden; } overflow: hidden; }
@@ -82,8 +82,7 @@ b, strong, label, th {
#header #logo img { #header #logo img {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-flow: row; flex-flow: row; }
max-height: 5rem; }
#header.scrolled { #header.scrolled {
height: 3rem; height: 3rem;
background-color: rgba(255, 255, 255, 0.9) !important; background-color: rgba(255, 255, 255, 0.9) !important;
@@ -825,9 +824,10 @@ ul.pagination {
#logo { #logo {
display: flex; display: flex;
flex-direction: row; } flex-direction: row; }
#logo img {
#logo img { padding: 0.5rem;
padding: 0.5rem; } max-height: 3rem;
margin: auto; }
.callout { .callout {
padding-top: 0.5rem; } padding-top: 0.5rem; }
@@ -867,26 +867,47 @@ ul.pagination {
width: 100%; } } width: 100%; } }
.after-h1 .test { .after-h1 .test {
opacity: 0; animation: anim 2.5s 1 normal ease-in-out forwards; }
transition: opacity 1s ease-in-out;
animation: anim 5s 500ms 1 normal ease-in-out forwards; }
.after-h1:hover .test {
opacity: 1; }
.programmes { .programmes {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
background: url("/user/themes/epau-antimatter/images/14360_default_big.jpg") 0px 0px no-repeat, url("/user/themes/epau-antimatter/images/10361_web_01.jpg") 1200px 300px no-repeat, url("/user/themes/epau-antimatter/images/hyperliens_marseille_.PNG") 0px 700px no-repeat, url("/user/themes/epau-antimatter/images/jeux-olypiques-paris-2024-village-athle-lot-e2.jpg") right no-repeat;
/* On bottom, like z-index: 1; */
background-color: #d5d2d1; background-color: #d5d2d1;
z-index: -1;
justify-content: center; justify-content: center;
padding-left: 15%; padding-left: 15%;
padding-right: 15%; padding-right: 15%;
padding-top: 8rem; padding-top: 8rem;
padding-bottom: 8rem; } padding-bottom: 8rem; }
.paralax {
position: absolute !important;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between; }
.paralax #photo1 {
position: relative;
top: -60px; }
.paralax #photo2 {
z-index: 0;
width: 700px !important;
position: relative;
top: 260px; }
.paralax #photo3 {
z-index: 0;
width: 700px !important;
position: relative;
top: 500px; }
.paralax #photo4 {
z-index: 0;
width: 700px !important;
position: relative;
top: 300px; }
.programme { .programme {
z-index: 1;
max-width: 35%; max-width: 35%;
padding: 1.5rem; padding: 1.5rem;
background-color: white; background-color: white;
@@ -895,7 +916,7 @@ ul.pagination {
text-transform: uppercase; text-transform: uppercase;
line-height: 1.2; } line-height: 1.2; }
.programme img { .programme img {
max-height: 15%; } max-height: 4rem; }
.programme p { .programme p {
font-family: "Sarabun", sans-serif; font-family: "Sarabun", sans-serif;
font-weight: 500; font-weight: 500;
@@ -949,7 +970,9 @@ ul.pagination {
width: 15rem !important; width: 15rem !important;
height: 15rem !important; } height: 15rem !important; }
.mozaique_personnes .equipe .personne .mozaique .photo img { .mozaique_personnes .equipe .personne .mozaique .photo img {
width: 100%; } object-fit: cover;
width: 100%;
height: 100%; }
.mozaique_personnes .equipe .personne .mozaique .info { .mozaique_personnes .equipe .personne .mozaique .info {
background-color: #fff; background-color: #fff;
display: flex; display: flex;
@@ -98,7 +98,7 @@ sub {
img { img {
border: 0; border: 0;
max-width: 15rem; // max-width: 15rem;
} }
svg:not(:root) { svg:not(:root) {
@@ -52,48 +52,15 @@
#logo { #logo {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
img {
padding: 0.5rem;
max-height: 3rem;
margin:auto;
}
} }
#logo img {
padding: 0.5rem;
}
//tentative animation when in View
// @media () {
//
// @viewport {
//
// }
// rect.after-h1 {
// animation-duration: 4s;
// animation-timing-function: linear;
// animation-timeline: grow-timeline;
// }
//
// @scroll-timeline grow-timeline {
// source: selector(.test);
// orientation: block;
// scroll-offsets: 250px, 300px;
// }
//
// @keyframes grow {
// to { transform: translate(300px) }
// }
// @k
// @keyframes souligne {
// 0% { width: 0.5%;
// }
// 100%{
// width: 50%;
// }
// }
//
// // selecteur:hover,
// // selecteur:focus,
// selecteur:hover{
// animation: souligne 2s ease-in-out;
// }
@@ -135,6 +102,7 @@
} }
.titre_bsn { .titre_bsn {
display: block; display: block;
margin-left: 40%; margin-left: 40%;
// padding-right: 15%; // padding-right: 15%;
@@ -152,84 +120,51 @@
@keyframes anim { @keyframes anim {
0% {width: 0%;} 0% {width: 0%;}
100% {width: 100%}
100% {width: 100%;}
} }
.after-h1 { // fonctionne mais manque "when in View" .after-h1 {
.test {
opacity: 0;
transition: opacity 1s ease-in-out;
animation: anim 5s 500ms 1 normal ease-in-out forwards;
}
&:hover { .test {
.test { // opacity: 0;
opacity: 1; // transition: opacity 1s ease-in-out;
} animation: anim 2.5s 1 normal ease-in-out forwards;
}
}
// &:hover {
// .test {
// opacity: 1;
// }
// opacity: 1; // opacity: 1;
// transition: width 5s ease-in-out; // transition: width 5s ease-in-out;
}
}
// fond images en grille pour parallax
// #background {
// background-color: #d5d2d1;
// display: grid;
// grid-template-columns: repeat(5, 1fr);
// grid-template-rows: repeat(8, 5vw);
// grid-gap: 15px;
// }
//
// #background img {
// max-width: 100% !important;
// max-height: 100% !important;
// // object-fit: cover;
// }
// .item-1 {
// grid-column-start: 1;
// grid-column-end: 3;
// grid-row-start: 1;
// grid-row-end: 5;
// }
//
// .item-2 {
// grid-column-start: 3;
// grid-column-end: 5;
// grid-row-start: 1;
// grid-row-end: 5;
// }
//
// .item-3 {
// grid-column-start: 5 ;
// grid-column-end: 1;
// grid-row-start: 9;
// grid-row-end: 6;
// }
//
// .item-4 {
// grid-column-start: 1;
// grid-column-end: 3;
// grid-row-start: 1;
// grid-row-end: 3;
// }
.programmes { .programmes {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
background: // background-image:
url("/user/themes/epau-antimatter/images/14360_default_big.jpg") 0px 0px no-repeat, /* On top, like z-index: 4; */ // url("/user/themes/epau-antimatter/images/14360_default_big.jpg") ,
url("/user/themes/epau-antimatter/images/10361_web_01.jpg") 1200px 300px no-repeat, /* like z-index: 3; */ // url("/user/themes/epau-antimatter/images/10361_web_01.jpg") ,
url("/user/themes/epau-antimatter/images/hyperliens_marseille_.PNG") 0px 700px no-repeat, /* like z-index: 2; */ // url("/user/themes/epau-antimatter/images/hyperliens_marseille_.PNG") ,
url("/user/themes/epau-antimatter/images/jeux-olypiques-paris-2024-village-athle-lot-e2.jpg") right no-repeat; /* On bottom, like z-index: 1; */ // url("/user/themes/epau-antimatter/images/jeux-olypiques-paris-2024-village-athle-lot-e2.jpg") ;
//
// background-attachment: fixed;
//
// background-position: 50% -50px;
// position: sticky;
// transform: translateY(-1);
// min-height: 500px;
background-color: #d5d2d1; background-color: #d5d2d1;
z-index: -1;
justify-content: center; justify-content: center;
padding-left: 15%; padding-left: 15%;
padding-right: 15%; padding-right: 15%;
@@ -238,20 +173,61 @@
padding-bottom: 8rem; padding-bottom: 8rem;
} }
.paralax {
position: absolute !important;
width: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
// transform: translate3d(0px, -128px, 0px);
#photo1 {
position: relative;
top: -60px;
}
#photo2 {
z-index: 0;
width:700px !important;
position: relative;
top: 260px;
}
#photo3 {
z-index: 0;
width:700px !important;
position: relative;
top: 500px;
}
#photo4 {
z-index: 0;
width:700px !important;
position: relative;
top: 300px;
}
}
.programme { .programme {
z-index: 1;
max-width: 35%; max-width: 35%;
// min-width: // min-width:
padding: 1.5rem; padding: 1.5rem;
background-color: white; background-color: white;
margin: 0.4rem; margin: 0.4rem;
h4 { h4 {
text-transform: uppercase; text-transform: uppercase;
line-height: 1.2; line-height: 1.2;
} }
img { img {
max-height: 15%; max-height: 4rem;
} }
p { p {
@@ -403,12 +379,14 @@
width: 15rem !important; width: 15rem !important;
height: 15rem !important; height: 15rem !important;
// object-fit: cover; // object-fit: cover;
// background-size: cover;
img { img {
// maxwidth: 15rem !important; // maxwidth: 15rem !important;
// height: 15rem !important; // height: 15rem !important;
// background-size: cover; object-fit: cover;
width: 100%; width: 100%;
height: 100%;
} }
@@ -15,7 +15,7 @@ $dropdown-color: #f6f6f6;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
flex-flow: row; flex-flow: row;
max-height: $header-height; // max-height: $header-height;
} }
// scroll based changes // scroll based changes
@@ -200,7 +200,7 @@ $dropdown-color: #f6f6f6;
&.active > a { &.active > a {
background-color: darken($dropdown-color, 4%); background-color: darken($dropdown-color, 4%);
color: $core-accent; color: $core-accent;
} }
@@ -1,5 +1,5 @@
<div class="gouvernance"> <div class="gouvernance after-h1">
<div class="titre_bsn"> <div class="titre_bsn">
@@ -7,7 +7,7 @@
<div class="test" > <div class="test" >
<svg width="100%" height="0.5rem"> <svg width="100%" height="0.5rem">
<rect class="after-h1" width="100%" height="100%" style="fill:rgb(255,255,255)" /> <rect class="" width="100%" height="100%" style="fill:rgb(255,255,255)" />
</svg> </svg>
</div> </div>
<p> Le conseil dadministration de lEurope des projets architecturaux et urbains et les Directions de programmes de lEurope des projets architecturaux urbains</p> <p> Le conseil dadministration de lEurope des projets architecturaux et urbains et les Directions de programmes de lEurope des projets architecturaux urbains</p>
@@ -1,12 +1,20 @@
<div class="programmes{{ page.header.class}}"> <div class="programmes{{ page.header.class}}">
<div class="background paralax">
<img id="photo1" src="/user/themes/epau-antimatter/images/14360_default_big.jpg" alt="photo 1" />
<img id="photo2" src="/user/themes/epau-antimatter/images/10361_web_01.jpg" alt="photo 2" />
<img id="photo3" src="/user/themes/epau-antimatter/images/hyperliens_marseille_.PNG" alt="photo 3" />
<img id="photo4" src="/user/themes/epau-antimatter/images/jeux-olypiques-paris-2024-village-athle-lot-e2.jpg" alt="photo 4" />
</div>
{{ content|raw }} {{ content|raw }}
{% for programme in page.header.programmes %} {% for programme in page.header.programmes %}
<div class="programme"> <div class="programme">
<a href="{{programme.site}}"> <a href="{{programme.site}}" target="_blank">
{% if programme.logo %} {% if programme.logo %}
<img src="{{page.media[programme.logo].url|e }}" alt="logo du programme {{programme.nom_du_programme}}" /> <img src="{{page.media[programme.logo].url|e }}" alt="logo du programme {{programme.nom_du_programme}}" />
{% endif %} {% endif %}
@@ -1,12 +1,12 @@
<div class="titre_nsb"> <div class="titre_nsb after-h1">
<h1>Ressources</h1> <h1>Ressources</h1>
<div class="test" > <div class="test" >
<svg width="100%" height="0.5rem"> <svg width="100%" height="0.5rem">
<rect class="after-h1" width="100%" height="100%" style="fill:rgb(0,0,0)" /> <rect class="" width="100%" height="100%" style="fill:rgb(0,0,0)" />
</svg> </svg>
</div> </div>
<!-- <div class="after-h1-finish"> <!-- <div class="after-h1-finish">