mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Use new cached treeview nodes for twig inline generator (admin pages)
This commit is contained in:
parent
ad69c32832
commit
d9b15ddbb9
20 changed files with 277 additions and 214 deletions
|
@ -3,6 +3,8 @@ controllers:
|
|||
type: annotation
|
||||
|
||||
prefix: '{_locale}'
|
||||
defaults:
|
||||
_locale: '%kernel.default_locale%'
|
||||
requirements:
|
||||
# Match only locales like de_DE or de
|
||||
_locale: "^[a-z]{2}(_[A-Z]{2})?$"
|
||||
|
|
|
@ -29,8 +29,8 @@ use App\Entity\Parts\Storelocation;
|
|||
use App\Entity\Parts\Supplier;
|
||||
use App\Entity\UserSystem\U2FKey;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Services\ToolsTreeBuilder;
|
||||
use App\Services\TreeBuilder;
|
||||
use App\Services\Trees\ToolsTreeBuilder;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use App\Services\Trees\TreeViewGenerator;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
|
|
@ -40,7 +40,7 @@ use App\Services\Attachments\PartPreviewGenerator;
|
|||
use App\Services\EntityURLGenerator;
|
||||
use App\Services\FAIconGenerator;
|
||||
use App\Services\MarkdownParser;
|
||||
use App\Services\TreeBuilder;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use Doctrine\ORM\QueryBuilder;
|
||||
use Omines\DataTablesBundle\Adapter\Doctrine\ORM\SearchCriteriaProvider;
|
||||
use Omines\DataTablesBundle\Adapter\Doctrine\ORMAdapter;
|
||||
|
@ -65,7 +65,7 @@ class PartsDataTable implements DataTableTypeInterface
|
|||
protected $attachmentURLGenerator;
|
||||
|
||||
public function __construct(EntityURLGenerator $urlGenerator, TranslatorInterface $translator,
|
||||
TreeBuilder $treeBuilder, AmountFormatter $amountFormatter,
|
||||
NodesListBuilder $treeBuilder, AmountFormatter $amountFormatter,
|
||||
PartPreviewGenerator $previewGenerator, AttachmentURLGenerator $attachmentURLGenerator)
|
||||
{
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace App\Form\Type;
|
|||
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Entity\PriceInformations\Currency;
|
||||
use App\Services\TreeBuilder;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Intl\Currencies;
|
||||
use Symfony\Component\OptionsResolver\Options;
|
||||
|
@ -33,7 +33,7 @@ class CurrencyEntityType extends StructuralEntityType
|
|||
{
|
||||
protected $base_currency;
|
||||
|
||||
public function __construct(EntityManagerInterface $em, TreeBuilder $builder, $base_currency)
|
||||
public function __construct(EntityManagerInterface $em, NodesListBuilder $builder, $base_currency)
|
||||
{
|
||||
parent::__construct($em, $builder);
|
||||
$this->base_currency = $base_currency;
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace App\Form\Type;
|
|||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Repository\StructuralDBElementRepository;
|
||||
use App\Services\TreeBuilder;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
|
@ -47,10 +47,10 @@ class StructuralEntityType extends AbstractType
|
|||
{
|
||||
protected $em;
|
||||
protected $options;
|
||||
/** @var TreeBuilder */
|
||||
/** @var NodesListBuilder */
|
||||
protected $builder;
|
||||
|
||||
public function __construct(EntityManagerInterface $em, TreeBuilder $builder)
|
||||
public function __construct(EntityManagerInterface $em, NodesListBuilder $builder)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->builder = $builder;
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
namespace App\Helpers;
|
||||
namespace App\Helpers\Trees;
|
||||
|
||||
use App\Entity\Base\DBElement;
|
||||
use App\Entity\Base\NamedDBElement;
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Helpers\Trees\TreeViewNodeState;
|
||||
|
||||
/**
|
||||
* This class represents a node for the bootstrap treeview node.
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace App\Helpers\Trees;
|
||||
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
|
||||
class TreeViewNodeIterator extends \ArrayIterator implements \RecursiveIterator
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
namespace App\Helpers;
|
||||
namespace App\Helpers\Trees;
|
||||
|
||||
class TreeViewNodeState
|
||||
{
|
|
@ -24,7 +24,7 @@ namespace App\Repository;
|
|||
|
||||
use App\Entity\Base\NamedDBElement;
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace App\Repository;
|
|||
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Helpers\Trees\StructuralDBElementIterator;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Symfony\Component\Stopwatch\Stopwatch;
|
||||
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Entity\Base\DBElement;
|
||||
use App\Entity\Base\NamedDBElement;
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Repository\StructuralDBElementRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* This service gives you multiple possibilities to generate trees.
|
||||
*/
|
||||
class TreeBuilder
|
||||
{
|
||||
protected $url_generator;
|
||||
protected $em;
|
||||
protected $translator;
|
||||
protected $cache;
|
||||
protected $keyGenerator;
|
||||
|
||||
public function __construct(EntityURLGenerator $URLGenerator, EntityManagerInterface $em,
|
||||
TranslatorInterface $translator, TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator)
|
||||
{
|
||||
$this->url_generator = $URLGenerator;
|
||||
$this->em = $em;
|
||||
$this->translator = $translator;
|
||||
$this->keyGenerator = $keyGenerator;
|
||||
$this->cache = $treeCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a tree for the given Element. The given element is the top node, all children are child nodes.
|
||||
*
|
||||
* @param StructuralDBElement $element The element for which the tree should be generated.
|
||||
* @param string $href_type The type of the links that should be used for the links. Set to null, to disable links.
|
||||
* See EntityURLGenerator::getURL for possible types.
|
||||
* @param DBElement|null $selectedElement When a element is given here, its tree node will be marked as selected in
|
||||
* the resulting tree. When $selectedElement is not existing in the tree, then nothing happens.
|
||||
*
|
||||
* @return TreeViewNode The Node for the given Element.
|
||||
*
|
||||
* @throws \App\Exceptions\EntityNotSupportedException
|
||||
*/
|
||||
public function elementToTreeNode(NamedDBElement $element, ?string $href_type = 'list_parts', DBElement $selectedElement = null): TreeViewNode
|
||||
{
|
||||
$children_nodes = null;
|
||||
|
||||
if ($element instanceof StructuralDBElement) {
|
||||
$children = $element->getSubelements();
|
||||
foreach ($children as $child) {
|
||||
$children_nodes[] = $this->elementToTreeNode($child, $href_type, $selectedElement);
|
||||
}
|
||||
}
|
||||
|
||||
//Check if we need to generate a href type
|
||||
$href = null;
|
||||
|
||||
if (!empty($href_type)) {
|
||||
$href = $this->url_generator->getURL($element, $href_type);
|
||||
}
|
||||
|
||||
$tree_node = new TreeViewNode($element->__toString(), $href, $children_nodes);
|
||||
|
||||
if (null != $children_nodes) {
|
||||
$tree_node->addTag((string) \count($children_nodes));
|
||||
}
|
||||
|
||||
//Check if we need to select the current part
|
||||
if (null !== $selectedElement && $element->getID() === $selectedElement->getID()) {
|
||||
$tree_node->setSelected(true);
|
||||
}
|
||||
|
||||
return $tree_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a tree for all elements of the given type.
|
||||
*
|
||||
* @param StructuralDBElement $class_name The class name of the StructuralDBElement class for which the tree should
|
||||
* be generated.
|
||||
* @param string $href_type The type of the links that should be used for the links. Set to null, to disable links.
|
||||
* See EntityURLGenerator::getURL for possible types.
|
||||
* @param DBElement|null $selectedElement When a element is given here, its tree node will be marked as selected in
|
||||
* the resulting tree. When $selectedElement is not existing in the tree, then nothing happens.
|
||||
*
|
||||
* @return TreeViewNode[] Returns an array, containing all nodes. It is empty if the given class has no elements.
|
||||
*
|
||||
* @throws \App\Exceptions\EntityNotSupportedException
|
||||
*/
|
||||
public function typeToTree(string $class_name, ?string $href_type = 'list_parts', DBElement $selectedElement = null): array
|
||||
{
|
||||
/**
|
||||
* @var StructuralDBElementRepository
|
||||
*/
|
||||
$repo = $this->em->getRepository($class_name);
|
||||
|
||||
if (new $class_name() instanceof StructuralDBElement) {
|
||||
$root_nodes = $repo->findRootNodes();
|
||||
} else {
|
||||
$root_nodes = $repo->findAll();
|
||||
}
|
||||
|
||||
$array = [];
|
||||
|
||||
//When we use the newEdit type, add the New Element node.
|
||||
if ('newEdit' === $href_type) {
|
||||
//Generate the url for the new node
|
||||
$href = $this->url_generator->createURL(new $class_name());
|
||||
$new_node = new TreeViewNode($this->translator->trans('entity.tree.new'), $href);
|
||||
//When the id of the selected element is null, then we have a new element, and we need to select "new" node
|
||||
if (null != $selectedElement && null == $selectedElement->getID()) {
|
||||
$new_node->setSelected(true);
|
||||
}
|
||||
$array[] = $new_node;
|
||||
//Add spacing
|
||||
$array[] = (new TreeViewNode(''))->setDisabled(true);
|
||||
|
||||
//Every other treeNode will be used for edit
|
||||
$href_type = 'edit';
|
||||
}
|
||||
|
||||
foreach ($root_nodes as $node) {
|
||||
$array[] = $this->elementToTreeNode($node, $href_type, $selectedElement);
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a flattened hierachical tree. Useful for generating option lists.
|
||||
* In difference to the Repository Function, the results here are cached.
|
||||
*
|
||||
* @param string $class_name The class name of the entity you want to retrieve.
|
||||
* @param StructuralDBElement|null $parent This entity will be used as root element. Set to null, to use global root
|
||||
*
|
||||
* @return StructuralDBElement[] A flattened list containing the tree elements.
|
||||
*/
|
||||
public function typeToNodesList(string $class_name, ?StructuralDBElement $parent = null): array
|
||||
{
|
||||
$parent_id = null != $parent ? $parent->getID() : '0';
|
||||
// Backslashes are not allowed in cache keys
|
||||
$secure_class_name = str_replace('\\', '_', $class_name);
|
||||
$key = 'list_'.$this->keyGenerator->generateKey().'_'.$secure_class_name.$parent_id;
|
||||
|
||||
$ret = $this->cache->get($key, function (ItemInterface $item) use ($class_name, $parent, $secure_class_name) {
|
||||
// Invalidate when groups, a element with the class or the user changes
|
||||
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
|
||||
/**
|
||||
* @var StructuralDBElementRepository
|
||||
*/
|
||||
$repo = $this->em->getRepository($class_name);
|
||||
|
||||
return $repo->toNodesList($parent);
|
||||
});
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
81
src/Services/Trees/NodesListBuilder.php
Normal file
81
src/Services/Trees/NodesListBuilder.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
namespace App\Services\Trees;
|
||||
|
||||
use App\Entity\Base\DBElement;
|
||||
use App\Entity\Base\NamedDBElement;
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use App\Repository\StructuralDBElementRepository;
|
||||
use App\Services\EntityURLGenerator;
|
||||
use App\Services\UserCacheKeyGenerator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
/**
|
||||
* This service gives you a flat list containing all structured entities in the order of the structure.
|
||||
*/
|
||||
class NodesListBuilder
|
||||
{
|
||||
protected $em;
|
||||
protected $cache;
|
||||
protected $keyGenerator;
|
||||
|
||||
public function __construct( EntityManagerInterface $em, TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator)
|
||||
{
|
||||
$this->em = $em;
|
||||
$this->keyGenerator = $keyGenerator;
|
||||
$this->cache = $treeCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a flattened hierachical tree. Useful for generating option lists.
|
||||
* In difference to the Repository Function, the results here are cached.
|
||||
*
|
||||
* @param string $class_name The class name of the entity you want to retrieve.
|
||||
* @param StructuralDBElement|null $parent This entity will be used as root element. Set to null, to use global root
|
||||
*
|
||||
* @return StructuralDBElement[] A flattened list containing the tree elements.
|
||||
*/
|
||||
public function typeToNodesList(string $class_name, ?StructuralDBElement $parent = null): array
|
||||
{
|
||||
$parent_id = null != $parent ? $parent->getID() : '0';
|
||||
// Backslashes are not allowed in cache keys
|
||||
$secure_class_name = str_replace('\\', '_', $class_name);
|
||||
$key = 'list_'.$this->keyGenerator->generateKey().'_'.$secure_class_name.$parent_id;
|
||||
|
||||
$ret = $this->cache->get($key, function (ItemInterface $item) use ($class_name, $parent, $secure_class_name) {
|
||||
// Invalidate when groups, a element with the class or the user changes
|
||||
$item->tag(['groups', 'tree_list', $this->keyGenerator->generateKey(), $secure_class_name]);
|
||||
/**
|
||||
* @var StructuralDBElementRepository
|
||||
*/
|
||||
$repo = $this->em->getRepository($class_name);
|
||||
|
||||
return $repo->toNodesList($parent);
|
||||
});
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
namespace App\Services;
|
||||
namespace App\Services\Trees;
|
||||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\Attachments\PartAttachment;
|
||||
|
@ -34,7 +34,8 @@ use App\Entity\Parts\Supplier;
|
|||
use App\Entity\PriceInformations\Currency;
|
||||
use App\Entity\UserSystem\Group;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use App\Services\UserCacheKeyGenerator;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
|
@ -23,15 +23,17 @@ namespace App\Services\Trees;
|
|||
|
||||
|
||||
use App\Entity\Base\DBElement;
|
||||
use App\Entity\Base\NamedDBElement;
|
||||
use App\Entity\Base\StructuralDBElement;
|
||||
use App\Helpers\Trees\TreeViewNodeIterator;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use App\Repository\StructuralDBElementRepository;
|
||||
use App\Services\EntityURLGenerator;
|
||||
use App\Services\UserCacheKeyGenerator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Contracts\Cache\ItemInterface;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class TreeViewGenerator
|
||||
{
|
||||
|
@ -40,21 +42,51 @@ class TreeViewGenerator
|
|||
protected $em;
|
||||
protected $cache;
|
||||
protected $keyGenerator;
|
||||
protected $translator;
|
||||
|
||||
public function __construct(EntityURLGenerator $URLGenerator, EntityManagerInterface $em,
|
||||
TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator)
|
||||
TagAwareCacheInterface $treeCache, UserCacheKeyGenerator $keyGenerator, TranslatorInterface $translator)
|
||||
{
|
||||
$this->urlGenerator = $URLGenerator;
|
||||
$this->em = $em;
|
||||
$this->cache = $treeCache;
|
||||
$this->keyGenerator = $keyGenerator;
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
public function getTreeView(string $class, ?StructuralDBElement $parent = null, string $href_type = 'list_parts', DBElement $selectedElement = null)
|
||||
/**
|
||||
* Gets a TreeView list for the entities of the given class.
|
||||
* @param string $class The class for which the treeView should be generated
|
||||
* @param StructuralDBElement|null $parent The root nodes in the tree should have this element as parent (use null, if you want to get all entities)
|
||||
* @param string $href_type The link type that will be generated for the hyperlink section of each node (see EntityURLGenerator for possible values).
|
||||
* Set to empty string, to disable href field.
|
||||
* @param DBElement|null $selectedElement The element that should be selected. If set to null, no element will be selected.
|
||||
* @return TreeViewNode[] An array of TreeViewNode[] elements of the root elements.
|
||||
*/
|
||||
public function getTreeView(string $class, ?StructuralDBElement $parent = null, string $href_type = 'list_parts', DBElement $selectedElement = null) : array
|
||||
{
|
||||
$head = [];
|
||||
|
||||
//When we use the newEdit type, add the New Element node.
|
||||
if ('newEdit' === $href_type) {
|
||||
//Generate the url for the new node
|
||||
$href = $this->urlGenerator->createURL(new $class());
|
||||
$new_node = new TreeViewNode($this->translator->trans('entity.tree.new'), $href);
|
||||
//When the id of the selected element is null, then we have a new element, and we need to select "new" node
|
||||
if (null == $selectedElement || null == $selectedElement->getID()) {
|
||||
$new_node->setSelected(true);
|
||||
}
|
||||
$head[] = $new_node;
|
||||
//Add spacing
|
||||
$head[] = (new TreeViewNode(''))->setDisabled(true);
|
||||
|
||||
//Every other treeNode will be used for edit
|
||||
$href_type = 'edit';
|
||||
}
|
||||
|
||||
$generic = $this->getGenericTree($class, $parent);
|
||||
$treeIterator = new TreeViewNodeIterator($generic);
|
||||
$recursiveIterator = new \RecursiveIteratorIterator($treeIterator);
|
||||
$recursiveIterator = new \RecursiveIteratorIterator($treeIterator, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
foreach ($recursiveIterator as $item) {
|
||||
/** @var $item TreeViewNode */
|
||||
if ($selectedElement !== null && $item->getId() === $selectedElement->getID()) {
|
||||
|
@ -71,7 +103,7 @@ class TreeViewGenerator
|
|||
}
|
||||
}
|
||||
|
||||
return $generic;
|
||||
return array_merge($head, $generic);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -85,11 +117,11 @@ class TreeViewGenerator
|
|||
*/
|
||||
public function getGenericTree(string $class, ?StructuralDBElement $parent = null) : array
|
||||
{
|
||||
if(!is_a($class, StructuralDBElement::class, true)) {
|
||||
throw new \InvalidArgumentException('$class must be a class string that implements StructuralDBElement!');
|
||||
if(!is_a($class, NamedDBElement::class, true)) {
|
||||
throw new \InvalidArgumentException('$class must be a class string that implements StructuralDBElement or NamedDBElement!');
|
||||
}
|
||||
if($parent !== null && !is_a($parent, $class)) {
|
||||
throw new \InvalidArgumentException('$parent must be of the type class!');
|
||||
throw new \InvalidArgumentException('$parent must be of the type $class!');
|
||||
}
|
||||
|
||||
/** @var StructuralDBElementRepository $repo */
|
||||
|
|
|
@ -31,7 +31,8 @@ use App\Services\FAIconGenerator;
|
|||
use App\Services\MarkdownParser;
|
||||
use App\Services\MoneyFormatter;
|
||||
use App\Services\SIFormatter;
|
||||
use App\Services\TreeBuilder;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use App\Services\Trees\TreeViewGenerator;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
|
@ -53,7 +54,7 @@ class AppExtension extends AbstractExtension
|
|||
protected $translator;
|
||||
|
||||
public function __construct(EntityURLGenerator $entityURLGenerator, MarkdownParser $markdownParser,
|
||||
SerializerInterface $serializer, TreeBuilder $treeBuilder,
|
||||
SerializerInterface $serializer, TreeViewGenerator $treeBuilder,
|
||||
MoneyFormatter $moneyFormatter,
|
||||
SIFormatter $SIFormatter, AmountFormatter $amountFormatter,
|
||||
AttachmentURLGenerator $attachmentURLGenerator,
|
||||
|
@ -103,7 +104,7 @@ class AppExtension extends AbstractExtension
|
|||
|
||||
public function treeData(DBElement $element, string $type = 'newEdit'): string
|
||||
{
|
||||
$tree = $this->treeBuilder->typeToTree(\get_class($element), $type, $element);
|
||||
$tree = $this->treeBuilder->getTreeView(\get_class($element), null, $type, $element);
|
||||
|
||||
return $this->serializer->serialize($tree, 'json', ['skip_null_values' => true]);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace App\Tests\Helpers;
|
||||
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TreeViewNodeTest extends TestCase
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace App\Tests\Repository;
|
|||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Entity\UserSystem\User;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use App\Repository\NamedDBElementRepository;
|
||||
use App\Repository\StructuralDBElementRepository;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
namespace App\Tests\Repository;
|
||||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use App\Repository\StructuralDBElementRepository;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
|
80
tests/Services/Trees/NodesListBuilderTest.php
Normal file
80
tests/Services/Trees/NodesListBuilderTest.php
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
namespace App\Tests\Services\Trees;
|
||||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Services\Trees\NodesListBuilder;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
/**
|
||||
* @Group DB
|
||||
* @package App\Tests\Services\Trees
|
||||
*/
|
||||
class NodesListBuilderTest extends WebTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* @var NodesListBuilder $service
|
||||
*/
|
||||
protected $service;
|
||||
protected $em;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
self::bootKernel();
|
||||
$this->service = self::$container->get(NodesListBuilder::class);
|
||||
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test $repo->toNodesList() for null as parameter
|
||||
*/
|
||||
public function testTypeToNodesListtRoot() : void
|
||||
{
|
||||
//List all root nodes and their children
|
||||
$nodes = $this->service->typeToNodesList(AttachmentType::class);
|
||||
|
||||
$this->assertCount(7, $nodes);
|
||||
$this->assertContainsOnlyInstancesOf(AttachmentType::class, $nodes);
|
||||
$this->assertEquals('Node 1', $nodes[0]->getName());
|
||||
$this->assertEquals('Node 1.1', $nodes[1]->getName());
|
||||
$this->assertEquals('Node 1.1.1', $nodes[2]->getName());
|
||||
$this->assertEquals('Node 1.2', $nodes[3]->getName());
|
||||
$this->assertEquals('Node 2', $nodes[4]->getName());
|
||||
$this->assertEquals('Node 2.1', $nodes[5]->getName());
|
||||
$this->assertEquals('Node 3', $nodes[6]->getName());
|
||||
}
|
||||
|
||||
public function testTypeToNodesListElement() : void
|
||||
{
|
||||
//List all nodes that are children to Node 1
|
||||
$node1 = $this->em->find(AttachmentType::class, 1);
|
||||
$nodes = $this->service->typeToNodesList(AttachmentType::class, $node1);
|
||||
|
||||
$this->assertCount(3, $nodes);
|
||||
$this->assertContainsOnlyInstancesOf(AttachmentType::class, $nodes);
|
||||
$this->assertEquals('Node 1.1', $nodes[0]->getName());
|
||||
$this->assertEquals('Node 1.1.1', $nodes[1]->getName());
|
||||
$this->assertEquals('Node 1.2', $nodes[2]->getName());
|
||||
}
|
||||
}
|
|
@ -22,21 +22,24 @@
|
|||
namespace App\Tests\Services\Trees;
|
||||
|
||||
use App\Entity\Attachments\AttachmentType;
|
||||
use App\Helpers\TreeViewNode;
|
||||
use App\Entity\Parts\Category;
|
||||
use App\Helpers\Trees\TreeViewNode;
|
||||
use App\Services\AmountFormatter;
|
||||
use App\Services\Trees\TreeViewGenerator;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||
|
||||
/**
|
||||
* @group DB
|
||||
*/
|
||||
class TreeGeneratorTest extends WebTestCase
|
||||
class TreeViewGeneratorTest extends WebTestCase
|
||||
{
|
||||
/**
|
||||
* @var TreeViewGenerator
|
||||
*/
|
||||
protected $service;
|
||||
protected $em;
|
||||
|
||||
public function setUp() : void
|
||||
{
|
||||
|
@ -45,6 +48,7 @@ class TreeGeneratorTest extends WebTestCase
|
|||
//Get an service instance.
|
||||
self::bootKernel();
|
||||
$this->service = self::$container->get(TreeViewGenerator::class);
|
||||
$this->em = self::$container->get(EntityManagerInterface::class);
|
||||
}
|
||||
|
||||
public function testGetGenericTree()
|
||||
|
@ -71,6 +75,49 @@ class TreeGeneratorTest extends WebTestCase
|
|||
$this->assertEquals(1, $tree[0]->getId());
|
||||
$this->assertEquals(2, $tree[1]->getId());
|
||||
$this->assertEquals(7, $tree[0]->getNodes()[0]->getNodes()[0]->getId());
|
||||
}
|
||||
|
||||
public function testGetTreeViewBasic()
|
||||
{
|
||||
$tree = $this->service->getTreeView(Category::class);
|
||||
$this->assertIsArray($tree);
|
||||
$this->assertContainsOnlyInstancesOf(TreeViewNode::class, $tree);
|
||||
|
||||
$this->assertCount(3, $tree);
|
||||
$this->assertCount(2, $tree[0]->getNodes());
|
||||
$this->assertCount(1, $tree[0]->getNodes()[0]->getNodes());
|
||||
|
||||
//Assert that the nodes contain the correct links
|
||||
$this->assertEquals('/en/category/1/parts', $tree[0]->getHref());
|
||||
$this->assertEquals('/en/category/2/parts', $tree[1]->getHref());
|
||||
$this->assertEquals('/en/category/7/parts', $tree[0]->getNodes()[0]->getNodes()[0]->getHref());
|
||||
}
|
||||
|
||||
public function testGetTreeViewNewEdit()
|
||||
{
|
||||
$tree = $this->service->getTreeView(Category::class, null, 'newEdit');
|
||||
|
||||
//First element should link to new category
|
||||
$this->assertStringContainsStringIgnoringCase('New', $tree[0]->getText());
|
||||
$this->assertEquals('/en/category/new', $tree[0]->getHref());
|
||||
//By default the new element node is selected
|
||||
$this->assertTrue($tree[0]->getState()->getSelected());
|
||||
|
||||
//Next element is spacing
|
||||
$this->assertEquals('', $tree[1]->getText());
|
||||
$this->assertTrue($tree[1]->getState()->getDisabled());
|
||||
|
||||
//All other elements should be normal
|
||||
$this->assertCount(5, $tree);
|
||||
}
|
||||
|
||||
public function testGetTreeViewSelectedNode()
|
||||
{
|
||||
$selected = $this->em->find(Category::class, 2);
|
||||
$tree = $this->service->getTreeView(Category::class, null, 'edit', $selected);
|
||||
|
||||
$this->assertNull($tree[0]->getState());
|
||||
//Only second element must be selected
|
||||
$this->assertTrue($tree[1]->getState()->getSelected());
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue