Skip to content

Commit

Permalink
Merge pull request #321
Browse files Browse the repository at this point in the history
This is an attempt to solve #303 (which is duped by MetaModels/core#35).

Deprecates `DataProviderInterface::resetFallback()`.
  • Loading branch information
discordier committed Dec 8, 2016
2 parents 8293b9b + 5689fe7 commit 086638b
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace ContaoCommunityAlliance\DcGeneral\Contao\Subscriber;

use ContaoCommunityAlliance\DcGeneral\Data\ConfigInterface;
use ContaoCommunityAlliance\DcGeneral\Event\AbstractModelAwareEvent;
use ContaoCommunityAlliance\DcGeneral\Event\PostDuplicateModelEvent;
use ContaoCommunityAlliance\DcGeneral\Event\PostPersistModelEvent;
Expand Down Expand Up @@ -99,12 +100,69 @@ private function handleFallback(AbstractModelAwareEvent $event)

$extra = (array) $properties->getProperty($propertyName)->getExtra();
if (array_key_exists('fallback', $extra) && (true === $extra['fallback'])) {
if (!$dataProvider->isUniqueValue($propertyName, $model->getProperty($propertyName), $model->getId())) {
// Reset fallback and save model again to have the correct value.
// BC Layer - use old reset fallback methodology until it get's removed.
if (null === ($config = $this->determineFilterConfig($event))) {
// @codingStandardsIgnoreStart
@trigger_error(
'DataProviderInterface::resetFallback is deprecated - ' .
'Please specify proper parent child relationship',
E_USER_DEPRECATED
);
// @codingStandardsIgnoreEnd

$dataProvider->resetFallback($propertyName);
$dataProvider->save($model);
}

$models = $dataProvider->fetchAll($config);

foreach ($models as $resetModel) {
if ($model->getId() === $resetModel->getId()) {
continue;
}
$resetModel->setProperty($propertyName, null);
$dataProvider->save($resetModel);
}
}
}
}

