Skip to content

Commit

Permalink
Merge tag '2.3.4'
Browse files Browse the repository at this point in the history
Hotfix release 2.3.4

- Fix group per week
- Fix show languages at untranslated models in edit mask
  • Loading branch information
stefanheimes committed Nov 30, 2023
2 parents 0e7e189 + de1d82a commit 16a2f6c
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 62 deletions.
3 changes: 3 additions & 0 deletions src/Contao/Callback/Callbacks.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ protected static function evaluateCallback($callback)
if ($serviceCallback[0] !== $callback[0]) {
return $serviceCallback;
}
if (!\class_exists($callback[0])) {
return $callback;
}

$class = new ReflectionClass($callback[0]);

Expand Down
50 changes: 37 additions & 13 deletions src/Contao/Compatibility/DcCompat.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,43 @@

namespace ContaoCommunityAlliance\DcGeneral\Contao\Compatibility;

use ContaoCommunityAlliance\DcGeneral\Data\DataProviderInterface;
use ContaoCommunityAlliance\DcGeneral\Data\ModelId;
use ContaoCommunityAlliance\DcGeneral\Data\ModelInterface;
use ContaoCommunityAlliance\DcGeneral\DataDefinition\ContainerInterface;
use ContaoCommunityAlliance\DcGeneral\DC\General;
use ContaoCommunityAlliance\DcGeneral\EnvironmentInterface;
use ContaoCommunityAlliance\DcGeneral\Exception\DcGeneralException;
use ContaoCommunityAlliance\DcGeneral\Exception\DcGeneralRuntimeException;
use ContaoCommunityAlliance\DcGeneral\Factory\Event\PopulateEnvironmentEvent;
use ContaoCommunityAlliance\DcGeneral\InputProviderInterface;

