partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

FixTreeCommand.php (4215B)


      1 <?php
      2 
      3 namespace PartKeepr\CoreBundle\Command;
      4 
      5 use Doctrine\ORM\EntityManager;
      6 use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
      7 use Symfony\Component\Console\Input\InputInterface;
      8 use Symfony\Component\Console\Output\OutputInterface;
      9 
     10 class FixTreeCommand extends ContainerAwareCommand
     11 {
     12     /**
     13      * @var EntityManager
     14      */
     15     private $entityManager;
     16 
     17     public function configure()
     18     {
     19         parent::configure();
     20         $this->setName('partkeepr:fix-category-trees');
     21         $this->setDescription('Fixes the category trees');
     22     }
     23 
     24     public function execute(InputInterface $input, OutputInterface $output)
     25     {
     26         $this->entityManager = $this->getContainer()->get("doctrine.orm.default_entity_manager");
     27         $this->fixTree('PartCategory');
     28         $this->fixTree('FootprintCategory');
     29         $this->fixTree('StorageLocationCategory');
     30     }
     31 
     32     /**
     33      * Fixes the tree for a given table due to the migration of doctrine2-nestedset to DoctrineExtensions.
     34      *
     35      * @param string $table The table name to fix
     36      *
     37      * @throws \Doctrine\DBAL\DBALException
     38      */
     39     public function fixTree($table)
     40     {
     41         $nodes = $this->getNodeIds($table);
     42 
     43         $queryBuilder = $this->entityManager->getConnection()->createQueryBuilder();
     44         $queryBuilder->update($table)
     45             ->set('parent_id', ':parent')
     46             ->set('root', ':root')
     47             ->set('lvl', ':level')
     48             ->where('id = :id');
     49 
     50         foreach ($nodes as $node) {
     51             $parent = $this->fetchParent($table, $node['id']);
     52             $level = $this->getLevel($table, $node['id']);
     53 
     54             if ($parent !== false) {
     55                 $this->entityManager->getConnection()->executeUpdate(
     56                     $queryBuilder->getSQL(),
     57                     [
     58                         ':parent' => $parent,
     59                         ':id'     => $node['id'],
     60                         ':level'  => $level,
     61                         ':root'   => 1,
     62                     ]
     63                 );
     64             } else {
     65                 $this->entityManager->getConnection()->executeUpdate(
     66                     $queryBuilder->getSQL(),
     67                     [
     68                         ':parent' => null,
     69                         ':id'     => $node['id'],
     70                         ':root'   => 1,
     71                         ':level'  => 0,
     72                     ]
     73                 );
     74             }
     75         }
     76     }
     77 
     78     /**
     79      * Fetches the parent node for a table and ID.
     80      *
     81      * @param $table
     82      * @param $id
     83      *
     84      * @return mixed
     85      */
     86     public function fetchParent($table, $id)
     87     {
     88         $queryBuilder = $this->entityManager->getConnection()->createQueryBuilder();
     89 
     90         $queryBuilder->select('parent.id')
     91             ->from($table, 'node')
     92             ->from($table, 'parent')
     93             ->where('parent.lft < node.lft')
     94             ->andWhere('parent.rgt > node.rgt')
     95             ->andWhere('node.id = :nodeid')
     96             ->orderBy('parent.rgt - parent.lft')
     97             ->setMaxResults(1);
     98 
     99         return $this->entityManager->getConnection()->fetchColumn($queryBuilder->getSQL(), [':nodeid' => $id], 0);
    100     }
    101 
    102     /**
    103      * Returns the node IDs for the table.
    104      *
    105      * @param $table
    106      *
    107      * @return array
    108      */
    109     public function getNodeIds($table)
    110     {
    111         $qb = $this->entityManager->getConnection()->createQueryBuilder();
    112 
    113         $qb->select('id')
    114             ->from($table)
    115             ->orderBy('id', 'ASC');
    116 
    117         return $this->entityManager->getConnection()->fetchAll($qb->getSQL());
    118     }
    119 
    120     /**
    121      * Returns the level for a given table and ID.
    122      *
    123      * @param $table
    124      * @param $id
    125      *
    126      * @return mixed
    127      */
    128     public function getLevel($table, $id)
    129     {
    130         $qb = $this->entityManager->getConnection()->createQueryBuilder();
    131 
    132         $qb->select('COUNT(*) AS level')
    133             ->from($table, 'node')
    134             ->from($table, 'parent')
    135             ->where('node.lft > parent.lft')
    136             ->andWhere('node.lft < parent.rgt')
    137             ->andWhere('node.id = :nodeid');
    138 
    139         return $this->entityManager->getConnection()->fetchAssoc($qb->getSQL(), [':nodeid' => $id])['level'];
    140     }
    141 }