Skip to content

Commit

Permalink
Merge PR #622 from @zonky2
Browse files Browse the repository at this point in the history
- Fix rebase from pr #608^
- Fix show languages at untranslated models in edit mask
  • Loading branch information
stefanheimes committed Nov 30, 2023
2 parents 0e7e189 + 829eeb5 commit cf7f3a4
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 53 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
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;
}
}
33 changes: 24 additions & 9 deletions src/DC/General.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
/**
* This class is only present so Contao can instantiate a backend properly as it needs a \DataContainer descendant.
*
* @psalm-suppress PropertyNotSetInConstructor
*
* @SuppressWarnings(PHPMD.TooManyPublicMethods)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
Expand All @@ -58,7 +60,7 @@ class General extends DataContainer implements DataContainerInterface
/**
* The environment attached to this DC.
*
* @var EnvironmentInterface
* @var EnvironmentInterface|null
*/
protected $objEnvironment;

Expand Down Expand Up @@ -95,6 +97,7 @@ public function __construct($tableName, array $module = [], CacheInterface $cach
}
$this->objEnvironment = $event->getEnvironment();
}, $this, $this);
assert($fetcher instanceof \Closure);
$dispatcher->addListener(PopulateEnvironmentEvent::NAME, $fetcher, 4800);

(new DcGeneralFactory($cache))
Expand All @@ -121,19 +124,25 @@ public function __construct($tableName, array $module = [], CacheInterface $cach
*
* @return EventDispatcherInterface
*/
private function getEventDispatcher()
private function getEventDispatcher(): EventDispatcherInterface
{
return System::getContainer()->get('event_dispatcher');
$dispatcher = System::getContainer()->get('event_dispatcher');
assert($dispatcher instanceof EventDispatcherInterface);

return $dispatcher;
}

/**
* Get the translator from the service container.
*
* @return TranslatorInterface
*/
private function getTranslator()
private function getTranslator(): TranslatorInterface
{
return System::getContainer()->get('cca.translator.contao_translator');
$translator = System::getContainer()->get('cca.translator.contao_translator');
assert($translator instanceof TranslatorInterface);

return $translator;
}

/**
Expand Down Expand Up @@ -240,7 +249,7 @@ public function getName()
*/
public function getEnvironment()
{
if (!$this->objEnvironment) {
if (null === $this->objEnvironment) {
throw new DcGeneralRuntimeException('No Environment set.');
}

Expand All @@ -254,7 +263,10 @@ public function getEnvironment()
*/
public function getViewHandler()
{
return $this->getEnvironment()->getView();
$view = $this->getEnvironment()->getView();
assert($view instanceof ViewInterface);

return $view;
}

/**
Expand All @@ -264,7 +276,10 @@ public function getViewHandler()
*/
public function getControllerHandler()
{
return $this->getEnvironment()->getController();
$controller = $this->getEnvironment()->getController();
assert($controller instanceof ControllerInterface);

return $controller;
}

/**
Expand Down Expand Up @@ -416,7 +431,7 @@ public function undo()
*
* @deprecated Only here as requirement of \DataContainer
*
* @return void
* @return never
*
* @throws DcGeneralRuntimeException Throws exception because method is not supported.
*/
Expand Down
Loading

0 comments on commit cf7f3a4

Please sign in to comment.