/**
* Determine the filter config to use.
*
* @param AbstractModelAwareEvent $event The event.
*
* @return ConfigInterface|null
*/
private function determineFilterConfig(AbstractModelAwareEvent $event)
{
$environment = $event->getEnvironment();
$model = $event->getModel();
$dataProvider = $environment->getDataProvider($model->getProviderName());
$definition = $environment->getDataDefinition();
$relationship = $definition->getModelRelationshipDefinition();

$root = $relationship->getRootCondition();
if (null !== $root && $root->matches($model)) {
return $dataProvider->getEmptyConfig()->setFilter($root->getFilterArray());
}

$parentFilter = $relationship->getChildCondition(
$definition->getBasicDefinition()->getParentDataProvider(),
$model->getProviderName()
);

if (null !== $parentFilter) {
$parentConfig = $dataProvider->getEmptyConfig()->setFilter($parentFilter->getInverseFilterFor($model));
$parentProvider = $environment->getDataProvider($parentFilter->getSourceName());
$parent = $parentProvider->fetchAll($parentConfig)->get(0);
return $dataProvider->getEmptyConfig()->setFilter($parentFilter->getFilter($parent));
}

// Trigger BC layer in handleFallback().
if ($root === null && count($relationship->getChildConditions()) == 0) {
return null;
}

return $dataProvider->getEmptyConfig();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,8 @@ public function getActiveVersion($mixID);
* @param string $strField The field to reset.
*
* @return void
*
* @deprecated Handle the resetting manually as you must filter the models.
*/
public function resetFallback($strField);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ protected function createModelFromDatabaseResult($dbResult)
/** @var \Contao\Database\Result $dbResult */
foreach ($dbResult->row() as $key => $value) {
if ($key == $this->idProperty) {
$objModel->setId($value);
$objModel->setIdRaw($value);
}

$objModel->setPropertyRaw($key, deserialize($value));
Expand Down Expand Up @@ -722,6 +722,10 @@ public function isUniqueValue($strField, $varNew, $intId = null)
*/
public function resetFallback($strField)
{
// @codingStandardsIgnoreStart
@trigger_error(__CLASS__ . '::' . __METHOD__ . ' is deprecated - handle resetting manually', E_USER_DEPRECATED);
// @codingStandardsIgnoreEnd

$this->objDatabase->query('UPDATE ' . $this->strSource . ' SET ' . $strField . ' = \'\'');
}

Expand Down
16 changes: 15 additions & 1 deletion src/ContaoCommunityAlliance/DcGeneral/Data/DefaultModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,25 @@ public function getPropertiesAsArray()
public function setID($mixID)
{
if ($this->mixID == null) {
$this->mixID = $mixID;
$this->setIdRaw($mixID);
$this->setMeta(static::IS_CHANGED, true);
}
}

/**
* Set the id for this object.
*
* This method is not interfaced and MUST only be used for initial values from the data provider.
*
* @param mixed $mixID Could be a integer, string or anything else - depends on the provider implementation.
*
* @return void
*/
public function setIdRaw($mixID)
{
$this->mixID = $mixID;
}

/**
* Update the property value in the model.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ public function getActiveVersion($mixID)
*/
public function resetFallback($strField)
{
// @codingStandardsIgnoreStart
@trigger_error(__CLASS__ . '::' . __METHOD__ . ' is deprecated - handle resetting manually', E_USER_DEPRECATED);
// @codingStandardsIgnoreEnd
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ public function getDestinationName()
*/
public function parseFilter($filter, $model)
{
$this->guardProviderNames(null, $model);

$arrApplied = array(
'operation' => $filter['operation'],
);
Expand Down Expand Up @@ -244,6 +246,8 @@ private function isValidSetter($setter)
*/
public function applyTo($objParent, $objChild)
{
$this->guardProviderNames($objChild, $objParent);

$setters = $this->getSetters();

if (empty($setters) || !is_array($setters)) {
Expand Down Expand Up @@ -282,6 +286,9 @@ public function applyTo($objParent, $objChild)
*/
public function copyFrom($sourceModel, $destinationModel)
{
$this->guardProviderNames($sourceModel);
$this->guardProviderNames($destinationModel);

$setters = $this->getSetters();

if (empty($setters) || !is_array($setters)) {
Expand Down Expand Up @@ -318,6 +325,8 @@ public function copyFrom($sourceModel, $destinationModel)
*/
public function getInverseFilterFor($objChild)
{
$this->guardProviderNames($objChild);

$arrResult = array();
foreach ($this->getInverseFilterArray() as $arrRule) {
$arrApplied = array(
Expand Down Expand Up @@ -391,13 +400,20 @@ protected function prepareRule($rule, $child)
*/
public function matches($objParent, $objChild)
{
try {
$this->guardProviderNames($objParent, $objChild);
} catch (\InvalidArgumentException $exception) {
return false;
}

$filter = $this->prepareRule(
array(
'operation' => 'AND',
'children' => $this->getFilterArray()
),
$objChild
);

return $this->checkCondition($objParent, $filter);
}

Expand Down Expand Up @@ -449,4 +465,28 @@ public function neededProperties()

return $this->neededProperties;
}

/**
* Guard that the data provider names match.
*
* @param ModelInterface|null $child The child model.
* @param ModelInterface|null $parent The parent model.
*
* @return void
*
* @throws \InvalidArgumentException When any provider name mismatches.
*/
private function guardProviderNames($child, $parent = null)
{
if (null !== $child && $child->getProviderName() !== $this->destinationProvider) {
throw new \InvalidArgumentException(
sprintf('provider name %s is not equal to %s', $child->getProviderName(), $this->destinationProvider)
);
}
if (null !== $parent && $parent->getProviderName() !== $this->sourceProvider) {
throw new \InvalidArgumentException(
sprintf('provider name %s is not equal to %s', $parent->getProviderName(), $this->sourceProvider)
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace ContaoCommunityAlliance\DcGeneral\DataDefinition\ModelRelationship;

use ContaoCommunityAlliance\DcGeneral\Data\ModelInterface;
use ContaoCommunityAlliance\DcGeneral\Exception\DcGeneralRuntimeException;

/**
Expand Down Expand Up @@ -108,6 +109,8 @@ public function getSourceName()
*/
public function applyTo($objModel)
{
$this->guardProviderName($objModel);

if ($this->setOn) {
foreach ($this->setOn as $rule) {
if (!($rule['property'] && isset($rule['value']))) {
Expand Down Expand Up @@ -137,6 +140,12 @@ public function applyTo($objModel)
*/
public function matches($objModel)
{
try {
$this->guardProviderName($objModel);
} catch (\InvalidArgumentException $exception) {
return false;
}

if ($this->getFilterArray()) {
return $this->checkCondition(
$objModel,
Expand All @@ -149,4 +158,22 @@ public function matches($objModel)

return true;
}

/**
* Guard that the data provider name matches.
*
* @param ModelInterface $model The model.
*
* @return void
*
* @throws \InvalidArgumentException When any provider name mismatches.
*/
private function guardProviderName($model)
{
if ($model->getProviderName() !== $this->sourceProvider) {
throw new \InvalidArgumentException(
sprintf('provider name %s is not equal to %s', $model->getProviderName(), $this->getSourceName())
);
}
}
}
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-2015 Contao Community Alliance.
* (c) 2013-2016 Contao Community Alliance.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
Expand All @@ -12,7 +12,7 @@
*
* @package contao-community-alliance/dc-general
* @author Christian Schiffler <c.schiffler@cyberspectrum.de>
* @copyright 2013-2015 Contao Community Alliance.
* @copyright 2013-2016 Contao Community Alliance.
* @license https://github.com/contao-community-alliance/dc-general/blob/master/LICENSE LGPL-3.0
* @filesource
*/
Expand All @@ -23,8 +23,76 @@
use ContaoCommunityAlliance\DcGeneral\DataDefinition\ModelRelationship\ParentChildCondition;
use ContaoCommunityAlliance\DcGeneral\Test\TestCase;

/**
* This class tests the ParentChildCondition.
*/
class ParentChildConditionTest extends TestCase
{
/**
* Test that the matches method does not match for children from another provider.
*
* @return void
*/
public function testMatchesForChildFromOtherProvider()
{
$parent = new DefaultModel();
$parent->setId(1);
$parent->setProviderName('test-provider');

$child = new DefaultModel();
$child->setPropertyRaw('pid', 1);
$child->setProviderName('test2-provider');

$condition = new ParentChildCondition();
$condition
->setFilterArray(
[[
'local' => 'id',
'operation' => '=',
'remote' => 'pid'
]]
)
->setSourceName('test-provider')
->setDestinationName('test-provider');

$this->assertFalse($condition->matches($parent, $child));
}

/**
* Test that the matches method does not match for children from another provider.
*
* @return void
*/
public function testMatchesForParentFromOtherProvider()
{
$parent = new DefaultModel();
$parent->setId(1);
$parent->setProviderName('test2-provider');

$child = new DefaultModel();
$child->setPropertyRaw('pid', 1);
$child->setProviderName('test-provider');

$condition = new ParentChildCondition();
$condition
->setFilterArray(
[[
'local' => 'id',
'operation' => '=',
'remote' => 'pid'
]]
)
->setSourceName('test-provider')
->setDestinationName('test-provider');

$this->assertFalse($condition->matches($parent, $child));
}

/**
* Test the matches method().
*
* @return void
*/
public function testMatches()
{
$parent = new DefaultModel();
Expand All @@ -43,6 +111,11 @@ public function testMatches()
$this->assertTrue($condition->matches($parent, $child));
}

/**
* Test the matches method().
*
* @return void
*/
public function testMatchesRemoteValue()
{
$parent = new DefaultModel();
Expand Down
Loading

0 comments on commit 086638b

Please sign in to comment.