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
## 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)
[![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
@@ -62,48 +74,6 @@ This will display all the available plugins and then you can install one or more
$ 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
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 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
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",
"version": "2.10.0",
"version": "2.12.0",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "6ecda5217bf048088b891f7403b262906be5a957"
"reference": "d501fd2658d55491a2295ff600ae5978eaad7403"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/6ecda5217bf048088b891f7403b262906be5a957",
"reference": "6ecda5217bf048088b891f7403b262906be5a957",
"url": "https://api.github.com/repos/filp/whoops/zipball/d501fd2658d55491a2295ff600ae5978eaad7403",
"reference": "d501fd2658d55491a2295ff600ae5978eaad7403",
"shasum": ""
},
"require": {
@@ -701,7 +701,7 @@
],
"support": {
"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": [
{
@@ -709,7 +709,7 @@
"type": "github"
}
],
"time": "2021-03-16T12:00:00+00:00"
"time": "2021-03-30T12:00:00+00:00"
},
{
"name": "gregwar/cache",
@@ -812,16 +812,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "1.7.0",
"version": "1.8.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3"
"reference": "35ea11d335fd638b5882ff1725228b3d35496ab1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3",
"reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1",
"reference": "35ea11d335fd638b5882ff1725228b3d35496ab1",
"shasum": ""
},
"require": {
@@ -881,9 +881,9 @@
],
"support": {
"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",
@@ -2246,16 +2246,16 @@
},
{
"name": "symfony/console",
"version": "v4.4.20",
"version": "v4.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "c98349bda966c70d6c08b4cd8658377c94166492"
"reference": "1ba4560dbbb9fcf5ae28b61f71f49c678086cf23"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/c98349bda966c70d6c08b4cd8658377c94166492",
"reference": "c98349bda966c70d6c08b4cd8658377c94166492",
"url": "https://api.github.com/repos/symfony/console/zipball/1ba4560dbbb9fcf5ae28b61f71f49c678086cf23",
"reference": "1ba4560dbbb9fcf5ae28b61f71f49c678086cf23",
"shasum": ""
},
"require": {
@@ -2315,7 +2315,7 @@
"description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/console/tree/v4.4.20"
"source": "https://github.com/symfony/console/tree/v4.4.21"
},
"funding": [
{
@@ -2331,7 +2331,7 @@
"type": "tidelift"
}
],
"time": "2021-02-22T18:44:15+00:00"
"time": "2021-03-26T09:23:24+00:00"
},
{
"name": "symfony/contracts",
@@ -2512,16 +2512,16 @@
},
{
"name": "symfony/http-client",
"version": "v4.4.20",
"version": "v4.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
"reference": "67c5af7489b3c2eea771abd973243f5c58f5fb40"
"reference": "911177e186b82e5b9a9f41c13af53699b6745657"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-client/zipball/67c5af7489b3c2eea771abd973243f5c58f5fb40",
"reference": "67c5af7489b3c2eea771abd973243f5c58f5fb40",
"url": "https://api.github.com/repos/symfony/http-client/zipball/911177e186b82e5b9a9f41c13af53699b6745657",
"reference": "911177e186b82e5b9a9f41c13af53699b6745657",
"shasum": ""
},
"require": {
@@ -2572,7 +2572,7 @@
"description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-client/tree/v4.4.20"
"source": "https://github.com/symfony/http-client/tree/v4.4.21"
},
"funding": [
{
@@ -2588,7 +2588,7 @@
"type": "tidelift"
}
],
"time": "2021-02-25T18:06:45+00:00"
"time": "2021-03-25T17:52:07+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -3055,16 +3055,16 @@
},
{
"name": "symfony/var-dumper",
"version": "v4.4.20",
"version": "v4.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "a1eab2f69906dc83c5ddba4632180260d0ab4f7f"
"reference": "0da0e174f728996f5d5072d6a9f0a42259dbc806"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/a1eab2f69906dc83c5ddba4632180260d0ab4f7f",
"reference": "a1eab2f69906dc83c5ddba4632180260d0ab4f7f",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/0da0e174f728996f5d5072d6a9f0a42259dbc806",
"reference": "0da0e174f728996f5d5072d6a9f0a42259dbc806",
"shasum": ""
},
"require": {
@@ -3124,7 +3124,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v4.4.20"
"source": "https://github.com/symfony/var-dumper/tree/v4.4.21"
},
"funding": [
{
@@ -3140,20 +3140,20 @@
"type": "tidelift"
}
],
"time": "2021-01-27T09:09:26+00:00"
"time": "2021-03-27T19:49:03+00:00"
},
{
"name": "symfony/yaml",
"version": "v4.4.20",
"version": "v4.4.21",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "29e61305e1c79d25f71060903982ead8f533e267"
"reference": "3871c720871029f008928244e56cf43497da7e9d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/29e61305e1c79d25f71060903982ead8f533e267",
"reference": "29e61305e1c79d25f71060903982ead8f533e267",
"url": "https://api.github.com/repos/symfony/yaml/zipball/3871c720871029f008928244e56cf43497da7e9d",
"reference": "3871c720871029f008928244e56cf43497da7e9d",
"shasum": ""
},
"require": {
@@ -3195,7 +3195,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v4.4.20"
"source": "https://github.com/symfony/yaml/tree/v4.4.21"
},
"funding": [
{
@@ -3211,7 +3211,7 @@
"type": "tidelift"
}
],
"time": "2021-02-22T15:36:50+00:00"
"time": "2021-03-05T17:58:50+00:00"
},
{
"name": "twig/twig",
@@ -3415,16 +3415,16 @@
},
{
"name": "codeception/codeception",
"version": "4.1.18",
"version": "4.1.19",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
"reference": "f47547bac347dfb5ea5351ff91148cbcc08e6818"
"reference": "138dc9345a81ec994dcd6b9680c501a752a37b00"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/f47547bac347dfb5ea5351ff91148cbcc08e6818",
"reference": "f47547bac347dfb5ea5351ff91148cbcc08e6818",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/138dc9345a81ec994dcd6b9680c501a752a37b00",
"reference": "138dc9345a81ec994dcd6b9680c501a752a37b00",
"shasum": ""
},
"require": {
@@ -3498,7 +3498,7 @@
],
"support": {
"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": [
{
@@ -3506,7 +3506,7 @@
"type": "open_collective"
}
],
"time": "2021-02-23T17:11:42+00:00"
"time": "2021-03-28T13:26:08+00:00"
},
{
"name": "codeception/lib-asserts",
@@ -3893,22 +3893,22 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "7.2.0",
"version": "7.3.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79"
"reference": "7008573787b430c1c1f650e3722d9bba59967628"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79",
"reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628",
"reference": "7008573787b430c1c1f650e3722d9bba59967628",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.4",
"guzzlehttp/psr7": "^1.7",
"guzzlehttp/psr7": "^1.7 || ^2.0",
"php": "^7.2.5 || ^8.0",
"psr/http-client": "^1.0"
},
@@ -3916,6 +3916,7 @@
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"ext-curl": "*",
"php-http/client-integration-tests": "^3.0",
"phpunit/phpunit": "^8.5.5 || ^9.3.5",
@@ -3929,7 +3930,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "7.1-dev"
"dev-master": "7.3-dev"
}
},
"autoload": {
@@ -3971,7 +3972,7 @@
],
"support": {
"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": [
{
@@ -3991,7 +3992,7 @@
"type": "github"
}
],
"time": "2020-10-10T11:47:56+00:00"
"time": "2021-03-23T11:33:13+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -4433,16 +4434,16 @@
},
{
"name": "phpspec/prophecy",
"version": "1.12.2",
"version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
"reference": "245710e971a030f42e08f4912863805570f23d39"
"reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
"reference": "245710e971a030f42e08f4912863805570f23d39",
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
"reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
"shasum": ""
},
"require": {
@@ -4494,22 +4495,22 @@
],
"support": {
"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",
"version": "0.12.81",
"version": "0.12.82",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "0dd5b0ebeff568f7000022ea5f04aa86ad3124b8"
"reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/0dd5b0ebeff568f7000022ea5f04aa86ad3124b8",
"reference": "0dd5b0ebeff568f7000022ea5f04aa86ad3124b8",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
"reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
"shasum": ""
},
"require": {
@@ -4540,7 +4541,7 @@
"description": "PHPStan - PHP Static Analysis Tool",
"support": {
"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": [
{
@@ -4556,7 +4557,7 @@
"type": "tidelift"
}
],
"time": "2021-03-08T22:03:02+00:00"
"time": "2021-03-19T06:08:17+00:00"
},
{
"name": "phpstan/phpstan-deprecation-rules",
@@ -4611,16 +4612,16 @@
},
{
"name": "phpunit/php-code-coverage",
"version": "9.2.5",
"version": "9.2.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1"
"reference": "f6293e1b30a2354e8428e004689671b83871edde"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1",
"reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde",
"reference": "f6293e1b30a2354e8428e004689671b83871edde",
"shasum": ""
},
"require": {
@@ -4676,7 +4677,7 @@
],
"support": {
"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": [
{
@@ -4684,7 +4685,7 @@
"type": "github"
}
],
"time": "2020-11-28T06:44:49+00:00"
"time": "2021-03-28T07:26:59+00:00"
},
{
"name": "phpunit/php-file-iterator",
@@ -4929,16 +4930,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.5.3",
"version": "9.5.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41"
"reference": "c73c6737305e779771147af66c96ca6a7ed8a741"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/27241ac75fc37ecf862b6e002bf713b6566cbe41",
"reference": "27241ac75fc37ecf862b6e002bf713b6566cbe41",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c73c6737305e779771147af66c96ca6a7ed8a741",
"reference": "c73c6737305e779771147af66c96ca6a7ed8a741",
"shasum": ""
},
"require": {
@@ -5016,7 +5017,7 @@
],
"support": {
"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": [
{
@@ -5028,7 +5029,7 @@
"type": "github"
}
],
"time": "2021-03-17T07:30:34+00:00"
"time": "2021-03-23T07:16:29+00:00"
},
{
"name": "psr/http-client",
+39
View File
@@ -1282,6 +1282,45 @@ form:
validate:
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:
type: tab
title: PLUGIN_ADMIN.SESSION
-8
View File
@@ -35,18 +35,10 @@ form:
validate:
type: textarea
header.media_order:
type: pagemedia
label: PLUGIN_ADMIN.PAGE_MEDIA
background_image:
type: filepicker
label: image pour fond parallax
options:
type: tab
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
auto_fix_orientation: true # Automatically fix the image orientation based on the Exif data
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:
loading: auto # Let browser pick [auto|lazy|eager]
+15 -8
View File
@@ -8,7 +8,7 @@
// Some standard defines
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_TESTING', false);
@@ -27,10 +27,17 @@ if (!defined('GRAV_ROOT')) {
$path = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, getenv('GRAV_ROOT') ?: getcwd()), DS);
define('GRAV_ROOT', $path);
}
if (!defined('GRAV_WEBROOT')) {
define('GRAV_WEBROOT', GRAV_ROOT);
}
if (!defined('GRAV_USER_PATH')) {
$path = rtrim(getenv('GRAV_USER_PATH') ?: 'user', DS);
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')) {
$path = rtrim(getenv('GRAV_CACHE_PATH') ?: 'cache', DS);
define('GRAV_CACHE_PATH', $path);
@@ -52,21 +59,21 @@ unset($path);
define('USER_PATH', GRAV_USER_PATH . DS);
define('CACHE_PATH', GRAV_CACHE_PATH . DS);
define('ROOT_DIR', GRAV_ROOT . DS);
define('USER_DIR', ROOT_DIR . USER_PATH);
define('CACHE_DIR', ROOT_DIR . CACHE_PATH);
define('USER_DIR', (!str_starts_with(USER_PATH, '/') ? GRAV_WEBROOT . '/' : '') . USER_PATH);
define('CACHE_DIR', (!str_starts_with(CACHE_PATH, '/') ? ROOT_DIR : '') . CACHE_PATH);
// DEPRECATED: Do not use!
define('ASSETS_DIR', ROOT_DIR . 'assets/');
define('IMAGES_DIR', ROOT_DIR . 'images/');
define('ASSETS_DIR', GRAV_WEBROOT . '/assets/');
define('IMAGES_DIR', GRAV_WEBROOT . '/images/');
define('ACCOUNTS_DIR', USER_DIR .'accounts/');
define('PAGES_DIR', USER_DIR .'pages/');
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('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('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
// Some extensions
+7 -8
View File
@@ -125,7 +125,7 @@ abstract class BaseAsset extends PropertyObject
if ($locator->isStream($asset)) {
$path = $locator->findResource($asset, true);
} else {
$path = GRAV_ROOT . $asset;
$path = GRAV_WEBROOT . $asset;
}
// If local file is missing return
@@ -172,15 +172,14 @@ abstract class BaseAsset extends PropertyObject
return $this;
}
/**
* Receive asset location and return the SRI integrity hash
*
* @param $input
*
* @param string $input
* @return string
*/
public static function integrityHash( $input )
public static function integrityHash($input)
{
$grav = Grav::instance();
@@ -188,7 +187,7 @@ abstract class BaseAsset extends PropertyObject
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_base64 = base64_encode($hash);
@@ -209,7 +208,7 @@ abstract class BaseAsset extends PropertyObject
*/
// protected function getLastModificationTime($asset)
// {
// $file = GRAV_ROOT . $asset;
// $file = GRAV_WEBROOT . $asset;
// if (Grav::instance()['locator']->isStream($asset)) {
// $file = $this->buildLocalLink($asset, true);
// }
@@ -228,7 +227,7 @@ abstract class BaseAsset extends PropertyObject
protected function buildLocalLink($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;
}
-1
View File
@@ -127,7 +127,6 @@ class Cache extends Getters
*/
public function init(Grav $grav)
{
/** @var Config $config */
$this->config = $grav['config'];
$this->now = time();
+7 -5
View File
@@ -164,6 +164,8 @@ class Setup extends Data
public function __construct($container)
{
// 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['cache']['prefixes'][''] = [GRAV_CACHE_PATH];
$this->streams['log']['prefixes'][''] = [GRAV_LOG_PATH];
@@ -197,16 +199,16 @@ class Setup extends Data
if (null !== $setupFile) {
// Make sure that the custom setup file exists. Terminates the script if not.
if (!str_starts_with($setupFile, '/')) {
$setupFile = GRAV_ROOT . '/' . $setupFile;
$setupFile = GRAV_WEBROOT . '/' . $setupFile;
}
if (!is_file($setupFile)) {
echo 'GRAV_SETUP_PATH is defined but does not point to existing setup file.';
exit(1);
}
} else {
$setupFile = GRAV_ROOT . '/setup.php';
$setupFile = GRAV_WEBROOT . '/setup.php';
if (!is_file($setupFile)) {
$setupFile = GRAV_ROOT . '/' . GRAV_USER_PATH . '/setup.php';
$setupFile = GRAV_WEBROOT . '/' . GRAV_USER_PATH . '/setup.php';
}
if (!is_file($setupFile)) {
$setupFile = null;
@@ -234,7 +236,7 @@ class Setup extends Data
$envPath .= '/';
} else {
// 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)) {
$envPath = 'user://env/';
} else {
@@ -257,7 +259,7 @@ class Setup extends Data
*/
public function init()
{
$locator = new UniformResourceLocator(GRAV_ROOT);
$locator = new UniformResourceLocator(GRAV_WEBROOT);
$files = [];
$guard = 5;
+5 -1
View File
@@ -524,8 +524,12 @@ class Blueprint extends BlueprintForm
* @param string $op
* @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);
foreach ($actions as $key => $action) {
if (!is_int($key) && is_array($actions)) {
@@ -62,7 +62,7 @@ abstract class Archiver
{
// Set infinite PHP execution time if possible.
if (Utils::functionExists('set_time_limit')) {
set_time_limit(0);
@set_time_limit(0);
}
$this->options = $options + $this->options;
+5 -5
View File
@@ -371,6 +371,10 @@ abstract class Folder
return;
}
if (strpos($target, $source) === 0) {
throw new RuntimeException('Cannot move folder to itself');
}
if (file_exists($target)) {
// Rename fails if target folder exists.
throw new RuntimeException('Cannot move files to existing folder/file.');
@@ -383,11 +387,7 @@ abstract class Folder
@rename($source, $target);
// Rename function can fail while still succeeding, so let's check if the folder exists.
if (!file_exists($target) || !is_dir($target)) {
// In some rare cases rename() creates file, not a folder. Get rid of it.
if (file_exists($target)) {
@unlink($target);
}
if (is_dir($source)) {
// Rename doesn't support moving folders across filesystems. Use copy instead.
self::copy($source, $target);
self::delete($source);
@@ -18,9 +18,8 @@ use Grav\Common\Flex\Traits\FlexGravTrait;
* Class FlexCollection
*
* @package Grav\Common\Flex
* @template TKey
* @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
{
+1 -2
View File
@@ -18,10 +18,9 @@ use Grav\Common\Flex\Traits\FlexIndexTrait;
* Class FlexIndex
*
* @package Grav\Common\Flex
* @template TKey
* @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface
* @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
{
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexCollection;
* Class GenericCollection
* @package Grav\Common\Flex\Generic
*
* @extends FlexCollection<string,GenericObject>
* @extends FlexCollection<GenericObject>
*/
class GenericCollection extends FlexCollection
{
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexIndex;
* Class GenericIndex
* @package Grav\Common\Flex\Generic
*
* @extends FlexIndex<string,GenericObject,GenericCollection>
* @extends FlexIndex<GenericObject,GenericCollection>
*/
class GenericIndex extends FlexIndex
{
@@ -35,7 +35,7 @@ use function is_string;
* Class GravPageCollection
* @package Grav\Plugin\FlexObjects\Types\GravPages
*
* @extends FlexPageCollection<string,PageObject>
* @extends FlexPageCollection<PageObject>
*
* Incompatibilities with Grav\Common\Page\Collection:
* $page = $collection->key() will not work at all
@@ -38,7 +38,7 @@ use function is_string;
* Class GravPageObject
* @package Grav\Plugin\FlexObjects\Types\GravPages
*
* @extends FlexPageIndex<string,PageObject,PageCollection>
* @extends FlexPageIndex<PageObject,PageCollection>
*
* @method PageIndex withModules(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.
$key = $this->getKey();
if ($key === $parentKey || strpos($parentKey, $key . '/') === 0) {
throw new RuntimeException(sprintf('Page /%s cannot be moved to %s', $key, $parentRoute));
}
$key = $this->getStorageKey();
/** @var PageObject|null $parent */
$parent = $parentKey !== false ? $this->getFlexDirectory()->getObject($parentKey, 'storage_key') : null;
@@ -301,6 +298,22 @@ class PageObject extends FlexPageObject
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.
*
@@ -373,7 +373,7 @@ class PageStorage extends FolderStorage
try {
if ($key === '' && empty($row['root'])) {
throw new RuntimeException('No storage key given');
throw new RuntimeException('Page has no path');
}
$grav = Grav::instance();
@@ -394,9 +394,17 @@ class PageStorage extends FolderStorage
if ($oldFolder !== $newFolder && file_exists($oldFolder)) {
$isCopy = $row['__META']['copy'] ?? false;
if ($isCopy) {
if (strpos($newFolder, $oldFolder . '/') === 0) {
throw new RuntimeException(sprintf('Page /%s cannot be copied to itself', $oldKey));
}
$this->copyRow($oldKey, $newKey);
$debugger->addMessage("Page copied: {$oldFolder} => {$newFolder}", 'debug');
} else {
if (strpos($newFolder, $oldFolder . '/') === 0) {
throw new RuntimeException(sprintf('Page /%s cannot be moved to itself', $oldKey));
}
$this->renameRow($oldKey, $newKey);
$debugger->addMessage("Page moved: {$oldFolder} => {$newFolder}", 'debug');
}
@@ -534,7 +542,7 @@ class PageStorage extends FolderStorage
$markdown = [];
$children = [];
if (is_string($path) && file_exists($path)) {
if (is_string($path) && is_dir($path)) {
$modified = filemtime($path);
$iterator = new FilesystemIterator($path, $this->flags);
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexCollection;
* Class UserGroupCollection
* @package Grav\Common\Flex\Types\UserGroups
*
* @extends FlexCollection<string,UserGroupObject>
* @extends FlexCollection<UserGroupObject>
*/
class UserGroupCollection extends FlexCollection
{
@@ -17,7 +17,7 @@ use Grav\Common\Flex\FlexIndex;
* Class GroupIndex
* @package Grav\Common\User\FlexUser
*
* @extends FlexIndex<string,UserGroupObject,UserGroupCollection>
* @extends FlexIndex<UserGroupObject,UserGroupCollection>
*/
class UserGroupIndex extends FlexIndex
{
@@ -20,7 +20,7 @@ use function is_string;
* Class UserCollection
* @package Grav\Common\Flex\Types\Users
*
* @extends FlexCollection<string,UserObject>
* @extends FlexCollection<UserObject>
*/
class UserCollection extends FlexCollection implements UserCollectionInterface
{
@@ -15,20 +15,20 @@ use Grav\Common\Debugger;
use Grav\Common\File\CompiledYamlFile;
use Grav\Common\Flex\FlexIndex;
use Grav\Common\Grav;
use Grav\Common\User\Interfaces\UserCollectionInterface;
use Grav\Common\User\Interfaces\UserInterface;
use Grav\Framework\Flex\Interfaces\FlexStorageInterface;
use Monolog\Logger;
use function count;
use function is_string;
use function method_exists;
/**
* Class UserIndex
* @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';
@@ -106,6 +106,24 @@ class UserIndex extends FlexIndex
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
*
@@ -538,13 +538,18 @@ class UserObject extends FlexObject implements UserInterface, Countable
}
}
$password = $this->getProperty('password');
if (null !== $password) {
$this->unsetProperty('password');
$this->unsetProperty('password1');
$this->unsetProperty('password2');
$password = $this->getProperty('password') ?? $this->getProperty('password1');
if (null !== $password && '' !== $password) {
$password2 = $this->getProperty('password2');
if (!\is_string($password) || ($password2 && $password !== $password2)) {
throw new \RuntimeException('Passwords did not match.');
}
$this->setProperty('hashed_password', Authentication::create($password));
}
$this->unsetProperty('password');
$this->unsetProperty('password1');
$this->unsetProperty('password2');
// Backwards compatibility with older plugins.
$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
*
* @param string|null $slug
* @return array|string
* @return string[]|string
*/
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
try {
if (Utils::functionExists('set_time_limit')) {
set_time_limit(0);
@set_time_limit(0);
}
} catch (Exception $e) {
}
@@ -41,6 +41,16 @@ trait ImageMediaTrait
/** @var bool */
protected $debug_watermarked = false;
/** @var bool */
protected $auto_sizes;
/** @var bool */
protected $aspect_ratio;
/** @var integer */
protected $retina_scale;
/** @var array */
public static $magic_actions = [
'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop',
@@ -358,11 +368,17 @@ trait ImageMediaTrait
->setPrettyName($this->getImagePrettyName());
// 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')) {
$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;
}
@@ -30,6 +30,11 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
use ImageMediaTrait;
use ImageLoadingTrait;
/**
* @var mixed|string
*/
private $saved_image_path;
/**
* Construct.
*
@@ -121,6 +126,12 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
$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;
}
@@ -170,7 +181,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
/** @var UniformResourceLocator $locator */
$locator = $grav['locator'];
$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;
@@ -232,6 +243,23 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
$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];
}
@@ -274,6 +302,29 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
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
*
+1 -1
View File
@@ -61,7 +61,7 @@ class Types implements \ArrayAccess, \Iterator, \Countable
*/
public function init()
{
if (null === $this->systemBlueprints) {
if (empty($this->systemBlueprints)) {
// Register all blueprints from the blueprints stream.
$this->systemBlueprints = $this->findBlueprints('blueprints://pages');
foreach ($this->systemBlueprints as $type => $blueprint) {
@@ -178,7 +178,7 @@ class InitializeProcessor extends ProcessorBase
$grav['plugins']->setup();
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)) {
$versions = [
'core' => [
@@ -30,7 +30,7 @@ class StreamsServiceProvider implements ServiceProviderInterface
public function register(Container $container)
{
$container['locator'] = function (Container $container) {
$locator = new UniformResourceLocator(GRAV_ROOT);
$locator = new UniformResourceLocator(GRAV_WEBROOT);
/** @var Setup $setup */
$setup = $container['setup'];
+2 -2
View File
@@ -128,12 +128,12 @@ class Session extends \Grav\Framework\Session\Session
/** @var Uri $uri */
$uri = $grav['uri'];
/** @var Forms|null $form */
$form = $grav['forms']->getActiveForm();
$form = $grav['forms']->getActiveForm(); // @phpstan-ignore-line
$sessionField = base64_encode($uri->url);
/** @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;
}
}
+2 -2
View File
@@ -205,8 +205,8 @@ class Uri
// set active language
$uri = $language->setActiveFromUri($uri);
// split the URL and params
$bits = parse_url($uri);
// split the URL and params (and make sure that the path isn't seen as domain)
$bits = parse_url('http://domain.com' . $uri);
//process 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
$password = $this->get('password');
if ($password) {
$password = $this->get('password') ?? $this->get('password1');
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->undef('password');
}
$this->undef('password');
$this->undef('password1');
$this->undef('password2');
$data = $this->items;
if ($username === $data['username']) {
@@ -37,10 +37,9 @@ use function is_scalar;
/**
* Class FlexCollection
* @package Grav\Framework\Flex
* @template TKey
* @template T of FlexObjectInterface
* @extends ObjectCollection<TKey,T>
* @implements FlexCollectionInterface<TKey,T>
* @extends ObjectCollection<string,T>
* @implements FlexCollectionInterface<T>
*/
class FlexCollection extends ObjectCollection implements FlexCollectionInterface
{
@@ -460,7 +459,6 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
/**
* @param string $key
* @return array
* @phpstan-param TKey $key
*/
public function getMetaData(string $key): array
{
@@ -491,7 +489,7 @@ class FlexCollection extends ObjectCollection implements FlexCollectionInterface
* @param string|null $scope
* @param UserInterface|null $user
* @return static
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
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 string|null $keyField
* @return static
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
* @throws \InvalidArgumentException
*/
protected function createFrom(array $elements, $keyField = null)
@@ -46,7 +46,6 @@ use function is_callable;
* Class FlexDirectory
* @package Grav\Framework\Flex
* @template T
* @template TKey
*/
class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
{
@@ -309,7 +308,7 @@ class FlexDirectory implements FlexDirectoryInterface, FlexAuthorizeInterface
* @param array|null $keys Array of keys.
* @param string|null $keyField Field to be used as the key.
* @return FlexCollectionInterface
* @phpstan-return FlexCollectionInterface<TKey,T>
* @phpstan-return FlexCollectionInterface<T>
*/
public function getCollection(array $keys = null, string $keyField = null): FlexCollectionInterface
{
+5 -7
View File
@@ -33,11 +33,10 @@ use function in_array;
/**
* Class FlexIndex
* @package Grav\Framework\Flex
* @template TKey
* @template T of FlexObjectInterface
* @template C of FlexCollectionInterface
* @extends ObjectIndex<TKey,T>
* @implements FlexIndexInterface<TKey,T>
* @extends ObjectIndex<string,T>
* @implements FlexIndexInterface<T>
* @mixin C
*/
class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexIndexInterface
@@ -54,7 +53,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
/**
* @param FlexDirectory $directory
* @return static
* @phpstan-return static<TKey,T,C>
* @phpstan-return static<T,C>
*/
public static function createFromStorage(FlexDirectory $directory)
{
@@ -343,7 +342,6 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
/**
* @param string $key
* @return array
* @phpstan-param TKey $key
*/
public function getMetaData($key): array
{
@@ -370,7 +368,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
/**
* @param array $orderings
* @return static
* @phpstan-return static<TKey,T,C>
* @phpstan-return static<T,C>
*/
public function orderBy(array $orderings)
{
@@ -538,7 +536,7 @@ class FlexIndex extends ObjectIndex implements FlexCollectionInterface, FlexInde
* @param array $entries
* @param string|null $keyField
* @return static
* @phpstan-return static<TKey,T,C>
* @phpstan-return static<T,C>
*/
protected function createFrom(array $entries, string $keyField = null)
{
@@ -22,9 +22,8 @@ use InvalidArgumentException;
*
* @used-by \Grav\Framework\Flex\FlexCollection
* @since 1.6
* @template TKey
* @template T
* @extends ObjectCollectionInterface<TKey,T>
* @extends ObjectCollectionInterface<string,T>
*/
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 array|null $options Search options, defaults to configured options.
* @return FlexCollectionInterface Returns a Flex Collection with only matching objects.
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
* @api
*/
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', ...].
*
* @return FlexCollectionInterface Returns a sorted version from the collection.
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
public function sort(array $orderings);
@@ -78,7 +77,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
*
* @param array $filters
* @return FlexCollectionInterface
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
public function filterBy(array $filters);
@@ -114,7 +113,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
*
* @param string|null $keyField Switch key field of the collection.
* @return FlexCollectionInterface Returns a new Flex Collection with new key field.
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
* @api
*/
public function withKeyField(string $keyField = null);
@@ -123,7 +122,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* Get Flex Index from the Flex Collection.
*
* @return FlexIndexInterface Returns a Flex Index from the current collection.
* @phpstan-return FlexIndexInterface<TKey,T>
* @phpstan-return FlexIndexInterface<T>
*/
public function getIndex();
@@ -131,7 +130,7 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
* Load all the objects into memory,
*
* @return FlexCollectionInterface
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
public function getCollection();
@@ -140,7 +139,6 @@ interface FlexCollectionInterface extends FlexCommonInterface, ObjectCollectionI
*
* @param string $key Key.
* @return array
* @phpstan-param TKey $key
*/
public function getMetaData(string $key): array;
}
@@ -21,9 +21,8 @@ use Grav\Framework\Flex\FlexDirectory;
*
* @used-by \Grav\Framework\Flex\FlexIndex
* @since 1.6
* @template TKey
* @template T
* @extends FlexCollectionInterface<TKey,T>
* @extends FlexCollectionInterface<T>
*/
interface FlexIndexInterface extends FlexCollectionInterface
{
@@ -20,9 +20,8 @@ use function is_int;
/**
* Class FlexPageCollection
* @package Grav\Plugin\FlexObjects\Types\FlexPages
* @template TKey
* @template T of \Grav\Framework\Flex\Interfaces\FlexObjectInterface
* @extends FlexCollection<TKey,T>
* @extends FlexCollection<T>
*/
class FlexPageCollection extends FlexCollection
{
@@ -53,7 +52,7 @@ class FlexPageCollection extends FlexCollection
/**
* @param bool $bool
* @return static
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
public function withPublished(bool $bool = true)
{
@@ -65,7 +64,7 @@ class FlexPageCollection extends FlexCollection
/**
* @param bool $bool
* @return static
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
public function withVisible(bool $bool = true)
{
@@ -77,7 +76,7 @@ class FlexPageCollection extends FlexCollection
/**
* @param bool $bool
* @return static
* @phpstan-return static<TKey,T>
* @phpstan-return static<T>
*/
public function withRoutable(bool $bool = true)
{
@@ -22,10 +22,9 @@ use Grav\Framework\Flex\FlexIndex;
* @method FlexPageIndex withPublished(bool $bool = true)
* @method FlexPageIndex withVisible(bool $bool = true)
*
* @template TKey
* @template T of FlexPageObject
* @template C of FlexPageCollection
* @extends FlexIndex<TKey,T,C>
* @extends FlexIndex<T,C>
*/
class FlexPageIndex extends FlexIndex
{
@@ -205,10 +205,10 @@ trait FlexMediaTrait
$filename = $info['path'] ?? $info['name'];
}
/** @var Medium|null $thumbFile */
/** @var Medium|null $imageFile */
$imageFile = $media[$filename];
/** @var Medium|null $thumbFile */
/** @var Medium|null $originalFile */
$originalFile = $originalMedia ? $originalMedia[$filename] : null;
$url = $imageFile ? $imageFile->url() : null;
@@ -384,7 +384,7 @@ trait FlexMediaTrait
$updated = true;
if ($medium) {
$media->add($filename, $medium);
} else {
} elseif (is_callable([$media, 'hide'])) {
$media->hide($filename);
}
}
+2 -2
View File
@@ -232,7 +232,7 @@ ERR;
$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->preflight();
@@ -280,7 +280,7 @@ ERR;
{
// Finalize can be run without installing Grav first.
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->install();
}
+1 -1
View File
@@ -36,7 +36,7 @@ final class Versions
*/
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])) {
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
---
# Ressources
@@ -18,6 +18,4 @@ admin:
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
---
# Contact
### Fabienne Dran
#### Assistante de direction
Fabienne.Dran@developpement-durable.gouv.fr
+ 33 (0)1 40 81 93 27
+33 (0)7 86 50 33 31
CONTACT :
Fabienne.Dran@developpement-durable.gouv.fr
+ 33 (0)1 40 81 9327
+33 (0)7 86 5033 31
@@ -91,8 +91,7 @@ sub {
bottom: -0.25em; }
img {
border: 0;
max-width: 15rem; }
border: 0; }
svg:not(:root) {
overflow: hidden; }
@@ -82,8 +82,7 @@ b, strong, label, th {
#header #logo img {
display: flex;
flex-direction: row;
flex-flow: row;
max-height: 5rem; }
flex-flow: row; }
#header.scrolled {
height: 3rem;
background-color: rgba(255, 255, 255, 0.9) !important;
@@ -825,9 +824,10 @@ ul.pagination {
#logo {
display: flex;
flex-direction: row; }
#logo img {
padding: 0.5rem; }
#logo img {
padding: 0.5rem;
max-height: 3rem;
margin: auto; }
.callout {
padding-top: 0.5rem; }
@@ -867,26 +867,47 @@ ul.pagination {
width: 100%; } }
.after-h1 .test {
opacity: 0;
transition: opacity 1s ease-in-out;
animation: anim 5s 500ms 1 normal ease-in-out forwards; }
.after-h1:hover .test {
opacity: 1; }
animation: anim 2.5s 1 normal ease-in-out forwards; }
.programmes {
display: flex;
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;
z-index: -1;
justify-content: center;
padding-left: 15%;
padding-right: 15%;
padding-top: 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 {
z-index: 1;
max-width: 35%;
padding: 1.5rem;
background-color: white;
@@ -895,7 +916,7 @@ ul.pagination {
text-transform: uppercase;
line-height: 1.2; }
.programme img {
max-height: 15%; }
max-height: 4rem; }
.programme p {
font-family: "Sarabun", sans-serif;
font-weight: 500;
@@ -949,7 +970,9 @@ ul.pagination {
width: 15rem !important;
height: 15rem !important; }
.mozaique_personnes .equipe .personne .mozaique .photo img {
width: 100%; }
object-fit: cover;
width: 100%;
height: 100%; }
.mozaique_personnes .equipe .personne .mozaique .info {
background-color: #fff;
display: flex;
@@ -98,7 +98,7 @@ sub {
img {
border: 0;
max-width: 15rem;
// max-width: 15rem;
}
svg:not(:root) {
@@ -52,48 +52,15 @@
#logo {
display: flex;
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 {
display: block;
margin-left: 40%;
// padding-right: 15%;
@@ -152,84 +120,51 @@
@keyframes anim {
0% {width: 0%;}
100% {width: 100%}
100% {width: 100%;}
}
.after-h1 { // fonctionne mais manque "when in View"
.test {
opacity: 0;
transition: opacity 1s ease-in-out;
animation: anim 5s 500ms 1 normal ease-in-out forwards;
}
.after-h1 {
&:hover {
.test {
opacity: 1;
}
.test {
// opacity: 0;
// transition: opacity 1s ease-in-out;
animation: anim 2.5s 1 normal ease-in-out forwards;
}
}
// &:hover {
// .test {
// opacity: 1;
// }
// opacity: 1;
// 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 {
display: flex;
flex-wrap: wrap;
background:
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/10361_web_01.jpg") 1200px 300px no-repeat, /* like z-index: 3; */
url("/user/themes/epau-antimatter/images/hyperliens_marseille_.PNG") 0px 700px no-repeat, /* like z-index: 2; */
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-image:
// url("/user/themes/epau-antimatter/images/14360_default_big.jpg") ,
// url("/user/themes/epau-antimatter/images/10361_web_01.jpg") ,
// url("/user/themes/epau-antimatter/images/hyperliens_marseille_.PNG") ,
// 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;
z-index: -1;
justify-content: center;
padding-left: 15%;
padding-right: 15%;
@@ -238,20 +173,61 @@
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 {
z-index: 1;
max-width: 35%;
// min-width:
padding: 1.5rem;
background-color: white;
margin: 0.4rem;
h4 {
text-transform: uppercase;
line-height: 1.2;
}
img {
max-height: 15%;
max-height: 4rem;
}
p {
@@ -403,12 +379,14 @@
width: 15rem !important;
height: 15rem !important;
// object-fit: cover;
// background-size: cover;
img {
// maxwidth: 15rem !important;
// height: 15rem !important;
// background-size: cover;
object-fit: cover;
width: 100%;
height: 100%;
}
@@ -15,7 +15,7 @@ $dropdown-color: #f6f6f6;
display: flex;
flex-direction: row;
flex-flow: row;
max-height: $header-height;
// max-height: $header-height;
}
// scroll based changes
@@ -200,7 +200,7 @@ $dropdown-color: #f6f6f6;
&.active > a {
background-color: darken($dropdown-color, 4%);
color: $core-accent;
}
@@ -1,5 +1,5 @@
<div class="gouvernance">
<div class="gouvernance after-h1">
<div class="titre_bsn">
@@ -7,7 +7,7 @@
<div class="test" >
<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>
</div>
<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="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 }}
{% for programme in page.header.programmes %}
<div class="programme">
<a href="{{programme.site}}">
<a href="{{programme.site}}" target="_blank">
{% if programme.logo %}
<img src="{{page.media[programme.logo].url|e }}" alt="logo du programme {{programme.nom_du_programme}}" />
{% endif %}
@@ -1,12 +1,12 @@
<div class="titre_nsb">
<div class="titre_nsb after-h1">
<h1>Ressources</h1>
<div class="test" >
<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>
</div>
<!-- <div class="after-h1-finish">