Skip to content

Instantly share code, notes, and snippets.

@harentius
Last active April 19, 2017 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harentius/d70af4a470cee0cec1bb36db966b0d9a to your computer and use it in GitHub Desktop.
Save harentius/d70af4a470cee0cec1bb36db966b0d9a to your computer and use it in GitHub Desktop.
<?php
namespace Vendor\Bundle\SomeBundle\Command;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class NestedSetRefreshCommand extends ContainerAwareCommand
{
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setName('vendor:nested-set:refresh')
->addArgument('entity', InputArgument::REQUIRED)
;
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @throws \Exception
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$container = $this->getContainer();
/** @var EntityManagerInterface $em */
$em = $container->get('doctrine.orm.entity_manager');
$repository = $em->getRepository($input->getArgument('entity'));
$refreshLeftAndRight = function($root, $left) use ($repository, &$refreshLeftAndRight) {
$right = $left + 1;
$children = $repository->findBy([
'parent' => $root,
]);
foreach ($children as $entity) {
// recursive execution of this function for each
// child of this node
// $right is the current right value, which is
// incremented by the refreshLeftAndRight function
$right = $refreshLeftAndRight($entity, $right);
}
// we've got the left value, and now that we've processed
// the children of this node we also know the right value
$this->updateValue($left, $root, 'left');
$this->updateValue($right, $root, 'right');
return $right + 1;
};
foreach ($repository->findBy(['parent' => null]) as $rootEntry) {
$refreshLeftAndRight($rootEntry, 1);
}
$em->flush();
foreach ($repository->findAll() as $entity) {
$level = 0;
$parent = $entity;
/** @noinspection PhpUndefinedMethodInspection */
while ($parent = $parent->getParent()) {
$level++;
}
$this->updateValue($level, $entity, 'level');
}
$em->flush();
}
/**
* @param mixed $value
* @param object $entity
* @param string $property
*/
private function updateValue($value, $entity, $property)
{
$reflection = new \ReflectionProperty(get_class($entity), $property);
$reflection->setAccessible(true);
$reflection->setValue($entity, $value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment