Skip to content

Commit

Permalink
Merge branch '5.x' into feature/table-fields-permission
Browse files Browse the repository at this point in the history
  • Loading branch information
leofeyer committed Jul 14, 2022
2 parents c778dc6 + 789ad3a commit 63df58d
Show file tree
Hide file tree
Showing 124 changed files with 2,294 additions and 3,595 deletions.
24 changes: 24 additions & 0 deletions UPGRADE.md
Expand Up @@ -7,6 +7,26 @@
The `exclude` property on DCA fields is no longer initialized when loading a back end module. Make sure to check for
`ContaoCorePermission::CAN_EDIT_FIELD_OF_TABLE` to know if a field should be available to a user.

### checkCredentials hook

The `checkCredentials` hook has been removed. Use the `CheckPassportEvent` instead.

### postLogin hook

The `postLogin` hook has been removed. Use the `LoginSuccessEvent` instead.

### importUser hook

The `importUser` hook has been removed. Implement a custom `UserProvider` service instead.

### postAuthenticate hook

The `postAuthenticate` hook has been removed. Use the `LoginSuccessEvent` instead.

### postLogout hook

The `postLogout` hook has been removed. Use the `LogoutEvent` instead.

### Contao 4 migrations

Contao 5 does not include any Contao 4 migrations, so make sure to upgrade to Contao 4.13 before upgrading to Contao 5!
Expand Down Expand Up @@ -191,6 +211,8 @@ The following content element types have been rewritten as fragment controllers
- `toplink` (`ce_toplink``content_element/toplink`)
- `image` (`ce_image``content_element/image`)
- `gallery` (`ce_gallery``content_element/gallery`)
- `youtube` (`ce_youtube``content_element/youtube`)
- `vimeo` (`ce_vimeo``content_element/vimeo`)

The legacy content elements and their templates are still around and will only be dropped in Contao 6. If you want to
use them instead of the new ones, you can opt in on a per-element basis by adding the respective lines to your
Expand All @@ -208,6 +230,8 @@ $GLOBALS['TL_CTE']['links']['hyperlink'] = \Contao\ContentHyperlink::class;
$GLOBALS['TL_CTE']['links']['toplink'] = \Contao\ContentToplink::class;
$GLOBALS['TL_CTE']['media']['image'] = \Contao\ContentImage::class;
$GLOBALS['TL_CTE']['media']['gallery'] = \Contao\ContentGallery::class;
$GLOBALS['TL_CTE']['media']['youtube'] = \Contao\ContentYouTube::class;
$GLOBALS['TL_CTE']['media']['vimeo'] = \Contao\ContentVimeo::class;
```

### Show to guests only
Expand Down
4 changes: 0 additions & 4 deletions calendar-bundle/src/Picker/EventPickerProvider.php
Expand Up @@ -60,10 +60,6 @@ public function getDcaAttributes(PickerConfig $config): array
{
$attributes = ['fieldType' => 'radio'];

if ($source = $config->getExtra('source')) {
$attributes['preserveRecord'] = $source;
}

if ($this->supportsValue($config)) {
$attributes['value'] = $this->getInsertTagValue($config);

Expand Down
2 changes: 0 additions & 2 deletions calendar-bundle/tests/Picker/EventPickerProviderTest.php
Expand Up @@ -102,7 +102,6 @@ public function testReturnsTheDcaAttributes(): void
$this->assertSame(
[
'fieldType' => 'radio',
'preserveRecord' => 'tl_calendar_events.2',
'value' => '5',
'flags' => ['urlattr'],
],
Expand All @@ -112,7 +111,6 @@ public function testReturnsTheDcaAttributes(): void
$this->assertSame(
[
'fieldType' => 'radio',
'preserveRecord' => 'tl_calendar_events.2',
],
$picker->getDcaAttributes(new PickerConfig('link', $extra, '{{link_url::5}}'))
);
Expand Down
14 changes: 7 additions & 7 deletions composer.json
Expand Up @@ -90,9 +90,9 @@
"psr/container": "^1.0",
"psr/http-message": "^1.0",
"psr/log": "^1.0",
"scheb/2fa-backup-code": "^5.8",
"scheb/2fa-bundle": "^5.8",
"scheb/2fa-trusted-device": "^5.8",
"scheb/2fa-backup-code": "^6.0",
"scheb/2fa-bundle": "^6.0",
"scheb/2fa-trusted-device": "^6.0",
"scrivo/highlight.php": "^9.18",
"scssphp/scssphp": "^1.5",
"simplepie/simplepie": "^1.3",
Expand Down Expand Up @@ -136,10 +136,10 @@
"symfony/property-access": "^5.4",
"symfony/proxy-manager-bridge": "^5.4",
"symfony/routing": "^5.4",
"symfony/security-bundle": "^5.4",
"symfony/security-core": "^5.4",
"symfony/security-csrf": "^5.4",
"symfony/security-http": "^5.4",
"symfony/security-bundle": "^6.0.2",
"symfony/security-core": "^6.1",
"symfony/security-csrf": "^6.0",
"symfony/security-http": "^6.0",
"symfony/service-contracts": "^1.1 || ^2.0",
"symfony/stopwatch": "^5.4",
"symfony/string": "^5.4",
Expand Down
9 changes: 4 additions & 5 deletions core-bundle/README.md
Expand Up @@ -64,22 +64,21 @@ sections:

```yml
security:
password_hashers:
Contao\User: auto

