142 lines
5 KiB
PHP
142 lines
5 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This file is part of the PropelBundle package.
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*
|
|
* @license MIT License
|
|
*/
|
|
|
|
namespace Propel\Bundle\PropelBundle\Model\Acl;
|
|
|
|
use Propel\Bundle\PropelBundle\Model\Acl\Base\ObjectIdentity as BaseObjectIdentity;
|
|
use Propel\Bundle\PropelBundle\Model\Acl\Map\ObjectIdentityTableMap;
|
|
|
|
use Propel\Runtime\ActiveQuery\Criteria;
|
|
use Propel\Runtime\Connection\ConnectionInterface;
|
|
|
|
class ObjectIdentity extends BaseObjectIdentity
|
|
{
|
|
public function preInsert(ConnectionInterface $con = null)
|
|
{
|
|
// Compatibility with default implementation.
|
|
$ancestor = new ObjectIdentityAncestor();
|
|
$ancestor->setObjectIdentityRelatedByObjectIdentityId($this);
|
|
$ancestor->setObjectIdentityRelatedByAncestorId($this);
|
|
|
|
$this->addObjectIdentityAncestorRelatedByAncestorId($ancestor);
|
|
|
|
if ($this->getParentObjectIdentityId()) {
|
|
$this->updateAncestorsTree($con);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function preUpdate(ConnectionInterface $con = null)
|
|
{
|
|
if ($this->isColumnModified(ObjectIdentityTableMap::COL_PARENT_OBJECT_IDENTITY_ID)) {
|
|
$this->updateAncestorsTree($con);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function preDelete(ConnectionInterface $con = null)
|
|
{
|
|
// Only retrieve direct children, it's faster and grand children will be retrieved recursively.
|
|
$children = ObjectIdentityQuery::create()->findChildren($this, $con);
|
|
|
|
$objIds = $children->getPrimaryKeys(false);
|
|
$objIds[] = $this->getId();
|
|
|
|
$children->delete($con);
|
|
|
|
// Manually delete those for DBAdapter not capable of cascading the DELETE.
|
|
ObjectIdentityAncestorQuery::create()
|
|
->filterByObjectIdentityId($objIds, Criteria::IN)
|
|
->delete($con)
|
|
;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update all ancestor entries to reflect changes on this instance.
|
|
*
|
|
* @param ConnectionInterface $con
|
|
*
|
|
* @return \Propel\Bundle\PropelBundle\Model\Acl\ObjectIdentity $this
|
|
*/
|
|
protected function updateAncestorsTree(ConnectionInterface $con = null)
|
|
{
|
|
$con->beginTransaction();
|
|
|
|
$oldAncestors = ObjectIdentityQuery::create()->findAncestors($this, $con);
|
|
|
|
$children = ObjectIdentityQuery::create()->findGrandChildren($this, $con);
|
|
$children->append($this);
|
|
|
|
if (count($oldAncestors)) {
|
|
foreach ($children as $eachChild) {
|
|
/*
|
|
* Delete only those entries, that are ancestors based on the parent relation.
|
|
* Ancestors of grand children up to the current node will be kept.
|
|
*/
|
|
$query = ObjectIdentityAncestorQuery::create()
|
|
->filterByObjectIdentityId($eachChild->getId())
|
|
->filterByObjectIdentityRelatedByAncestorId($oldAncestors, Criteria::IN)
|
|
;
|
|
|
|
if ($eachChild->getId() !== $this->getId()) {
|
|
$query->filterByAncestorId(array($eachChild->getId(), $this->getId()), Criteria::NOT_IN);
|
|
} else {
|
|
$query->filterByAncestorId($this->getId(), Criteria::NOT_EQUAL);
|
|
}
|
|
|
|
$query->delete($con);
|
|
}
|
|
}
|
|
|
|
// This is the new parent object identity!
|
|
$parent = $this->getObjectIdentityRelatedByParentObjectIdentityId($con);
|
|
if (null !== $parent) {
|
|
$newAncestors = ObjectIdentityQuery::create()->findAncestors($parent, $con);
|
|
$newAncestors->append($parent);
|
|
foreach ($newAncestors as $eachAncestor) {
|
|
// This collection contains the current object identity!
|
|
foreach ($children as $eachChild) {
|
|
$ancestor = ObjectIdentityAncestorQuery::create()
|
|
->filterByObjectIdentityId($eachChild->getId())
|
|
->filterByAncestorId($eachAncestor->getId())
|
|
->findOneOrCreate($con)
|
|
;
|
|
|
|
// If the entry already exists, next please.
|
|
if (!$ancestor->isNew()) {
|
|
continue;
|
|
}
|
|
|
|
if ($eachChild->getId() === $this->getId()) {
|
|
// Do not save() here, as it would result in an infinite recursion loop!
|
|
$this->addObjectIdentityAncestorRelatedByObjectIdentityId($ancestor);
|
|
} else {
|
|
// Save the new ancestor to avoid integrity constraint violation.
|
|
$ancestor->save($con);
|
|
|
|
$eachChild
|
|
->addObjectIdentityAncestorRelatedByObjectIdentityId($ancestor)
|
|
->save($con)
|
|
;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$con->commit();
|
|
|
|
return $this;
|
|
}
|
|
}
|