Merge branch 'develop' of github.com:getgrav/grav into feature/media

 Conflicts:
	composer.lock
This commit is contained in:
Matias Griese
2022-03-09 12:29:31 +02:00
8 changed files with 136 additions and 53 deletions

View File

@@ -10,16 +10,19 @@
## mm/dd/2022
1. [](#new)
* Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533)
* Added XSS check for uploaded SVG files before they get stored
* Fixed phpstan issues (All level 2, Framework level 5)
2. [](#bugfix)
* Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504)
* Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542)
* Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540)
* Fixed entity sanitization for XSS detection
* Fixed avatar save location when `account://` stream points to custom directory
* Fixed bug in `Utils::url()` when path contains root
* Added new local Multiavatar (local generation). **This will be default in Grav 1.8**
* Added support to get image size for SVG vector images [#3533](https://github.com/getgrav/grav/pull/3533)
* Added XSS check for uploaded SVG files before they get stored
* Fixed phpstan issues (All level 2, Framework level 5)
2. [](#improved)
* Moved Accounts out of Experimental section of System configuration
3. [](#bugfix)
* Fixed `'mbstring' extension is not loaded` error, use Polyfill instead [#3504](https://github.com/getgrav/grav/pull/3504)
* Fixed new `Utils::pathinfo()` and `Utils::basename()` being too strict for legacy use [#3542](https://github.com/getgrav/grav/issues/3542)
* Fixed non-standard video html atributes generated by `{{ media.html() }}` [#3540](https://github.com/getgrav/grav/issues/3540)
* Fixed entity sanitization for XSS detection
* Fixed avatar save location when `account://` stream points to custom directory
* Fixed bug in `Utils::url()` when path contains part of root
# v1.7.30
## 02/07/2022

View File

@@ -57,7 +57,8 @@
"itsgoingd/clockwork": "^5.0",
"symfony/http-client": "^4.4",
"composer/semver": "^1.4",
"rhukster/dom-sanitizer": "^1.0"
"rhukster/dom-sanitizer": "^1.0",
"multiavatar/multiavatar-php": "^1.0"
},
"require-dev": {
"codeception/codeception": "^4.1",

View File

@@ -1786,35 +1786,15 @@ form:
validate:
type: bool
experimental:
accounts:
type: tab
title: PLUGIN_ADMIN.EXPERIMENTAL
title: PLUGIN_ADMIN.ACCOUNTS
fields:
experimental_section:
type: section
title: PLUGIN_ADMIN.EXPERIMENTAL
underline: true
# flex_pages:
# type: section
# title: Flex Pages
#
# pages.type:
# type: select
# label: PLUGIN_ADMIN.PAGES_TYPE
# highlight: regular
# help: PLUGIN_ADMIN.PAGES_TYPE_HELP
# options:
# regular: PLUGIN_ADMIN.REGULAR
# flex: PLUGIN_ADMIN.FLEX
pages.type:
type: hidden
flex_accounts:
type: section
title: Flex Accounts
title: User Accounts
accounts.type:
type: select
@@ -1833,3 +1813,41 @@ form:
options:
file: PLUGIN_ADMIN.FILE
folder: PLUGIN_ADMIN.FOLDER
accounts.avatar:
type: select
label: PLUGIN_ADMIN.AVATAR
default: gravatar
help: PLUGIN_ADMIN.AVATAR_HELP
options:
multiavatar: Multiavatar [local]
gravatar: Gravatar [external]
# experimental:
# type: tab
# title: PLUGIN_ADMIN.EXPERIMENTAL
#
# fields:
# experimental_section:
# type: section
# title: PLUGIN_ADMIN.EXPERIMENTAL
# underline: true
#
# flex_pages:
# type: section
# title: Flex Pages
#
# pages.type:
# type: select
# label: PLUGIN_ADMIN.PAGES_TYPE
# highlight: regular
# help: PLUGIN_ADMIN.PAGES_TYPE_HELP
# options:
# regular: PLUGIN_ADMIN.REGULAR
# flex: PLUGIN_ADMIN.FLEX
#
# pages.type:
# type: hidden

View File

@@ -15,6 +15,17 @@ form:
multiple: false
random_name: true
multiavatar_only:
type: conditional
condition: config.system.accounts.avatar == 'multiavatar'
fields:
avatar_hash:
type: text
label: ''
placeholder: 'e.g. dceaadcfda491f4e45'
description: PLUGIN_ADMIN.AVATAR_HASH
size: large
content:
type: section
title: PLUGIN_ADMIN.ACCOUNT

View File

@@ -208,6 +208,7 @@ http:
accounts:
type: regular # EXPERIMENTAL: Account type: regular or flex
storage: file # EXPERIMENTAL: Flex storage type: file or folder
avatar: gravatar # Avatar generator [multiavatar|gravatar]
flex:
cache:

View File

@@ -9,12 +9,15 @@
namespace Grav\Common\User\Traits;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Grav\Common\Page\Medium\ImageMedium;
use Grav\Common\Page\Medium\Medium;
use Grav\Common\Page\Medium\StaticImageMedium;
use Grav\Common\User\Authentication;
use Grav\Common\Utils;
use Multiavatar;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use function is_array;
use function is_string;
@@ -175,9 +178,52 @@ trait UserTrait
}
$email = $this->get('email');
$avatar_generator = Grav::instance()['config']->get('system.accounts.avatar', 'multiavatar');
if ($avatar_generator === 'gravatar') {
if (!$email) {
return '';
}
$hash = md5(strtolower(trim($email)));
return 'https://www.gravatar.com/avatar/' . $hash;
}
$hash = $this->get('avatar_hash');
if (!$hash) {
$username = $this->get('username');
$hash = md5(strtolower(trim($email ?? $username)));
}
return $this->generateMultiavatar($hash);
}
/**
* @param string $hash
* @return string
*/
protected function generateMultiavatar(string $hash): string
{
/** @var UniformResourceLocator $locator */
$locator = Grav::instance()['locator'];
$storage = $locator->findResource('image://multiavatar', true, true);
$avatar_file = "{$storage}/{$hash}.svg";
if (!file_exists($storage)) {
Folder::create($storage);
}
if (!file_exists($avatar_file)) {
$mavatar = new Multiavatar();
file_put_contents($avatar_file, $mavatar->generate($hash, null, null));
}
$avatar_url = $locator->findResource("image://multiavatar/{$hash}.svg", false, true);
return Utils::url($avatar_url);
// By default fall back to gravatar image.
return $email ? 'https://www.gravatar.com/avatar/' . md5(strtolower(trim($email))) : '';
}
abstract public function get($name, $default = null, $separator = null);

View File

@@ -134,14 +134,13 @@ abstract class Utils
$resource = $locator->findResource($input, false);
}
} else {
// $root = $uri->rootUrl();
// $pattern = '/(' . '\\' . $root . '[\s\/])/';
// if (preg_match($pattern, $input, $matches)) {
// $input = static::replaceFirstOccurrence($matches[0], '', $input);
// }
$root = preg_quote($uri->rootUrl(), '#');
$pattern = '#(' . $root . '$|' . $root . '/)#';
if (!empty($root) && preg_match($pattern, $input, $matches)) {
$input = static::replaceFirstOccurrence($matches[0], '', $input);
}
$input = ltrim($input, '/');
$resource = $input;
}

View File

@@ -503,21 +503,25 @@ class UtilsTest extends \Codeception\TestCase\Test
self::assertSame('http://testing.dev/subdir/random/path1/path2/foobar.jpg', Utils::url('/random/path1/path2/foobar.jpg', true));
// Absolute Paths including the grav base.
self::assertSame('/subdir/subdir', Utils::url('/subdir'));
self::assertSame('/subdir/subdir/path1', Utils::url('/subdir/path1'));
self::assertSame('/subdir/subdir/path1/path2', Utils::url('/subdir/path1/path2'));
self::assertSame('/subdir/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg'));
self::assertSame('/subdir/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg'));
self::assertSame('/subdir/', Utils::url('/subdir'));
self::assertSame('/subdir/', Utils::url('/subdir/'));
self::assertSame('/subdir/path1', Utils::url('/subdir/path1'));
self::assertSame('/subdir/path1/path2', Utils::url('/subdir/path1/path2'));
self::assertSame('/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg'));
self::assertSame('/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg'));
// Absolute paths from Grav root with domain.
self::assertSame('http://testing.dev/subdir/subdir', Utils::url('/subdir', true));
self::assertSame('http://testing.dev/subdir/subdir/path1', Utils::url('/subdir/path1', true));
self::assertSame('http://testing.dev/subdir/subdir/path1/path2', Utils::url('/subdir/path1/path2', true));
self::assertSame('http://testing.dev/subdir/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true));
self::assertSame('http://testing.dev/subdir/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true));
self::assertSame('http://testing.dev/subdir/', Utils::url('/subdir', true));
self::assertSame('http://testing.dev/subdir/', Utils::url('/subdir/', true));
self::assertSame('http://testing.dev/subdir/path1', Utils::url('/subdir/path1', true));
self::assertSame('http://testing.dev/subdir/path1/path2', Utils::url('/subdir/path1/path2', true));
self::assertSame('http://testing.dev/subdir/foobar.jpg', Utils::url('/subdir/foobar.jpg', true));
self::assertSame('http://testing.dev/subdir/path1/foobar.jpg', Utils::url('/subdir/path1/foobar.jpg', true));
// Relative paths from Grav root.
self::assertSame('/subdir/sub', Utils::url('/sub'));
self::assertSame('/subdir/subdir', Utils::url('subdir'));
self::assertSame('/subdir/subdir2/sub', Utils::url('/subdir2/sub'));
self::assertSame('/subdir/subdir/path1', Utils::url('subdir/path1'));
self::assertSame('/subdir/subdir/path1/path2', Utils::url('subdir/path1/path2'));
self::assertSame('/subdir/path1', Utils::url('path1'));