providers:
contao.security.backend_user_provider:
id: contao.security.backend_user_provider

contao.security.frontend_user_provider:
id: contao.security.frontend_user_provider

password_hashers:
Contao\User: auto

firewalls:
contao_backend:
request_matcher: contao.routing.backend_matcher
provider: contao.security.backend_user_provider
user_checker: contao.security.user_checker
anonymous: ~
switch_user: true

contao_login:
Expand All @@ -92,7 +91,6 @@ security:
request_matcher: contao.routing.frontend_matcher
provider: contao.security.frontend_user_provider
user_checker: contao.security.user_checker
anonymous: ~
switch_user: false

contao_login:
Expand All @@ -101,6 +99,7 @@ security:
remember_me:
secret: '%kernel.secret%'
remember_me_parameter: autologin
service: contao.security.persistent_remember_me_handler

logout:
path: contao_frontend_logout
Expand Down
14 changes: 7 additions & 7 deletions core-bundle/composer.json
Expand Up @@ -88,9 +88,9 @@
"psr/container": "^1",
"psr/http-message": "^1.0",
"psr/log": "^1.0",
"scheb/2fa-backup-code": "^5.8",
"scheb/2fa-bundle": "^5.8",
"scheb/2fa-trusted-device": "^5.8",
"scheb/2fa-backup-code": "^6.0",
"scheb/2fa-bundle": "^6.0",
"scheb/2fa-trusted-device": "^6.0",
"scrivo/highlight.php": "^9.18",
"scssphp/scssphp": "^1.5",
"simplepie/simplepie": "^1.3",
Expand Down Expand Up @@ -127,10 +127,10 @@
"symfony/process": "^5.4",
"symfony/property-access": "^5.4",
"symfony/routing": "^5.4",
"symfony/security-bundle": "^5.4",
"symfony/security-core": "^5.4",
"symfony/security-csrf": "^5.4",
"symfony/security-http": "^5.4",
"symfony/security-bundle": "^6.0.2",
"symfony/security-core": "^6.1",
"symfony/security-csrf": "^6.0",
"symfony/security-http": "^6.0",
"symfony/service-contracts": "^1.1 || ^2.0",
"symfony/string": "^5.4",
"symfony/translation": "^5.4",
Expand Down
1 change: 0 additions & 1 deletion core-bundle/phpunit.xml.dist
Expand Up @@ -65,7 +65,6 @@
</listener>
</listeners>
<extensions>
<extension class="Contao\CoreBundle\Tests\PhpunitExtension\DeprecatedClasses"/>
<extension class="Contao\TestCase\ClearCachePhpunitExtension"/>
</extensions>
</phpunit>
4 changes: 1 addition & 3 deletions core-bundle/src/ContaoCoreBundle.php
Expand Up @@ -29,7 +29,6 @@
use Contao\CoreBundle\DependencyInjection\Compiler\RegisterFragmentsPass;
use Contao\CoreBundle\DependencyInjection\Compiler\RegisterHookListenersPass;
use Contao\CoreBundle\DependencyInjection\Compiler\RegisterPagesPass;
use Contao\CoreBundle\DependencyInjection\Compiler\RemembermeServicesPass;
use Contao\CoreBundle\DependencyInjection\Compiler\RewireTwigPathsPass;
use Contao\CoreBundle\DependencyInjection\Compiler\SearchIndexerPass;
use Contao\CoreBundle\DependencyInjection\Compiler\TaggedMigrationsPass;
Expand Down Expand Up @@ -69,7 +68,7 @@ public function build(ContainerBuilder $container): void

/** @var SecurityExtension $extension */
$extension = $container->getExtension('security');
$extension->addSecurityListenerFactory(new ContaoLoginFactory());
$extension->addAuthenticatorFactory(new ContaoLoginFactory());

