This commit is contained in:
kevin
2020-12-14 23:12:44 +01:00
parent b1e14f5f7b
commit b6ed4d771e
38 changed files with 1338 additions and 409 deletions
+66
View File
@@ -0,0 +1,66 @@
name: PHP Tests
on:
push:
branches: [ develop ]
pull_request:
branches: [ develop ]
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
php: [ 7.4, 7.3, 7.2 ]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: opcache, gd
coverage: none
- name: Validate composer.json and composer.lock
run: composer validate
- name: Get composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Run test suite
run: vendor/bin/codecept run
- name: Slack Notification
uses: 8398a7/action-slack@v3
with:
status: custom
fields: workflow,job,commit,repo,ref,author,took
custom_payload: |
{
username: 'action-slack',
icon_emoji: ':octocat:',
attachments: [{
color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
text: `${process.env.AS_WORKFLOW}\n${process.env.AS_JOB} (${process.env.AS_COMMIT}) of ${process.env.AS_REPO}@${process.env.AS_REF} by ${process.env.AS_AUTHOR} succeeded in ${process.env.AS_TOOK}`,
}]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }} # required
if: always() # Pick up events even if the job fails or is canceled.
+30
View File
@@ -1,3 +1,33 @@
# v1.6.30
## 12/03/2020
1. [](#bugfix)
* Rollback `samesite` cookie logic as it causes issues with PHP < 7.3 [#309](https://github.com/getgrav/grav/issues/3089)
* Fixed issue with `.travis.yml` due to GitHub API deprecated functionality
# v1.6.29
## 12/02/2020
1. [](#new)
* Added basic support for `user/config/versions.yaml`
1. [](#improved)
* Updated bundled JQuery to latest version `3.5.1`
* Forward a `sid` to GPM when downloading a premium package via CLI
* Better handling of missing repository index [grav-plugin-admin#1916](https://github.com/getgrav/grav-plugin-admin/issues/1916)
* Set `grav_cli` as referrer when using `Response` from CLI
* Add option for timeout in `self-upgrade` command [#3013](https://github.com/getgrav/grav/pull/3013)
* Allow to set SameSite from system.yaml [#3063](https://github.com/getgrav/grav/pull/3063)
* Update media.yaml with some MS Office mimetypes [#3070](https://github.com/getgrav/grav/pull/3070)
1. [](#bugfix)
* Fixed hardcoded system folder in blueprints, config and language streams
* Added `.htaccess` rule to block attempts to use Twig in the request URL
* Fix compatibility with Symfony 4.2 and up. [#3048](https://github.com/getgrav/grav/pull/3048)
* Fix failing example custom shceduled job. [#3050](https://github.com/getgrav/grav/pull/3050)
* Fix for XSS advisory [GHSA-cvmr-6428-87w9](https://github.com/getgrav/grav/security/advisories/GHSA-cvmr-6428-87w9)
* Fix uploads_dangerous_extensions checking [#3060](https://github.com/getgrav/grav/pull/3060)
* Remove redundant prefixing of `.` to extension [#3060](https://github.com/getgrav/grav/pull/3060)
* Check exact extension in checkFilename utility [#3061](https://github.com/getgrav/grav/pull/3061)
# v1.6.28 # v1.6.28
## 10/07/2020 ## 10/07/2020
+15
View File
@@ -0,0 +1,15 @@
# Security Policy
## Supported Versions
We are focusing our security updates on the following versions
| Version | Supported |
| ------- | ------------------ |
| 1.7.x | :white_check_mark: |
| 1.6.x | :white_check_mark: |
| < 1.6 | :x: |
## Reporting a Vulnerability
Please contact contact@getgrav.org with a detailed explaination of the security issue found and we will work with you to get it resolved as fast as possible.
+2 -3
View File
@@ -50,15 +50,14 @@
"composer/ca-bundle": "^1.0", "composer/ca-bundle": "^1.0",
"dragonmantank/cron-expression": "^1.2", "dragonmantank/cron-expression": "^1.2",
"phive/twig-extensions-deferred": "^1.0", "phive/twig-extensions-deferred": "^1.0",
"willdurand/negotiation": "2.x-dev" "willdurand/negotiation": "^3.0"
}, },
"require-dev": { "require-dev": {
"codeception/codeception": "^2.4", "codeception/codeception": "^2.4",
"phpstan/phpstan": "^0.11", "phpstan/phpstan": "^0.11",
"phpstan/phpstan-deprecation-rules": "^0.11.0", "phpstan/phpstan-deprecation-rules": "^0.11.0",
"phpunit/php-code-coverage": "~6.0", "phpunit/php-code-coverage": "~6.0",
"fzaninotto/faker": "^1.8", "fzaninotto/faker": "^1.8"
"victorjonsson/markdowndocs": "dev-master"
}, },
"suggest": { "suggest": {
"ext-zend-opcache": "Recommended for better performance", "ext-zend-opcache": "Recommended for better performance",
Generated
+768 -242
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,5 +1,5 @@
#!/bin/sh #!/bin/sh
chown -R kevin:http . chown -R 1000:www-data .
find . -type f -exec chmod 664 {} \; find . -type f -exec chmod 664 {} \;
find ./bin -type f -exec chmod 775 {} \; find ./bin -type f -exec chmod 775 {} \;
find . -type d -exec chmod 775 {} \; find . -type d -exec chmod 775 {} \;
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -39,12 +39,13 @@ form:
.command: .command:
type: text type: text
label: PLUGIN_ADMIN.COMMAND label: PLUGIN_ADMIN.COMMAND
placeholder: 'cd ~;ls -lah;' placeholder: 'ls'
validate: validate:
required: true required: true
.args: .args:
type: text type: text
label: PLUGIN_ADMIN.EXTRA_ARGUMENTS label: PLUGIN_ADMIN.EXTRA_ARGUMENTS
placeholder: '-lah'
.at: .at:
type: cron type: cron
label: PLUGIN_ADMIN.SCHEDULER_RUNAT label: PLUGIN_ADMIN.SCHEDULER_RUNAT
+3 -3
View File
@@ -103,7 +103,7 @@ types:
docx: docx:
type: file type: file
thumb: media/thumb-docx.png thumb: media/thumb-docx.png
mime: application/msword mime: application/vnd.openxmlformats-officedocument.wordprocessingml.document
xls: xls:
type: file type: file
thumb: media/thumb-xls.png thumb: media/thumb-xls.png
@@ -111,7 +111,7 @@ types:
xlsx: xlsx:
type: file type: file
thumb: media/thumb-xlsx.png thumb: media/thumb-xlsx.png
mime: application/vnd.ms-excel mime: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
ppt: ppt:
type: file type: file
thumb: media/thumb-ppt.png thumb: media/thumb-ppt.png
@@ -119,7 +119,7 @@ types:
pptx: pptx:
type: file type: file
thumb: media/thumb-pptx.png thumb: media/thumb-pptx.png
mime: application/vnd.ms-powerpoint mime: application/vnd.openxmlformats-officedocument.presentationml.presentation
pps: pps:
type: file type: file
thumb: media/thumb-pps.png thumb: media/thumb-pps.png
+1 -1
View File
@@ -8,7 +8,7 @@
// Some standard defines // Some standard defines
define('GRAV', true); define('GRAV', true);
define('GRAV_VERSION', '1.6.28'); define('GRAV_VERSION', '1.6.30');
define('GRAV_TESTING', false); define('GRAV_TESTING', false);
define('DS', '/'); define('DS', '/');
+1 -1
View File
@@ -70,7 +70,7 @@ class Backups
public function getBackupDownloadUrl($backup, $base_url) public function getBackupDownloadUrl($backup, $base_url)
{ {
$param_sep = $param_sep = Grav::instance()['config']->get('system.param_sep', ':'); $param_sep = $param_sep = Grav::instance()['config']->get('system.param_sep', ':');
$download = urlencode(base64_encode($backup)); $download = urlencode(base64_encode(basename($backup)));
$url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim($base_url, $url = rtrim(Grav::instance()['uri']->rootUrl(true), '/') . '/' . trim($base_url,
'/') . '/task' . $param_sep . 'backup/download' . $param_sep . $download . '/admin-nonce' . $param_sep . Utils::getNonce('admin-form'); '/') . '/task' . $param_sep . 'backup/download' . $param_sep . $download . '/admin-nonce' . $param_sep . Utils::getNonce('admin-form');
+3 -3
View File
@@ -59,13 +59,13 @@ class Setup extends Data
'blueprints' => [ 'blueprints' => [
'type' => 'ReadOnlyStream', 'type' => 'ReadOnlyStream',
'prefixes' => [ 'prefixes' => [
'' => ['environment://blueprints', 'user://blueprints', 'system/blueprints'], '' => ['environment://blueprints', 'user://blueprints', 'system://blueprints'],
] ]
], ],
'config' => [ 'config' => [
'type' => 'ReadOnlyStream', 'type' => 'ReadOnlyStream',
'prefixes' => [ 'prefixes' => [
'' => ['environment://config', 'user://config', 'system/config'], '' => ['environment://config', 'user://config', 'system://config'],
] ]
], ],
'plugins' => [ 'plugins' => [
@@ -89,7 +89,7 @@ class Setup extends Data
'languages' => [ 'languages' => [
'type' => 'ReadOnlyStream', 'type' => 'ReadOnlyStream',
'prefixes' => [ 'prefixes' => [
'' => ['environment://languages', 'user://languages', 'system/languages'], '' => ['environment://languages', 'user://languages', 'system://languages'],
] ]
], ],
'cache' => [ 'cache' => [
+18 -4
View File
@@ -233,6 +233,11 @@ class GPM extends Iterator
public function getUpdatablePlugins() public function getUpdatablePlugins()
{ {
$items = []; $items = [];
if (!$this->repository) {
return $items;
}
$repository = $this->repository['plugins']; $repository = $this->repository['plugins'];
// local cache to speed things up // local cache to speed things up
@@ -312,6 +317,11 @@ class GPM extends Iterator
public function getUpdatableThemes() public function getUpdatableThemes()
{ {
$items = []; $items = [];
if (!$this->repository) {
return $items;
}
$repository = $this->repository['themes']; $repository = $this->repository['themes'];
// local cache to speed things up // local cache to speed things up
@@ -359,6 +369,10 @@ class GPM extends Iterator
*/ */
public function getReleaseType($package_name) public function getReleaseType($package_name)
{ {
if (!$this->repository) {
return null;
}
$repository = $this->repository['plugins']; $repository = $this->repository['plugins'];
if (isset($repository[$package_name])) { if (isset($repository[$package_name])) {
return $repository[$package_name]->release_type; return $repository[$package_name]->release_type;
@@ -407,7 +421,7 @@ class GPM extends Iterator
*/ */
public function getRepositoryPlugin($slug) public function getRepositoryPlugin($slug)
{ {
return @$this->repository['plugins'][$slug]; return $this->repository['plugins'][$slug] ?? null;
} }
/** /**
@@ -416,7 +430,7 @@ class GPM extends Iterator
*/ */
public function getRepositoryPlugins() public function getRepositoryPlugins()
{ {
return $this->repository['plugins']; return $this->repository['plugins'] ?? null;
} }
/** /**
@@ -426,7 +440,7 @@ class GPM extends Iterator
*/ */
public function getRepositoryTheme($slug) public function getRepositoryTheme($slug)
{ {
return @$this->repository['themes'][$slug]; return $this->repository['themes'][$slug] ?? null;
} }
/** /**
@@ -435,7 +449,7 @@ class GPM extends Iterator
*/ */
public function getRepositoryThemes() public function getRepositoryThemes()
{ {
return $this->repository['themes']; return $this->repository['themes'] ?? null;
} }
/** /**
+4 -2
View File
@@ -284,7 +284,8 @@ class Response
$options['fopen']['notification'] = ['self', 'progress']; $options['fopen']['notification'] = ['self', 'progress'];
} }
$options['fopen']['header'] = 'Referer: ' . Grav::instance()['uri']->rootUrl(true); $referer = \defined('GRAV_CLI') ? 'grav_cli' : Grav::instance()['uri']->rootUrl(true);
$options['fopen']['header'] = 'Referer: ' . $referer;
if (isset($options['fopen']['ssl'])) { if (isset($options['fopen']['ssl'])) {
$ssl = $options['fopen']['ssl']; $ssl = $options['fopen']['ssl'];
unset($options['fopen']['ssl']); unset($options['fopen']['ssl']);
@@ -367,7 +368,8 @@ class Response
*/ */
private static function curlExecFollow($ch, $options, $callback) private static function curlExecFollow($ch, $options, $callback)
{ {
curl_setopt_array($ch, [ CURLOPT_REFERER => Grav::instance()['uri']->rootUrl(true) ]); $referer = \defined('GRAV_CLI') ? 'grav_cli' : Grav::instance()['uri']->rootUrl(true);
curl_setopt_array($ch, [ CURLOPT_REFERER => $referer ]);
if ($callback) { if ($callback) {
curl_setopt_array( curl_setopt_array(
@@ -9,6 +9,8 @@
namespace Grav\Common\Processors; namespace Grav\Common\Processors;
use Grav\Framework\File\Formatter\YamlFormatter;
use Grav\Framework\File\YamlFile;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface; use Psr\Http\Server\RequestHandlerInterface;
@@ -21,8 +23,27 @@ class ConfigurationProcessor extends ProcessorBase
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
{ {
$this->startTimer(); $this->startTimer();
$this->container['config']->init(); $config = $this->container['config'];
$config->init();
$this->container['plugins']->setup(); $this->container['plugins']->setup();
if ($config->get('versions') === null) {
$filename = GRAV_ROOT . '/user/config/versions.yaml';
if (!is_file($filename)) {
$versions = [
'core' => [
'grav' => [
'version' => GRAV_VERSION,
'history' => ['version' => GRAV_VERSION, 'date' => gmdate('Y-m-d H:i:s')]
]
]
];
$config->set('versions', $versions);
$file = new YamlFile($filename, new YamlFormatter(['inline' => 4]));
$file->save($versions);
}
}
$this->stopTimer(); $this->stopTimer();
return $handler->handle($request); return $handler->handle($request);
+2 -2
View File
@@ -298,8 +298,8 @@ class Job
if (is_callable($this->command)) { if (is_callable($this->command)) {
$this->output = $this->exec(); $this->output = $this->exec();
} else { } else {
$args = \is_string($this->args) ? $this->args : implode(' ', $this->args); $args = \is_string($this->args) ? explode(' ', $this->args) : $this->args;
$command = $this->command . ' ' . $args; $command = array_merge([$this->command], $args);
$process = new Process($command); $process = new Process($command);
$this->process = $process; $this->process = $process;
@@ -246,7 +246,7 @@ class Scheduler
*/ */
public function isCrontabSetup() public function isCrontabSetup()
{ {
$process = new Process('crontab -l'); $process = new Process(['crontab', '-l']);
$process->run(); $process->run();
if ($process->isSuccessful()) { if ($process->isSuccessful()) {
+1 -1
View File
@@ -133,7 +133,7 @@ class Security
// Set the patterns we'll test against // Set the patterns we'll test against
$patterns = [ $patterns = [
// Match any attribute starting with "on" or xmlns // Match any attribute starting with "on" or xmlns
'on_events' => '#(<[^>]+[[a-z\x00-\x20\"\'\/])(\son|\sxmlns)[a-z].*=>?#iUu', 'on_events' => '#(<[^>]+[[a-z\x00-\x20\"\'\/])([\s\/]on|\sxmlns)[a-z].*=>?#iUu',
// Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols // Match javascript:, livescript:, vbscript:, mocha:, feed: and data: protocols
'invalid_protocols' => '#(' . implode('|', $invalid_protocols) . '):.*?#iUu', 'invalid_protocols' => '#(' . implode('|', $invalid_protocols) . '):.*?#iUu',
+3 -7
View File
@@ -859,11 +859,7 @@ abstract class Utils
public static function checkFilename($filename) public static function checkFilename($filename)
{ {
$dangerous_extensions = Grav::instance()['config']->get('security.uploads_dangerous_extensions', []); $dangerous_extensions = Grav::instance()['config']->get('security.uploads_dangerous_extensions', []);
array_walk($dangerous_extensions, function(&$val) { $extension = pathinfo($filename, PATHINFO_EXTENSION);
$val = '.' . $val;
});
$extension = '.' . pathinfo($filename, PATHINFO_EXTENSION);
return !( return !(
// Empty filenames are not allowed. // Empty filenames are not allowed.
@@ -872,8 +868,8 @@ abstract class Utils
|| strtr($filename, "\t\v\n\r\0\\/", '_______') !== $filename || strtr($filename, "\t\v\n\r\0\\/", '_______') !== $filename
// Filename should not start or end with dot or space. // Filename should not start or end with dot or space.
|| trim($filename, '. ') !== $filename || trim($filename, '. ') !== $filename
// Filename should not contain .php in it. // File extension should not be part of configured dangerous extensions
|| static::contains($extension, $dangerous_extensions) || in_array($extension, $dangerous_extensions)
); );
} }
@@ -570,7 +570,8 @@ class InstallCommand extends ConsoleCommand
[ [
'slug' => $package->slug, 'slug' => $package->slug,
'filename' => $package->premium['filename'], 'filename' => $package->premium['filename'],
'license_key' => $license 'license_key' => $license,
'sid' => md5(GRAV_ROOT)
] ]
)); ));
@@ -46,6 +46,9 @@ class SelfupgradeCommand extends ConsoleCommand
protected $overwrite; protected $overwrite;
/** @var int */
protected $timeout;
protected function configure() protected function configure()
{ {
$this $this
@@ -69,6 +72,13 @@ class SelfupgradeCommand extends ConsoleCommand
InputOption::VALUE_NONE, InputOption::VALUE_NONE,
'Option to overwrite packages if they already exist' 'Option to overwrite packages if they already exist'
) )
->addOption(
'timeout',
't',
InputOption::VALUE_OPTIONAL,
'Option to set the timeout in seconds when downloading the update (0 for no timeout)',
30
)
->setDescription('Detects and performs an update of Grav itself when available') ->setDescription('Detects and performs an update of Grav itself when available')
->setHelp('The <info>update</info> command updates Grav itself when a new version is available'); ->setHelp('The <info>update</info> command updates Grav itself when a new version is available');
} }
@@ -78,6 +88,7 @@ class SelfupgradeCommand extends ConsoleCommand
$this->upgrader = new Upgrader($this->input->getOption('force')); $this->upgrader = new Upgrader($this->input->getOption('force'));
$this->all_yes = $this->input->getOption('all-yes'); $this->all_yes = $this->input->getOption('all-yes');
$this->overwrite = $this->input->getOption('overwrite'); $this->overwrite = $this->input->getOption('overwrite');
$this->timeout = (int) $this->input->getOption('timeout');
$this->displayGPMRelease(); $this->displayGPMRelease();
@@ -116,7 +127,6 @@ class SelfupgradeCommand extends ConsoleCommand
$questionHelper = $this->getHelper('question'); $questionHelper = $this->getHelper('question');
$this->output->writeln("Grav v<cyan>{$remote}</cyan> is now available [release date: {$release}]."); $this->output->writeln("Grav v<cyan>{$remote}</cyan> is now available [release date: {$release}].");
$this->output->writeln('You are currently using v<cyan>' . GRAV_VERSION . '</cyan>.'); $this->output->writeln('You are currently using v<cyan>' . GRAV_VERSION . '</cyan>.');
@@ -185,7 +195,16 @@ class SelfupgradeCommand extends ConsoleCommand
{ {
$tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true); $tmp_dir = Grav::instance()['locator']->findResource('tmp://', true, true);
$this->tmp = $tmp_dir . '/Grav-' . uniqid('', false); $this->tmp = $tmp_dir . '/Grav-' . uniqid('', false);
$output = Response::get($package['download'], [], [$this, 'progress']); $options = [
'curl' => [
CURLOPT_TIMEOUT => $this->timeout,
],
'fopen' => [
'timeout' => $this->timeout,
],
];
$output = Response::get($package['download'], $options, [$this, 'progress']);
Folder::create($this->tmp); Folder::create($this->tmp);
@@ -63,9 +63,10 @@ trait ObjectCollectionTrait
/** /**
* @param string $property Object property to be fetched. * @param string $property Object property to be fetched.
* @param mixed $default Default value if not set. * @param mixed $default Default value if not set.
* @param bool $doCreate Not being used.
* @return mixed[] Key/Value pairs of the properties. * @return mixed[] Key/Value pairs of the properties.
*/ */
public function doGetProperty($property, $default = null) public function &doGetProperty($property, $default = null, $doCreate = false)
{ {
$list = []; $list = [];
+32
View File
@@ -1,14 +1,22 @@
absolute_urls: false absolute_urls: false
timezone: Europe/Paris timezone: Europe/Paris
default_locale: null
param_sep: ':' param_sep: ':'
wrapped_site: false wrapped_site: false
reverse_proxy_setup: false reverse_proxy_setup: false
force_ssl: false force_ssl: false
force_lowercase_urls: true force_lowercase_urls: true
custom_base_url: null
username_regex: '^[a-z0-9_-]{3,16}$' username_regex: '^[a-z0-9_-]{3,16}$'
pwd_regex: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}' pwd_regex: '(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}'
intl_enabled: true intl_enabled: true
http_x_forwarded:
protocol: true
host: false
port: true
ip: true
languages: languages:
supported: null
default_lang: fr default_lang: fr
include_default_lang: false include_default_lang: false
pages_fallback_only: false pages_fallback_only: false
@@ -28,6 +36,7 @@ pages:
list: list:
count: 50 count: 50
dateformat: dateformat:
default: null
short: 'jS M Y' short: 'jS M Y'
long: 'jS M Y' long: 'jS M Y'
publish_dates: true publish_dates: true
@@ -47,6 +56,12 @@ pages:
special_chars: special_chars:
'>': gt '>': gt
'<': lt '<': lt
valid_link_attributes:
- rel
- target
- id
- class
- classes
types: types:
- html - html
- htm - htm
@@ -55,6 +70,7 @@ pages:
- json - json
- rss - rss
- atom - atom
append_url_extension: null
expires: 604800 expires: 604800
cache_control: '31536000' cache_control: '31536000'
last_modified: false last_modified: false
@@ -69,6 +85,7 @@ pages:
- .git - .git
- .idea - .idea
ignore_hidden: true ignore_hidden: true
hide_empty_folders: false
url_taxonomy_filters: true url_taxonomy_filters: true
frontmatter: frontmatter:
process_twig: false process_twig: false
@@ -89,6 +106,17 @@ cache:
lifetime: 604800 lifetime: 604800
gzip: false gzip: false
allow_webserver_gzip: false allow_webserver_gzip: false
redis:
socket: null
server: null
port: null
password: null
memcache:
server: null
port: null
memcached:
server: null
port: null
twig: twig:
cache: false cache: false
debug: false debug: false
@@ -132,6 +160,8 @@ images:
seofriendly: false seofriendly: false
media: media:
enable_media_timestamp: false enable_media_timestamp: false
unsupported_inline_types: null
allowed_fallback_types: null
auto_metadata_exif: false auto_metadata_exif: false
upload_limit: 8388608 upload_limit: 8388608
session: session:
@@ -143,8 +173,10 @@ session:
secure: false secure: false
httponly: true httponly: true
split: true split: true
path: null
gpm: gpm:
releases: stable releases: stable
proxy_url: null
method: auto method: auto
verify_peer: true verify_peer: true
official_gpm_only: true official_gpm_only: true
+6
View File
@@ -0,0 +1,6 @@
core:
grav:
version: 1.6.30
history:
version: 1.6.30
date: '2020-12-06 17:57:16'
@@ -6,9 +6,9 @@ lieux: '93 Baker Street'
artistes: ' Olivia Bax' artistes: ' Olivia Bax'
title: '‘at large'', ' title: '‘at large'', '
media_order: 'Olivia Bax, Boulder (with handle), 2015.jpg,Detail of Olivia Bax, Hot Spot, 2018.jpg,Olivia Bax, Love Handles, 2017.jpg,Olivia Bax, Pump, 2016.jpg,Olivia Bax, Slot _ Groove, 2015.jpg,Olivia Bax, Rumble, 2018.jpg,Installation Olivia Bax.jpg,Detail ''Footloose'', 2017.jpg,Olivia Bax, Footloose, 2017.jpg' media_order: 'Olivia Bax, Boulder (with handle), 2015.jpg,Detail of Olivia Bax, Hot Spot, 2018.jpg,Olivia Bax, Love Handles, 2017.jpg,Olivia Bax, Pump, 2016.jpg,Olivia Bax, Slot _ Groove, 2015.jpg,Olivia Bax, Rumble, 2018.jpg,Installation Olivia Bax.jpg,Detail ''Footloose'', 2017.jpg,Olivia Bax, Footloose, 2017.jpg'
show_sidebar: false
aura: aura:
pagetype: website pagetype: website
show_sidebar: false
--- ---
An awareness of materials is crucial in pursuing any artistic endeavour. An awareness of materials is crucial in pursuing any artistic endeavour.
@@ -27,7 +27,7 @@ materials for further assembly (Iza Genzken). Olivia Bax's work is a
distinct example of this aesthetic manu propria, for Bax not only distinct example of this aesthetic manu propria, for Bax not only
physically leaves the imprint of her hand, her gestures on the surface of her physically leaves the imprint of her hand, her gestures on the surface of her
sculptures, but she also uses handles as a recurring motif (Hot Spot, sculptures, but she also uses handles as a recurring motif (Hot Spot,
Boulder (with handle) and Pump). Her stand-alone pieces (Rumble and Boulder (**with handle) and Pump). Her stand-alone pieces (Rumble** and
Roar) have a human scale, as if they were based on her own height. Roar) have a human scale, as if they were based on her own height.
Bax's investigation of material rhythms can be likened to the act of Bax's investigation of material rhythms can be likened to the act of
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+16
View File
@@ -127,7 +127,23 @@ function newsletter() {
} }
function OpenSearch(){
$('.wrap_search a').click(function() {
$('.search-wrapper').toggleClass("opacity");
});
var url = window.location.pathname
var splitUrl = url.split("/");
console.log(splitUrl);
if(splitUrl[1] == "search" ){
$('.search-wrapper').addClass("opacity");
}
}
$(document).ready(function(){ $(document).ready(function(){
// more(); // more();
// newsletter(); // newsletter();
OpenSearch();
}); });
+1
View File
@@ -14,6 +14,7 @@
@import 'theme/header'; @import 'theme/header';
@import 'theme/footer'; @import 'theme/footer';
@import 'theme/menu'; @import 'theme/menu';
@import 'theme/search';
// Extra Skeleton Styling // Extra Skeleton Styling
@import 'theme/blog'; @import 'theme/blog';
@@ -115,86 +115,4 @@
} }
} }
.simplesearch_results{
.section{
// width: calc((100% / 12) * 9);
width: 100%;
.simplesearch{
.center{
width: calc((100% / 12) * 9);
}
.result_for{
text-transform: uppercase;
p{
margin: 0!important;
}
}
.search-wrapper{
form{
display: inline-flex;
.search-input, button{
font-family: $Bold;
font-size: 6rem;
text-transform: uppercase;
width: 100%;
height: auto;
border: none;
background: none;
}
}
}
}
}
.card-cat{
margin-bottom:0.6rem;
}
}
.search-results{
.results{
margin-top: 6rem;
@include flexbox;
align-items: flex-end;
width: 100%;
.search-row{
width: calc((100% / 12) * 6);
margin-bottom: 6rem;
a{
display: block;
}
&:nth-child(odd){
padding-right: 0.7rem;
}
&:nth-child(even){
padding-left: 0.7rem;
}
.search-item{
margin: 0;
}
.card-cat{
margin-bottom:0.6rem;
}
.search-title{
h2{
font-size: 2.5rem;
line-height: 2.7rem;
}
}
.search-details{
font-family: $Bold;
font-size: 2.5rem;
line-height: 2.7rem;
font-weight: 400;
margin: 0;
text-transform: uppercase;
}
.search-image{
float: none;
width: 100%;
margin-top: 1.5rem;
margin-bottom: 1.5rem;
}
}
}
}
@@ -157,6 +157,7 @@
} }
} }
.dz-default{ .dz-default{
display: none;
span{ span{
display: none; display: none;
} }
@@ -279,3 +280,7 @@
margin-left: 1rem; margin-left: 1rem;
} }
} }
input{
outline: none;
}
@@ -0,0 +1,113 @@
.simplesearch_results{
.section{
// width: calc((100% / 12) * 9);
width: 100%;
.simplesearch{
.center{
width: calc((100% / 12) * 9);
}
.result_for{
text-transform: uppercase;
p{
margin: 0!important;
}
}
}
}
.card-cat{
margin-bottom:0.6rem;
}
}
.wrap_search{
display: inline-flex;
align-items: baseline;
& > a{
margin-right: 1.2rem;
}
}
.search-wrapper{
opacity: 0;
transition: opacity 0.2s ease;
&.opacity{
opacity: 1;
transition: opacity 0.2s ease;
}
form{
display: inline-flex;
.search-input, button{
font-family: $Bold;
font-size: 1.5rem;
text-transform: uppercase;
height: auto;
border: none;
background: none;
}
button{
width: auto;
}
.search-input{
max-width: 200px;
width: 100%;
border-bottom: 1px solid black;
margin-right: 1.2rem;
background: white!important;
&:focus, &:active, &::placeholder{
outline: none;
background-color:transparent!important;
}
}
}
}
.search-results{
.results{
margin-top: 6rem;
@include flexbox;
align-items: flex-end;
width: 100%;
.search-row{
width: calc((100% / 12) * 6);
margin-bottom: 6rem;
a{
display: block;
}
&:nth-child(odd){
padding-right: 0.7rem;
}
&:nth-child(even){
padding-left: 0.7rem;
}
.search-item{
margin: 0;
}
.card-cat{
margin-bottom:0.6rem;
}
.search-title{
h2{
font-size: 2.5rem;
line-height: 2.7rem;
}
}
.search-details{
font-family: $Bold;
font-size: 2.5rem;
line-height: 2.7rem;
font-weight: 400;
margin: 0;
text-transform: uppercase;
}
.search-image{
float: none;
width: 100%;
margin-top: 1.5rem;
margin-bottom: 1.5rem;
}
}
}
}
@@ -0,0 +1,118 @@
{% extends "forms/field.html.twig" %}
{% macro bytesToSize(bytes) -%}
{% spaceless %}
{% set kilobyte = 1024 %}
{% set megabyte = kilobyte * 1024 %}
{% set gigabyte = megabyte * 1024 %}
{% set terabyte = gigabyte * 1024 %}
{% if bytes < kilobyte %}
{{ bytes ~ ' B' }}
{% elseif bytes < megabyte %}
{{ (bytes / kilobyte)|number_format(2, '.') ~ ' KB' }}
{% elseif bytes < gigabyte %}
{{ (bytes / megabyte)|number_format(2, '.') ~ ' MB' }}
{% elseif bytes < terabyte %}
{{ (bytes / gigabyte)|number_format(2, '.') ~ ' GB' }}
{% else %}
{{ (bytes / terabyte)|number_format(2, '.') ~ ' TB' }}
{% endif %}
{% endspaceless %}
{%- endmacro %}
{% macro preview(path, value, global) %}
{% if value %}
{% set uri = global.grav.uri %}
{% set files = global.files %}
{% set config = global.grav.config %}
{% set route = global.context.route() %}
{% set type = global.context.content() is not null ? 'pages' : global.plugin ? 'plugins' : global.theme ? 'themes' : 'config' %}
{% set blueprint_name = global.blueprints.getFilename %}
{% if type == 'pages' %}
{% set blueprint_name = type ~ '/' ~ blueprint_name %}
{% endif %}
{% set blueprint = base64_encode(blueprint_name) %}
{% set real_path = value.thumb ?? global.context.media[path].relativePath ?? global.form.getPagePathFromToken(path) %}
{% set remove = global.form.getFileDeleteAjaxRoute(files.name, path)|string ?: uri.addNonce(
global.base_url_relative ~
'/media.json' ~
'/task' ~ config.system.param_sep ~ 'removeFileFromBlueprint' ~
'/proute' ~ config.system.param_sep ~ base64_encode(route) ~
'/blueprint' ~ config.system.param_sep ~ blueprint ~
'/type' ~ config.system.param_sep ~ type ~
'/field' ~ config.system.param_sep ~ files.name ~
'/path' ~ config.system.param_sep ~ base64_encode(value.path), 'admin-form', 'admin-nonce') %}
{% set file = value|merge({remove: remove, path: value.thumb_url ?? (uri.rootUrl == '/' ? '/' : uri.rootUrl ~ '/' ~ real_path) }) %}
<div class="hidden" data-file="{{ file|json_encode|e('html_attr') }}"></div>
{% endif %}
{% endmacro %}
{% import _self as macro %}
{% set defaults = config.plugins.form %}
{% set files = defaults.files|merge(field|default([])) %}
{% set limit = not field.multiple ? 1 : files.limit %}
{% do config.set('forms.dropzone.enabled', true) %}
{% block input %}
{% set page_can_upload = exists or (type == 'page' and not exists and not (field.destination starts with '@self' or field.destination starts with 'self@')) %}
{% set max_filesize = (field.filesize > form_max_filesize or field.filesize == 0) ? form_max_filesize : field.filesize %}
{% block prepend %}{% endblock %}
{% set settings = {name: field.name, paramName: (scope ~ field.name)|fieldName ~ (files.multiple ? '[]' : ''), limit: limit, filesize: max_filesize, accept: files.accept, resolution: files.resolution, resizeWidth: files.resizeWidth, resizeHeight: files.resizeHeight, resizeQuality: files.resizeQuality } %}
{% set dropzoneSettings = field.dropzone %}
<div class="{{ form_field_wrapper_classes ?: 'form-input-wrapper' }} {{ field.classes }} dropzone files-upload form-input-file {{ field.size }}" data-grav-file-settings="{{ settings|json_encode|e('html_attr') }}" data-dropzone-options="{{ dropzoneSettings|json_encode|e('html_attr') }}" {% if form.getFileUploadAjaxRoute %}data-file-url-add="{{ form.getFileUploadAjaxRoute() }}"{% endif %}>
{% block file_extras %}{% endblock %}
<input
{# required attribute structures #}
{% block input_attributes %}
type="file"
{% if files.multiple %}multiple="multiple"{% endif %}
{% if files.accept %}accept="{{ files.accept|join(',') }}"{% endif %}
{% if field.disabled %}disabled="disabled"{% endif %}
{% if field.random_name %}random="true"{% endif %}
{% if required %}required="required"{% endif %}
{{ parent() }}
{% endblock %}
/>
{% for path, file in value %}
{{ macro.preview(path, file, _context) }}
{% endfor %}
{% include 'forms/fields/hidden/hidden.html.twig' with {field: {name: '_json.' ~ field.name}, value: (value ?? [])|json_encode } %}
</div>
{% if grav.browser.browser == 'msie' and grav.browser.version < 12 %}
{% do assets.addJs('plugin://form/assets/object.assign.polyfill.js') %}
{% endif %}
{% do assets.addJs('jquery', 101) %}
{% do assets.addJs('plugin://form/assets/form.vendor.js', { 'group': 'bottom', 'loading': 'defer' }) %}
{% do assets.addJs('plugin://form/assets/form.min.js', { 'group': 'bottom', 'loading': 'defer' }) %}
{% do assets.addCss('plugin://form/assets/dropzone.min.css', { 'group': 'form'}) %}
{{ assets.css('form')|raw }}
{% do assets.addInlineJs("
window.GravForm = window.GravForm || {};
window.GravForm = Object.assign({}, window.GravForm, {
translations: {
PLUGIN_FORM: {
'DROPZONE_CANCEL_UPLOAD': " ~ 'PLUGIN_FORM.DROPZONE_CANCEL_UPLOAD'|t|json_encode ~ ",
'DROPZONE_CANCEL_UPLOAD_CONFIRMATION': " ~ 'PLUGIN_FORM.DROPZONE_CANCEL_UPLOAD_CONFIRMATION'|t|json_encode ~ ",
'DROPZONE_DEFAULT_MESSAGE': " ~ 'PLUGIN_FORM.DROPZONE_DEFAULT_MESSAGE'|t|json_encode ~ ",
'DROPZONE_FALLBACK_MESSAGE': " ~ 'PLUGIN_FORM.DROPZONE_FALLBACK_MESSAGE'|t|json_encode ~ ",
'DROPZONE_FALLBACK_TEXT': " ~ 'PLUGIN_FORM.DROPZONE_FALLBACK_TEXT'|t|json_encode ~ ",
'DROPZONE_FILE_TOO_BIG': " ~ 'PLUGIN_FORM.DROPZONE_FILE_TOO_BIG'|t|json_encode ~ ",
'DROPZONE_INVALID_FILE_TYPE': " ~ 'PLUGIN_FORM.DROPZONE_INVALID_FILE_TYPE'|t|json_encode ~ ",
'DROPZONE_MAX_FILES_EXCEEDED': " ~ 'PLUGIN_FORM.DROPZONE_MAX_FILES_EXCEEDED'|t|json_encode ~ ",
'DROPZONE_REMOVE_FILE': " ~ 'PLUGIN_FORM.DROPZONE_REMOVE_FILE'|t|json_encode ~ ",
'DROPZONE_REMOVE_FILE_CONFIRMATION': " ~ 'PLUGIN_FORM.DROPZONE_REMOVE_FILE_CONFIRMATION'|t|json_encode ~ ",
'DROPZONE_RESPONSE_ERROR': " ~ 'PLUGIN_FORM.DROPZONE_RESPONSE_ERROR'|t|json_encode ~ ",
'RESOLUTION_MIN': " ~ 'PLUGIN_FORM.RESOLUTION_MIN'|t|json_encode ~ ",
'RESOLUTION_MAX': " ~ 'PLUGIN_FORM.RESOLUTION_MAX'|t|json_encode ~ "
}
}
});
", {'group': 'bottom', 'position': 'before'}) %}
{% endblock %}
@@ -2,9 +2,10 @@
<ul {{ tree ? 'class="tree"' : '' }}> <ul {{ tree ? 'class="tree"' : '' }}>
{{ macros.nav_loop(pages) }} {{ macros.nav_loop(pages) }}
<li> <li class="wrap_search">
<a href="/search"> <a href="#">
<img src="/user/themes/vocurations/images/Icone_search.svg" alt=""> <img src="/user/themes/vocurations/images/Icone_search.svg" alt="">
</a> </a>
{% include 'partials/simplesearch_searchbox.html.twig' %}
</li> </li>
</ul> </ul>
@@ -2,7 +2,6 @@
{% set pageCollection = search_results %} {% set pageCollection = search_results %}
{% if page.template == 'modular' %} {% if page.template == 'modular' %}
{% for item in page.collection %} {% for item in page.collection %}
{% if item.media.images %} {% if item.media.images %}
{% set value = query|hyphenize %} {% set value = query|hyphenize %}
@@ -10,7 +9,9 @@
{% if title|contains(value) == 1 %} {% if title|contains(value) == 1 %}
<section class="search-row"> <section class="search-row">
<a href="{{ item.header.url_news }}" target="_blank"> {% if item.header.url_news %}
<a href="{{ item.header.url_news }}" target="_blank">
{% endif %}
{% set banner = item.media.images|first %} {% set banner = item.media.images|first %}
<div class="search-item"> <div class="search-item">
@@ -35,7 +36,10 @@
{% endif %} {% endif %}
</div> </div>
{% if item.header.url_news %}
</a> </a>
{% endif %}
</section> </section>
{% endif %} {% endif %}
@@ -46,6 +50,7 @@
{% if page.media.images %} {% if page.media.images %}
<section class="search-row"> <section class="search-row">
<a href="{{page.url}}"> <a href="{{page.url}}">
{% set banner = page.media.images|first %} {% set banner = page.media.images|first %}
<div class="search-item"> <div class="search-item">
@@ -2,6 +2,7 @@
<div class="search-wrapper"> <div class="search-wrapper">
<form name="search" data-simplesearch-form> <form name="search" data-simplesearch-form>
<input <input
autocomplete="off"
name="searchfield" name="searchfield"
class="search-input" class="search-input"
type="text" type="text"
@@ -2,17 +2,14 @@
{% block content %} {% block content %}
<div class="content-padding simplesearch"> <div class="content-padding simplesearch">
<div class="center">
{% include 'partials/simplesearch_searchbox.html.twig' %}
</div>
<div class="result_for"> <div class="result_for">
<p> <p>
{% if query %} {% if query %}
{% set count = search_results ? search_results.count : 0 %} {% set count = search_results ? search_results.count : 0 %}
{% if count is same as( 1 ) %} {% if count is same as( 1 ) %}
{{ "PLUGIN_SIMPLESEARCH.SEARCH_RESULTS_SUMMARY_SINGULAR"|t(query|e)|raw }} "{{ query }}" - Found {{ search_results.count }} {{ 'Result'|pluralize(search_results.count) }}
{% else %} {% else %}
{{ "PLUGIN_SIMPLESEARCH.SEARCH_RESULTS_SUMMARY_PLURAL"|t(query|e, count)|raw }} "{{ query }}" - Found {{ search_results.count }} {{ 'Results'|t(query|e, count)|raw }}
{% endif %} {% endif %}
{% endif %} {% endif %}
</p> </p>
+3
View File
@@ -27,6 +27,9 @@ RewriteEngine On
# If you experience problems on your site block out the operations listed below # If you experience problems on your site block out the operations listed below
# This attempts to block the most common type of exploit `attempts` to Grav # This attempts to block the most common type of exploit `attempts` to Grav
# #
# Block out any script trying to use twig tags in URL.
RewriteCond %{REQUEST_URI} ({{|}}|{%|%}) [OR]
RewriteCond %{QUERY_STRING} ({{|}}|{%25|%25}) [OR]
# Block out any script trying to base64_encode data within the URL. # Block out any script trying to base64_encode data within the URL.
RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR] RewriteCond %{QUERY_STRING} base64_encode[^(]*\([^)]*\) [OR]
# Block out any script that includes a <script> tag in URL. # Block out any script that includes a <script> tag in URL.