Passed
Push — master ( 9668d1...ad69c3 )
by Jan
04:30
created

TreeViewGenerator   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 34
dl 0
loc 77
rs 10
c 1
b 0
f 0
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getTreeView() 0 22 6
A getGenericTree() 0 27 5
A __construct() 0 7 1
1
<?php
2
/**
3
 * This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
4
 *
5
 * Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
6
 *
7
 * This program is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU General Public License
9
 * as published by the Free Software Foundation; either version 2
10
 * of the License, or (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
20
 */
21
22
namespace App\Services\Trees;
23
24
25
use App\Entity\Base\DBElement;
26
use App\Entity\Base\StructuralDBElement;
27
use App\Helpers\Trees\TreeViewNodeIterator;
28
use App\Helpers\TreeViewNode;
29
use App\Repository\StructuralDBElementRepository;
30
use App\Services\EntityURLGenerator;
31
use App\Services\UserCacheKeyGenerator;
32
use Doctrine\ORM\EntityManagerInterface;
33
use Symfony\Contracts\Cache\ItemInterface;
34
use Symfony\Contracts\Cache\TagAwareCacheInterface;
35
36
class TreeViewGenerator
37
{
38
39
    protected $urlGenerator;
40
    protected $em;
41
    protected $cache;
42
    protected $keyGenerator;
43
44
    public function __construct(EntityURLGenerator $URLGenerator, EntityManagerInterface $em,
45
        TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator)
46
    {
47
        $this->urlGenerator = $URLGenerator;
48
        $this->em = $em;
49
        $this->cache = $treeCache;
50
        $this->keyGenerator = $keyGenerator;
51
    }
52
53
    public function getTreeView(string $class, ?StructuralDBElement $parent = null, string $href_type = 'list_parts', DBElement $selectedElement = null)
54
    {
55
        $generic = $this->getGenericTree($class, $parent);
56
        $treeIterator = new TreeViewNodeIterator($generic);
57
        $recursiveIterator = new \RecursiveIteratorIterator($treeIterator);
58
        foreach ($recursiveIterator as $item) {
59
            /** @var $item TreeViewNode */
60
            if ($selectedElement !== null && $item->getId() === $selectedElement->getID()) {
61
               $item->setSelected(true);
62
            }
63
64
            if (!empty($item->getNodes())) {
65
                $item->addTag((string) \count($item->getNodes()));
66
            }
67
68
            if (!empty($href_type)) {
69
                $entity = $this->em->getPartialReference($class, $item->getId());
70
                $item->setHref($this->urlGenerator->getURL($entity, $href_type));
71
            }
72
        }
73
74
        return $generic;
75
    }
76
77
    /**
78
     * /**
79
     * Gets a tree of TreeViewNode elements. The root elements has $parent as parent.
80
     * The treeview is generic, that means the href are null and ID values are set.
81
     *
82
     * @param  string  $class The class for which the tree should be generated
83
     * @param  StructuralDBElement|null  $parent The parent the root elements should have.
84
     * @return TreeViewNode[]
85
     */
86
    public function getGenericTree(string $class, ?StructuralDBElement $parent = null) : array
87
    {
88
        if(!is_a($class, StructuralDBElement::class, true)) {
89
            throw new \InvalidArgumentException('$class must be a class string that implements StructuralDBElement!');
90
        }
91
        if($parent !== null && !is_a($parent, $class)) {
92
            throw new \InvalidArgumentException('$parent must be of the type class!');
93
        }
94
95
        /** @var StructuralDBElementRepository $repo */
96
        $repo = $this->em->getRepository($class);
97
98
        //If we just want a part of a tree, dont cache it
99
        if ($parent !== null) {
100
           return $repo->getGenericNodeTree($parent);
101
        }
102
103
        $secure_class_name = str_replace('\\', '_', $class);
104
        $key = 'treeview_'.$this->keyGenerator->generateKey().'_'.$secure_class_name;
105
106
        $ret = $this->cache->get($key, function (ItemInterface $item) use ($repo, $parent, $secure_class_name) {
107
            // Invalidate when groups, a element with the class or the user changes
108
            $item->tag(['groups', 'tree_treeview', $this->keyGenerator->generateKey(), $secure_class_name]);
109
            return $repo->getGenericNodeTree($parent);
110
        });
111
112
        return $ret;
113
    }
114
}