/**
* Small compatibility layer for callbacks, that expect a "full-featured" DC instance.
*
* @psalm-suppress PropertyNotSetInConstructor
*/
class DcCompat extends General
{
/**
* The current model.
*
* @var ModelInterface
* @var ModelInterface|null
*/
protected $model;

/**
* Name of the property currently working on.
*
* @var string
* @var string|null
*/
protected $propertyName;

/**
* Create a new instance.
*
* @param EnvironmentInterface $environment The Dc instance to use for delegating.
* @param ModelInterface $model The model within scope (optional).
* @param ModelInterface|null $model The model within scope (optional).
* @param string|null $propertyName The name of the property within scope (optional).
*/
public function __construct(EnvironmentInterface $environment, ModelInterface $model = null, $propertyName = null)
Expand All @@ -71,7 +76,7 @@ public function __construct(EnvironmentInterface $environment, ModelInterface $m
/**
* Retrieve the current model.
*
* @return ModelInterface
* @return ModelInterface|null
*/
public function getModel()
{
Expand All @@ -81,17 +86,21 @@ public function getModel()
/**
* Retrieve the current property.
*
* @return string
* @return string|null
*/
public function getPropertyName()
{
return $this->propertyName;
}

/**
* {@inheritdoc}
* Internal use only.
*
* @throws DcGeneralException This method is for internal use only.
*
* @return never
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function handlePopulateEnvironment(PopulateEnvironmentEvent $event)
{
Expand All @@ -105,7 +114,7 @@ public function handlePopulateEnvironment(PopulateEnvironmentEvent $event)
*
* @throws DcGeneralException This method is for internal use only.
*/
protected function getTablenameCallback($strTable)
protected function getTablenameCallback($tableName)
{
throw new DcGeneralException(
__CLASS__ . '::getTablenameCallback() is internal use only and must not be called'
Expand Down Expand Up @@ -134,12 +143,18 @@ public function __get($name)
switch ($name) {
case 'id':
if (null !== $this->getModel()) {
return $this->getModel()->getId();
$model = $this->getModel();
assert($model instanceof ModelInterface);
return $model->getId();
}

$environment = $this->getEnvironment();
$environment = $this->getEnvironment();

$dataDefinition = $environment->getDataDefinition();
$inputProvider = $environment->getInputProvider();
assert($dataDefinition instanceof ContainerInterface);

$inputProvider = $environment->getInputProvider();
assert($inputProvider instanceof InputProviderInterface);

$idParameter = $inputProvider->hasParameter('id') ? 'id' : 'pid';
if (!$inputProvider->hasParameter($idParameter)) {
Expand Down Expand Up @@ -168,7 +183,10 @@ public function __get($name)

case 'parentTable':
if ($this->getEnvironment()->getParentDataDefinition()) {
return $this->getEnvironment()->getParentDataDefinition()->getName();
$container = $this->getEnvironment()->getParentDataDefinition();
assert($container instanceof ContainerInterface);

return $container->getName();
}
return null;

Expand All @@ -182,11 +200,16 @@ public function __get($name)
throw new DcGeneralRuntimeException('The magic property $dc->createNewVersion is not supported yet!');

case 'table':
return $this->getEnvironment()->getDataProvider()->getEmptyModel()->getProviderName();
$dataProvider = $this->getEnvironment()->getDataProvider();
assert($dataProvider instanceof DataProviderInterface);

return $dataProvider->getEmptyModel()->getProviderName();

case 'value':
if ($this->propertyName && $this->getModel()) {
return $this->getModel()->getProperty($this->propertyName);
$model = $this->getModel();
assert($model instanceof ModelInterface);
return $model->getProperty($this->propertyName);
}
return null;

Expand All @@ -200,6 +223,7 @@ public function __get($name)
throw new DcGeneralRuntimeException('The magic property $dc->palette is not supported yet!');

case 'activeRecord':
assert($this->model instanceof ModelInterface);
return new ActiveRecord($this->model);

default:
Expand Down
21 changes: 9 additions & 12 deletions src/Contao/Dca/Builder/Legacy/LegacyDcaDataDefinitionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* This file is part of contao-community-alliance/dc-general.
*
* (c) 2013-2022 Contao Community Alliance.
* (c) 2013-2023 Contao Community Alliance.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
Expand All @@ -17,7 +17,7 @@
* @author Stefan Heimes <[email protected]>
* @author Sven Baumann <[email protected]>
* @author Ingolf Steinhardt <[email protected]>
* @copyright 2013-2022 Contao Community Alliance.
* @copyright 2013-2023 Contao Community Alliance.
* @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later
* @filesource
*/
Expand Down Expand Up @@ -162,7 +162,7 @@ public function build(ContainerInterface $container, BuildDataDefinitionEvent $e
* Register the callback handlers for the given legacy callbacks.
*
* @param EventDispatcherInterface $dispatcher The event dispatcher.
* @param array $callbacks The callbacks to be handled.
* @param list<callable>|callable $callbacks The callbacks to be handled.
* @param string $eventName The event to be registered to.
* @param array $arguments The arguments to pass to the constructor.
* @param class-string $listener The listener class to use.
Expand All @@ -175,14 +175,11 @@ public function build(ContainerInterface $container, BuildDataDefinitionEvent $e
*/
protected function parseCallback($dispatcher, $callbacks, $eventName, $arguments, $listener)
{
if (!(is_array($callbacks) || is_callable($callbacks))) {
return;
}

// If only one callback given, ensure the loop below handles it correctly.
if (is_array($callbacks) && (2 === count($callbacks)) && !is_array($callbacks[0])) {
if (is_array($callbacks) && (2 === count($callbacks)) && !is_array($callbacks[0] ?? [])) {
$callbacks = [$callbacks];
}

foreach ((array) $callbacks as $callback) {
if ($this->isCallbackBlacklisted($callback, $listener)) {
continue;
Expand All @@ -198,17 +195,17 @@ protected function parseCallback($dispatcher, $callbacks, $eventName, $arguments
/**
* Check if callback is blacklisted.
*
* @param mixed $callback The callback.
* @param string $listener The listener class.
* @param mixed $callback The callback.
* @param class-string $listener The listener class.
*
* @return bool
*/
private function isCallbackBlacklisted($callback, $listener)
private function isCallbackBlacklisted(mixed $callback, string $listener): bool
{
return ((ContainerOnLoadCallbackListener::class === $listener)
&& is_array($callback)
&& ('checkPermission' === $callback[1])
&& (0 === strpos($callback[0], 'tl_')));
&& (str_starts_with($callback[0], 'tl_')));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,11 @@ private function renderFieldSets(
private function getModelFromWidget(Widget $widget): ModelInterface
{
if ($widget->dataContainer instanceof DcCompat) {
return $widget->dataContainer->getModel();
$model = $widget->dataContainer->getModel();
if (null === $model) {
throw new \InvalidArgumentException('Datacontainer does not hold a model.');
}
return $model;
}
if ($widget instanceof AbstractWidget) {
return $widget->getModel();
Expand Down
17 changes: 4 additions & 13 deletions src/Contao/View/Contao2BackendView/EditMask.php
Original file line number Diff line number Diff line change
Expand Up @@ -1021,17 +1021,10 @@ public function execute()
private function executeMultiLanguage(ContaoBackendViewTemplate $template)
{
$dataProvider = $this->getEnvironment()->getDataProvider($this->model->getProviderName());
assert($dataProvider instanceof DataProviderInterface);

if (
\in_array(
MultiLanguageDataProviderInterface::class,
\class_implements($dataProvider)
)
$dataProvider instanceof MultiLanguageDataProviderInterface
&& null !== $dataProvider->getLanguages($this->model->getId())
) {
/** @var MultiLanguageDataProviderInterface $dataProvider */
$dataProvider = $this->getEnvironment()->getDataProvider();

$locales = System::getContainer()->get('contao.intl.locales');
assert($locales instanceof Locales);

Expand All @@ -1043,10 +1036,8 @@ private function executeMultiLanguage(ContaoBackendViewTemplate $template)
$translator = $this->environment->getTranslator();
assert($translator instanceof TranslatorInterface);

$template->set(
'languages',
$controller->getSupportedLanguages($this->model->getId())
)
$template
->set('languages', $controller->getSupportedLanguages($this->model->getId()))
->set('language', $dataProvider->getCurrentLanguage())
->set('languageSubmit', $translator->translate('MSC.showSelected'))
->set('languageHeadline', $languages[$dataProvider->getCurrentLanguage()] ?? '');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ class GetGroupHeaderSubscriber
*
* @var EventDispatcherInterface
*/
private $dispatcher;
private EventDispatcherInterface $dispatcher;

/**
* The translator.
*
* @var TranslatorInterface
*/
private $translator;
private TranslatorInterface $translator;

/**
* Create a new instance.
Expand Down Expand Up @@ -136,6 +136,7 @@ protected function formatGroupHeader(
if (isset($evaluation['multiple']) && !$evaluation['multiple'] && ('checkbox' === $property->getWidgetType())) {
return $this->formatCheckboxOptionLabel($model->getProperty($property->getName()));
}

if (GroupAndSortingInformationInterface::GROUP_NONE !== $groupingMode) {
return $this->formatByGroupingMode($groupingMode, $groupingLength, $environment, $property, $model);
}
Expand Down Expand Up @@ -240,9 +241,9 @@ private function formatByCharGrouping($value, $groupingLength)
*
* @param int $value The value.
*
* @return string|null
* @return string
*/
private function formatByDayGrouping(int $value): ?string
private function formatByDayGrouping(int $value): string
{
$value = $this->getTimestamp($value);

Expand All @@ -263,13 +264,14 @@ private function formatByDayGrouping(int $value): ?string
*
* @return string
*/
private function formatByWeekGrouping(int $value): ?string
private function formatByWeekGrouping(int $value): string
{
$value = $this->getTimestamp($value);

if (0 === $value) {
return '-';
}

$event = new ParseDateEvent($value, $this->translator->translate('MSC.week_format'));
$this->dispatcher->dispatch($event, ContaoEvents::DATE_PARSE);

Expand All @@ -281,15 +283,16 @@ private function formatByWeekGrouping(int $value): ?string
*
* @param int $value The value.
*
* @return string|null
* @return string
*/
private function formatByMonthGrouping(int $value): ?string
private function formatByMonthGrouping(int $value): string
{
$value = $this->getTimestamp($value);

if (0 === $value) {
return '-';
}

$event = new ParseDateEvent($value, 'F Y');
$this->dispatcher->dispatch($event, ContaoEvents::DATE_PARSE);

Expand Down Expand Up @@ -317,11 +320,11 @@ private function formatByYearGrouping($value)
/**
* Make sure a timestamp is returned.
*
* @param int|\DateTime $value The given date.
* @param \DateTime|int $value The given date.
*
* @return int
*/
private function getTimestamp($value)
private function getTimestamp(\DateTime|int $value): int
{
return ($value instanceof \DateTime) ? $value->getTimestamp() : $value;
}
Expand Down
10 changes: 7 additions & 3 deletions src/Contao/View/Contao2BackendView/Widget/AbstractWidget.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* This file is part of contao-community-alliance/dc-general.
*
* (c) 2013-2019 Contao Community Alliance.
* (c) 2013-2023 Contao Community Alliance.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
Expand All @@ -14,7 +14,8 @@
* @author David Molineus <[email protected]>
* @author Christian Schiffler <[email protected]>
* @author Sven Baumann <[email protected]>
* @copyright 2013-2019 Contao Community Alliance.
* @author Ingolf Steinhardt <[email protected]>
* @copyright 2013-2023 Contao Community Alliance.
* @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0-or-later
* @filesource
*/
Expand Down Expand Up @@ -91,6 +92,9 @@ public function getEnvironment()
public function getModel()
{
assert($this->dataContainer instanceof DcCompat);
return $this->dataContainer->getModel();
$model = $this->dataContainer->getModel();
assert($model instanceof ModelInterface);

return $model;
}
}
Loading

0 comments on commit 16a2f6c

Please sign in to comment.