$container->addCompilerPass(
new AddEventAliasesPass([
Expand Down Expand Up @@ -109,7 +108,6 @@ public function build(ContainerBuilder $container): void
)
);

$container->addCompilerPass(new RemembermeServicesPass('contao_frontend'));
$container->addCompilerPass(new DataContainerCallbackPass());
$container->addCompilerPass(new TranslationDataCollectorPass());
$container->addCompilerPass(new RegisterHookListenersPass(), PassConfig::TYPE_OPTIMIZE);
Expand Down
6 changes: 6 additions & 0 deletions core-bundle/src/Controller/BackendPreviewSwitchController.php
Expand Up @@ -128,6 +128,12 @@ private function authenticatePreview(Request $request): Response

if ($this->security->isGranted('ROLE_ALLOWED_TO_SWITCH_MEMBER')) {
$frontendUsername = $request->request->get('user');

// Logout the current logged-in user if an empty user is submitted
if ('' === $frontendUsername && null !== $this->tokenChecker->getFrontendUsername()) {
$this->previewAuthenticator->removeFrontendAuthentication();
$frontendUsername = null;
}
}

$showUnpublished = 'hide' !== $request->request->get('unpublished');
Expand Down
158 changes: 158 additions & 0 deletions core-bundle/src/Controller/ContentElement/VideoController.php
@@ -0,0 +1,158 @@
<?php

declare(strict_types=1);

/*
* This file is part of Contao.
*
* (c) Leo Feyer
*
* @license LGPL-3.0-or-later
*/

namespace Contao\CoreBundle\Controller\ContentElement;

use Contao\ContentModel;
use Contao\CoreBundle\Image\Studio\Studio;
use Contao\CoreBundle\ServiceAnnotation\ContentElement;
use Contao\CoreBundle\Twig\FragmentTemplate;
use Contao\StringUtil;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* @ContentElement("vimeo", category="media")
* @ContentElement("youtube", category="media")
*
* @phpstan-type VideoSourceParameters array{
* provider: 'vimeo'|'youtube',
* video_id: string,
* options: array<string, string>,
* base_url: string,
* query: string,
* url: string
* }
*/
class VideoController extends AbstractContentElementController
{
public function __construct(private readonly Studio $studio)
{
}

protected function getResponse(FragmentTemplate $template, ContentModel $model, Request $request): Response
{
// Video source data, size and aspect ratio
$sourceParameters = match ($type = $template->get('type')) {
'vimeo' => $this->getVimeoSourceParameters($model),
'youtube' => $this->getYoutubeSourceParameters($model, $request->getLocale()),
default => throw new \InvalidArgumentException(sprintf('Unknown video provider "%s".', $type))
};

$template->set('source', $sourceParameters);

$size = StringUtil::deserialize($model->playerSize, true);

$template->set('width', $size[0] ?? 640);
$template->set('height', $size[1] ?? 360);
$template->set('aspect_ratio', $model->playerAspect);

// Meta data
$template->set('caption', $model->playerCaption);

// Splash image
$figure = !$model->splashImage ? null : $this->studio
->createFigureBuilder()
->fromUuid($model->singleSRC ?: '')
->setSize($model->size)
->buildIfResourceExists()
;

$template->set('splash_image', $figure);

return $template->getResponse();
}

/**
* @return array<string, string|array<string, string>>
*
* @phpstan-return VideoSourceParameters
*/
private function getVimeoSourceParameters(ContentModel $model): array
{
$options = [];

foreach (StringUtil::deserialize($model->vimeoOptions, true) as $option) {
[$option, $value] = match ($option) {
'vimeo_portrait', 'vimeo_title', 'vimeo_byline' => [substr($option, 6), '0'],
default => [substr($option, 6), '1'],
};

$options[$option] = $value;
}

if ($color = $model->playerColor) {
$options['color'] = $color;
}

$query = http_build_query($options);

if (($start = $model->playerStart) > 0) {
$options['start'] = $start;
$query .= "#t={$start}s";
}

return [
'provider' => 'vimeo',
'video_id' => $videoId = $model->vimeo,
'options' => $options,
'base_url' => $baseUrl = "https://player.vimeo.com/video/$videoId",
'query' => $query,
'url' => empty($query) ? $baseUrl : "$baseUrl?$query",
];
}

/**
* @return array<string, string|array<string, string>>
*
* @phpstan-return VideoSourceParameters
*/
private function getYoutubeSourceParameters(ContentModel $model, string $locale): array
{
$options = [];
$domain = 'https://www.youtube.com';

foreach (StringUtil::deserialize($model->youtubeOptions, true) as $option) {
if ('youtube_nocookie' === $option) {
$domain = 'https://www.youtube-nocookie.com';

continue;
}

[$option, $value] = match ($option) {
'youtube_fs', 'youtube_rel', 'youtube_controls' => [substr($option, 8), '0'],
'youtube_hl' => [substr($option, 8), \Locale::parseLocale($locale)[\Locale::LANG_TAG] ?? ''],
'youtube_iv_load_policy' => [substr($option, 8), '3'],
default => [substr($option, 8), '1'],
};

$options[$option] = $value;
}

if (($start = $model->playerStart) > 0) {
$options['start'] = $start;
}

if (($end = $model->playerStop) > 0) {
$options['end'] = $end;
}

return [
'provider' => 'youtube',
'video_id' => $videoId = $model->youtube,
'options' => $options,
'base_url' => $baseUrl = "$domain/embed/$videoId",
'query' => $query = http_build_query($options),
'url' => empty($query) ? $baseUrl : "$baseUrl?$query",
];
}
}
Expand Up @@ -31,11 +31,13 @@ class MakeServicesPublicPass implements CompilerPassInterface
'monolog.logger.contao',
'security.authentication_utils',
'security.authentication.trust_resolver',
'security.authorization_checker',
'security.encoder_factory',
'security.firewall.map',
'security.helper',
'security.logout_url_generator',
'security.password_hasher_factory',
'security.token_storage',
'uri_signer',
];

Expand Down

0 comments on commit 63df58d

Please sign in to comment.