No flags found
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
3f6b083
... +249 ...
92cea37
Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.
e.g., #unittest #integration
#production #enterprise
#frontend #backend
13 | 13 | ||
14 | 14 | namespace Sonata\ClassificationBundle\Admin\Filter; |
|
15 | 15 | ||
16 | - | use Sonata\AdminBundle\Datagrid\ProxyQueryInterface as BaseProxyQueryInterface; |
|
16 | + | use Sonata\AdminBundle\Filter\Model\FilterData; |
|
17 | 17 | use Sonata\AdminBundle\Form\Type\Filter\DefaultType; |
|
18 | 18 | use Sonata\ClassificationBundle\Model\CategoryInterface; |
|
19 | 19 | use Sonata\ClassificationBundle\Model\CategoryManagerInterface; |
23 | 23 | ||
24 | 24 | final class CategoryFilter extends Filter |
|
25 | 25 | { |
|
26 | - | /** |
|
27 | - | * @var CategoryManagerInterface |
|
28 | - | */ |
|
29 | - | private $categoryManager; |
|
26 | + | private CategoryManagerInterface $categoryManager; |
|
30 | 27 | ||
31 | 28 | public function __construct(CategoryManagerInterface $categoryManager) |
|
32 | 29 | { |
|
33 | 30 | $this->categoryManager = $categoryManager; |
|
34 | 31 | } |
|
35 | 32 | ||
36 | - | public function filter(BaseProxyQueryInterface $proxyQuery, $alias, $field, $data): void |
|
33 | + | public function filter(ProxyQueryInterface $query, string $alias, string $field, FilterData $data): void |
|
37 | 34 | { |
|
38 | - | // NEXT_MAJOR: Remove the call to `assert()` and use this class as argument type declaration. |
|
39 | - | \assert($proxyQuery instanceof ProxyQueryInterface); |
|
40 | - | ||
41 | - | if (null === $data || !\is_array($data) || !\array_key_exists('value', $data)) { |
|
35 | + | if (!$data->hasValue() || null === $data->getValue()) { |
|
42 | 36 | return; |
|
43 | 37 | } |
|
44 | 38 | ||
45 | - | if (null !== $data['value']) { |
|
46 | - | $proxyQuery |
|
47 | - | ->getQueryBuilder() |
|
48 | - | ->andWhere(sprintf('%s.%s = :category', $alias, $field)) |
|
49 | - | ->setParameter('category', $data['value']); |
|
50 | - | } |
|
39 | + | $query |
|
40 | + | ->getQueryBuilder() |
|
41 | + | ->andWhere(sprintf('%s.%s = :category', $alias, $field)) |
|
42 | + | ->setParameter('category', $data->getValue()); |
|
51 | 43 | ||
52 | - | $this->active = null !== $data['value']; |
|
44 | + | $this->setActive(true); |
|
53 | 45 | } |
|
54 | 46 | ||
55 | 47 | public function getDefaultOptions(): array |
|
56 | 48 | { |
|
57 | 49 | return [ |
|
58 | 50 | 'context' => null, |
|
51 | + | 'field_type' => ChoiceType::class, |
|
59 | 52 | ]; |
|
60 | 53 | } |
|
61 | 54 | ||
62 | - | public function getFieldType(): string |
|
63 | - | { |
|
64 | - | return $this->getOption('field_type', ChoiceType::class); |
|
65 | - | } |
|
66 | - | ||
67 | - | public function getFieldOptions(): array |
|
68 | - | { |
|
69 | - | return $this->getOption('choices', [ |
|
70 | - | 'choices' => $this->getChoices(), |
|
71 | - | 'choice_translation_domain' => false, |
|
72 | - | ]); |
|
73 | - | } |
|
74 | - | ||
75 | 55 | public function getRenderSettings(): array |
|
76 | 56 | { |
|
77 | 57 | return [DefaultType::class, [ |
|
78 | 58 | 'field_type' => $this->getFieldType(), |
|
79 | - | 'field_options' => $this->getFieldOptions(), |
|
59 | + | 'field_options' => $this->getOption('choices', [ |
|
60 | + | 'choices' => $this->getChoices(), |
|
61 | + | 'choice_translation_domain' => false, |
|
62 | + | ]), |
|
80 | 63 | 'label' => $this->getLabel(), |
|
81 | 64 | ]]; |
|
82 | 65 | } |
|
83 | 66 | ||
84 | - | protected function association(BaseProxyQueryInterface $queryBuilder, $data): array |
|
67 | + | protected function association(ProxyQueryInterface $query, FilterData $data): array |
|
85 | 68 | { |
|
86 | - | $alias = $queryBuilder->entityJoin($this->getParentAssociationMappings()); |
|
69 | + | $alias = $query->entityJoin($this->getParentAssociationMappings()); |
|
87 | 70 | $part = strrchr('.'.$this->getFieldName(), '.'); |
|
88 | 71 | $fieldName = substr(false === $part ? $this->getFieldType() : $part, 1); |
|
89 | 72 |
100 | 83 | if (null === $context) { |
|
101 | 84 | $categories = $this->categoryManager->getAllRootCategories(); |
|
102 | 85 | } else { |
|
103 | - | $categories = $this->categoryManager->getCategories($context); |
|
86 | + | $categories = $this->categoryManager->getRootCategoriesForContext($context); |
|
104 | 87 | } |
|
105 | 88 | ||
106 | 89 | $choices = []; |
|
107 | 90 | ||
108 | 91 | foreach ($categories as $category) { |
|
109 | - | $choices[sprintf('%s (%s)', $category->getName(), $category->getContext()->getId())] = $category->getId(); |
|
92 | + | $catContext = $category->getContext(); |
|
93 | + | ||
94 | + | \assert(null !== $catContext); |
|
95 | + | ||
96 | + | $choices[sprintf('%s (%s)', $category->getName() ?? '', $catContext->getId() ?? '')] = $category->getId(); |
|
110 | 97 | ||
111 | 98 | $this->visitChild($category, $choices); |
|
112 | 99 | } |
|
113 | 100 | ||
114 | 101 | return $choices; |
|
115 | 102 | } |
|
116 | 103 | ||
104 | + | /** |
|
105 | + | * @param array<string, mixed> $choices |
|
106 | + | */ |
|
117 | 107 | private function visitChild(CategoryInterface $category, array &$choices, int $level = 2): void |
|
118 | 108 | { |
|
119 | 109 | if (0 === \count($category->getChildren())) { |
14 | 14 | namespace Sonata\ClassificationBundle\Block\Service; |
|
15 | 15 | ||
16 | 16 | use Sonata\AdminBundle\Admin\AdminInterface; |
|
17 | - | use Sonata\AdminBundle\Form\FormMapper; |
|
18 | 17 | use Sonata\BlockBundle\Block\BlockContextInterface; |
|
18 | + | use Sonata\BlockBundle\Block\Service\EditableBlockService; |
|
19 | + | use Sonata\BlockBundle\Form\Mapper\FormMapper; |
|
19 | 20 | use Sonata\BlockBundle\Meta\Metadata; |
|
21 | + | use Sonata\BlockBundle\Meta\MetadataInterface; |
|
20 | 22 | use Sonata\BlockBundle\Model\BlockInterface; |
|
21 | 23 | use Sonata\ClassificationBundle\Model\CollectionInterface; |
|
22 | 24 | use Sonata\ClassificationBundle\Model\CollectionManagerInterface; |
|
23 | 25 | use Sonata\ClassificationBundle\Model\ContextManagerInterface; |
|
24 | 26 | use Sonata\Form\Type\ImmutableArrayType; |
|
25 | - | use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface; |
|
27 | + | use Sonata\Form\Validator\ErrorElement; |
|
26 | 28 | use Symfony\Component\Form\Extension\Core\Type\ChoiceType; |
|
27 | 29 | use Symfony\Component\Form\Extension\Core\Type\TextType; |
|
28 | 30 | use Symfony\Component\HttpFoundation\Response; |
31 | 33 | ||
32 | 34 | /** |
|
33 | 35 | * @author Christian Gripp <mail@core23.de> |
|
36 | + | * |
|
37 | + | * @phpstan-extends AbstractClassificationBlockService<CollectionInterface> |
|
34 | 38 | */ |
|
35 | - | abstract class AbstractCollectionsBlockService extends AbstractClassificationBlockService |
|
39 | + | abstract class AbstractCollectionsBlockService extends AbstractClassificationBlockService implements EditableBlockService |
|
36 | 40 | { |
|
37 | - | /** |
|
38 | - | * @var CollectionManagerInterface |
|
39 | - | */ |
|
40 | - | private $collectionManager; |
|
41 | + | private CollectionManagerInterface $collectionManager; |
|
41 | 42 | ||
42 | 43 | /** |
|
43 | - | * @var AdminInterface|null |
|
44 | + | * @phpstan-var AdminInterface<CollectionInterface>|null |
|
44 | 45 | */ |
|
45 | - | private $collectionAdmin; |
|
46 | + | private ?AdminInterface $collectionAdmin; |
|
46 | 47 | ||
47 | 48 | /** |
|
48 | - | * AbstractCollectionsBlockService constructor. |
|
49 | - | * |
|
50 | - | * @param string|Environment $twigOrDeprecatedName |
|
51 | - | * @param EngineInterface|ContextManagerInterface $contextManagerOrDeprecatedTemplating |
|
52 | - | * @param ContextManagerInterface|CollectionManagerInterface $collectionManagerOrDeprecatedContextManager |
|
53 | - | * @param CollectionManagerInterface|AdminInterface|null $collectionAdminOrDeprecatedCollectionManager |
|
54 | - | * @param AdminInterface|null $deprecatedCollectionAdmin |
|
49 | + | * @phpstan-param AdminInterface<CollectionInterface>|null $collectionAdmin |
|
55 | 50 | */ |
|
56 | 51 | public function __construct( |
|
57 | - | $twigOrDeprecatedName, |
|
58 | - | $contextManagerOrDeprecatedTemplating, |
|
59 | - | $collectionManagerOrDeprecatedContextManager, |
|
60 | - | $collectionAdminOrDeprecatedCollectionManager, |
|
61 | - | $deprecatedCollectionAdmin = null |
|
52 | + | Environment $twig, |
|
53 | + | ContextManagerInterface $contextManager, |
|
54 | + | CollectionManagerInterface $collectionManager, |
|
55 | + | ?AdminInterface $collectionAdmin = null |
|
62 | 56 | ) { |
|
63 | - | // NEXT_MAJOR: remove the if block |
|
64 | - | if (\is_string($twigOrDeprecatedName)) { |
|
65 | - | parent::__construct( |
|
66 | - | $twigOrDeprecatedName, |
|
67 | - | $contextManagerOrDeprecatedTemplating, |
|
68 | - | $collectionManagerOrDeprecatedContextManager |
|
69 | - | ); |
|
70 | - | ||
71 | - | $this->collectionManager = $collectionAdminOrDeprecatedCollectionManager; |
|
72 | - | $this->collectionAdmin = $deprecatedCollectionAdmin; |
|
73 | - | } else { |
|
74 | - | parent::__construct( |
|
75 | - | $twigOrDeprecatedName, |
|
76 | - | $contextManagerOrDeprecatedTemplating |
|
77 | - | ); |
|
78 | - | ||
79 | - | $this->collectionManager = $collectionManagerOrDeprecatedContextManager; |
|
80 | - | $this->collectionAdmin = $collectionAdminOrDeprecatedCollectionManager; |
|
81 | - | } |
|
57 | + | parent::__construct($twig, $contextManager); |
|
58 | + | ||
59 | + | $this->collectionManager = $collectionManager; |
|
60 | + | $this->collectionAdmin = $collectionAdmin; |
|
82 | 61 | } |
|
83 | 62 | ||
84 | - | public function execute(BlockContextInterface $blockContext, ?Response $response = null) |
|
63 | + | public function execute(BlockContextInterface $blockContext, ?Response $response = null): Response |
|
85 | 64 | { |
|
86 | 65 | $collection = $this->getCollection($blockContext->getSetting('collectionId'), $blockContext->getSetting('collection')); |
|
87 | 66 | $collections = $this->collectionManager->findBy([ |
|
88 | 67 | 'enabled' => true, |
|
89 | 68 | 'context' => $blockContext->getSetting('context'), |
|
90 | 69 | ]); |
|
91 | 70 | ||
92 | - | return $this->renderResponse($blockContext->getTemplate(), [ |
|
71 | + | $template = $blockContext->getTemplate(); |
|
72 | + | ||
73 | + | \assert(\is_string($template)); |
|
74 | + | ||
75 | + | return $this->renderResponse($template, [ |
|
93 | 76 | 'context' => $blockContext, |
|
94 | 77 | 'settings' => $blockContext->getSettings(), |
|
95 | 78 | 'block' => $blockContext->getBlock(), |
98 | 81 | ], $response); |
|
99 | 82 | } |
|
100 | 83 | ||
101 | - | public function buildEditForm(FormMapper $formMapper, BlockInterface $block) |
|
84 | + | public function configureCreateForm(FormMapper $form, BlockInterface $block): void |
|
85 | + | { |
|
86 | + | $this->configureEditForm($form, $block); |
|
87 | + | } |
|
88 | + | ||
89 | + | public function configureEditForm(FormMapper $form, BlockInterface $block): void |
|
102 | 90 | { |
|
103 | 91 | if (null === $this->collectionAdmin) { |
|
104 | 92 | throw new \BadMethodCallException('You need the sonata-project/admin-bundle library to edit this block.'); |
|
105 | 93 | } |
|
106 | 94 | ||
107 | - | $adminField = $this->getFormAdminType($formMapper, $this->collectionAdmin, 'collectionId', 'collection', [ |
|
95 | + | $adminField = $this->getFormAdminType($form, $this->collectionAdmin, 'collectionId', 'collection', [ |
|
108 | 96 | 'label' => 'form.label_collection', |
|
109 | 97 | ], [ |
|
110 | 98 | 'translation_domain' => 'SonataClassificationBundle', |
115 | 103 | ], |
|
116 | 104 | ]); |
|
117 | 105 | ||
118 | - | $formMapper->add( |
|
106 | + | $form->add( |
|
119 | 107 | 'settings', |
|
120 | 108 | ImmutableArrayType::class, |
|
121 | 109 | [ |
148 | 136 | ); |
|
149 | 137 | } |
|
150 | 138 | ||
151 | - | public function configureSettings(OptionsResolver $resolver) |
|
139 | + | public function validate(ErrorElement $errorElement, BlockInterface $block): void |
|
140 | + | { |
|
141 | + | } |
|
142 | + | ||
143 | + | public function configureSettings(OptionsResolver $resolver): void |
|
152 | 144 | { |
|
153 | 145 | $resolver->setDefaults([ |
|
154 | 146 | 'title' => null, |
162 | 154 | ]); |
|
163 | 155 | } |
|
164 | 156 | ||
165 | - | public function load(BlockInterface $block) |
|
157 | + | public function load(BlockInterface $block): void |
|
166 | 158 | { |
|
167 | - | if (is_numeric($block->getSetting('collectionId'))) { |
|
168 | - | $block->setSetting('collectionId', $this->getCollection($block->getSetting('collectionId'))); |
|
159 | + | $collectionId = $block->getSetting('collectionId'); |
|
160 | + | if (\is_int($collectionId) || \is_string($collectionId)) { |
|
161 | + | $block->setSetting('collectionId', $this->getCollection($collectionId)); |
|
169 | 162 | } |
|
170 | 163 | } |
|
171 | 164 | ||
172 | - | public function prePersist(BlockInterface $block) |
|
165 | + | public function prePersist(BlockInterface $block): void |
|
173 | 166 | { |
|
174 | 167 | $this->resolveIds($block); |
|
175 | 168 | } |
|
176 | 169 | ||
177 | - | public function preUpdate(BlockInterface $block) |
|
170 | + | public function preUpdate(BlockInterface $block): void |
|
178 | 171 | { |
|
179 | 172 | $this->resolveIds($block); |
|
180 | 173 | } |
|
181 | 174 | ||
182 | - | public function getBlockMetadata($code = null) |
|
175 | + | public function getMetadata(): MetadataInterface |
|
183 | 176 | { |
|
184 | - | $description = (null !== $code ? $code : $this->getName()); |
|
185 | - | ||
186 | - | return new Metadata($this->getName(), $description, false, 'SonataClassificationBundle', [ |
|
177 | + | return new Metadata('sonata.classification.block.collections', null, null, 'SonataClassificationBundle', [ |
|
187 | 178 | 'class' => 'fa fa-folder-open-o', |
|
188 | 179 | ]); |
|
189 | 180 | } |
|
190 | 181 | ||
191 | 182 | /** |
|
192 | - | * @param CollectionInterface|int $id |
|
193 | - | * @param mixed $default |
|
194 | - | * |
|
195 | - | * @return CollectionInterface|null |
|
183 | + | * @param CollectionInterface|int|string|null $id |
|
184 | + | * @param mixed $default |
|
196 | 185 | */ |
|
197 | - | final protected function getCollection($id, $default = null) |
|
186 | + | final protected function getCollection($id, $default = null): ?CollectionInterface |
|
198 | 187 | { |
|
199 | 188 | if ($id instanceof CollectionInterface) { |
|
200 | 189 | return $id; |
|
201 | 190 | } |
|
202 | 191 | ||
203 | - | if (is_numeric($id)) { |
|
192 | + | if (null !== $id) { |
|
204 | 193 | return $this->collectionManager->find($id); |
|
205 | 194 | } |
|
206 | 195 |
211 | 200 | return null; |
|
212 | 201 | } |
|
213 | 202 | ||
214 | - | private function resolveIds(BlockInterface $block) |
|
203 | + | private function resolveIds(BlockInterface $block): void |
|
215 | 204 | { |
|
216 | 205 | $block->setSetting( |
|
217 | 206 | 'collectionId', |
|
218 | - | \is_object($block->getSetting('collectionId')) ? $block->getSetting('collectionId')->getId() : null |
|
207 | + | $block->getSetting('collectionId') instanceof CollectionInterface |
|
208 | + | ? $block->getSetting('collectionId')->getId() |
|
209 | + | : null |
|
219 | 210 | ); |
|
220 | 211 | } |
|
221 | 212 | } |
13 | 13 | ||
14 | 14 | namespace Sonata\ClassificationBundle\Command; |
|
15 | 15 | ||
16 | + | use Sonata\ClassificationBundle\Model\CategoryManagerInterface; |
|
17 | + | use Sonata\ClassificationBundle\Model\CollectionManagerInterface; |
|
16 | 18 | use Sonata\ClassificationBundle\Model\ContextInterface; |
|
17 | - | use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
|
19 | + | use Sonata\ClassificationBundle\Model\ContextManagerInterface; |
|
20 | + | use Sonata\ClassificationBundle\Model\TagManagerInterface; |
|
21 | + | use Symfony\Component\Console\Command\Command; |
|
18 | 22 | use Symfony\Component\Console\Input\InputInterface; |
|
19 | 23 | use Symfony\Component\Console\Output\OutputInterface; |
|
20 | 24 | ||
21 | - | /** |
|
22 | - | * @final since sonata-project/classification-bundle 3.18 |
|
23 | - | */ |
|
24 | - | class FixContextCommand extends ContainerAwareCommand |
|
25 | + | final class FixContextCommand extends Command |
|
25 | 26 | { |
|
26 | - | public function configure() |
|
27 | - | { |
|
28 | - | $this->setName('sonata:classification:fix-context'); |
|
29 | - | $this->setDescription('Generate the default context if none defined and attach the context to all elements'); |
|
27 | + | protected static $defaultName = 'sonata:classification:fix-context'; |
|
28 | + | protected static $defaultDescription = 'Generate the default context if none defined and attach the context to all elements'; |
|
29 | + | ||
30 | + | private ContextManagerInterface $contextManager; |
|
31 | + | ||
32 | + | private TagManagerInterface $tagManager; |
|
33 | + | ||
34 | + | private CollectionManagerInterface $collectionManager; |
|
35 | + | ||
36 | + | private CategoryManagerInterface $categoryManager; |
|
37 | + | ||
38 | + | public function __construct( |
|
39 | + | ContextManagerInterface $contextManager, |
|
40 | + | TagManagerInterface $tagManager, |
|
41 | + | CollectionManagerInterface $collectionManager, |
|
42 | + | CategoryManagerInterface $categoryManager |
|
43 | + | ) { |
|
44 | + | parent::__construct(); |
|
45 | + | ||
46 | + | $this->contextManager = $contextManager; |
|
47 | + | $this->tagManager = $tagManager; |
|
48 | + | $this->collectionManager = $collectionManager; |
|
49 | + | $this->categoryManager = $categoryManager; |
|
30 | 50 | } |
|
31 | 51 | ||
32 | - | public function execute(InputInterface $input, OutputInterface $output) |
|
52 | + | public function configure(): void |
|
33 | 53 | { |
|
34 | - | $contextManager = $this->getContainer()->get('sonata.classification.manager.context'); |
|
35 | - | $tagManager = $this->getContainer()->get('sonata.classification.manager.tag'); |
|
36 | - | $collectionManager = $this->getContainer()->get('sonata.classification.manager.collection'); |
|
37 | - | $categoryManager = $this->getContainer()->get('sonata.classification.manager.category'); |
|
54 | + | \assert(null !== static::$defaultDescription); |
|
55 | + | $this->setDescription(static::$defaultDescription); |
|
56 | + | } |
|
38 | 57 | ||
58 | + | public function execute(InputInterface $input, OutputInterface $output): int |
|
59 | + | { |
|
39 | 60 | $output->writeln('1. Checking default context'); |
|
40 | 61 | ||
41 | - | $defaultContext = $contextManager->findOneBy([ |
|
62 | + | $defaultContext = $this->contextManager->findOneBy([ |
|
42 | 63 | 'id' => ContextInterface::DEFAULT_CONTEXT, |
|
43 | 64 | ]); |
|
44 | 65 | ||
45 | - | if (!$defaultContext) { |
|
66 | + | if (null === $defaultContext) { |
|
46 | 67 | $output->writeln(' > default context is missing, creating one'); |
|
47 | - | $defaultContext = $contextManager->create(); |
|
68 | + | $defaultContext = $this->contextManager->create(); |
|
48 | 69 | $defaultContext->setId(ContextInterface::DEFAULT_CONTEXT); |
|
49 | 70 | $defaultContext->setName('Default'); |
|
50 | 71 | $defaultContext->setEnabled(true); |
|
51 | 72 | ||
52 | - | $contextManager->save($defaultContext); |
|
73 | + | $this->contextManager->save($defaultContext); |
|
53 | 74 | } else { |
|
54 | 75 | $output->writeln(' > default context exists'); |
|
55 | 76 | } |
|
56 | 77 | ||
57 | 78 | $output->writeln('2. Find tag without default context'); |
|
58 | 79 | ||
59 | - | foreach ($tagManager->findBy([]) as $tag) { |
|
60 | - | if ($tag->getContext()) { |
|
80 | + | foreach ($this->tagManager->findBy([]) as $tag) { |
|
81 | + | if (null !== $tag->getContext()) { |
|
61 | 82 | continue; |
|
62 | 83 | } |
|
63 | 84 | ||
64 | - | $output->writeln(sprintf(' > attach default context to tag: %s (%s)', $tag->getSlug(), $tag->getId())); |
|
85 | + | $tagId = $tag->getId(); |
|
86 | + | \assert(null !== $tagId); |
|
87 | + | ||
88 | + | $output->writeln(sprintf(' > attach default context to tag: %s (%s)', $tag->getSlug() ?? '', $tagId)); |
|
65 | 89 | $tag->setContext($defaultContext); |
|
66 | 90 | ||
67 | - | $tagManager->save($tag); |
|
91 | + | $this->tagManager->save($tag); |
|
68 | 92 | } |
|
69 | 93 | ||
70 | 94 | $output->writeln('3. Find collection without default context'); |
|
71 | 95 | ||
72 | - | foreach ($collectionManager->findBy([]) as $collection) { |
|
73 | - | if ($collection->getContext()) { |
|
96 | + | foreach ($this->collectionManager->findBy([]) as $collection) { |
|
97 | + | if (null !== $collection->getContext()) { |
|
74 | 98 | continue; |
|
75 | 99 | } |
|
76 | 100 | ||
77 | - | $output->writeln(sprintf(' > attach default context to collection: %s (%s)', $collection->getSlug(), $collection->getId())); |
|
101 | + | $collectionId = $collection->getId(); |
|
102 | + | \assert(null !== $collectionId); |
|
103 | + | ||
104 | + | $output->writeln(sprintf(' > attach default context to collection: %s (%s)', $collection->getSlug() ?? '', $collectionId)); |
|
78 | 105 | $collection->setContext($defaultContext); |
|
79 | 106 | ||
80 | - | $collectionManager->save($collection); |
|
107 | + | $this->collectionManager->save($collection); |
|
81 | 108 | } |
|
82 | 109 | ||
83 | 110 | $output->writeln('3. Find category without default context'); |
|
84 | 111 | ||
85 | - | foreach ($categoryManager->findBy([]) as $category) { |
|
86 | - | if ($category->getContext()) { |
|
112 | + | foreach ($this->categoryManager->findBy([]) as $category) { |
|
113 | + | if (null !== $category->getContext()) { |
|
87 | 114 | continue; |
|
88 | 115 | } |
|
89 | 116 | ||
90 | - | $output->writeln(sprintf(' > attach default context to collection: %s (%s)', $category->getSlug(), $category->getId())); |
|
117 | + | $categoryId = $category->getId(); |
|
118 | + | \assert(null !== $categoryId); |
|
119 | + | ||
120 | + | $output->writeln(sprintf(' > attach default context to collection: %s (%s)', $category->getSlug() ?? '', $categoryId)); |
|
91 | 121 | $category->setContext($defaultContext); |
|
92 | 122 | ||
93 | - | $categoryManager->save($category); |
|
123 | + | $this->categoryManager->save($category); |
|
94 | 124 | } |
|
95 | 125 | ||
96 | 126 | $output->writeln('Done!'); |
17 | 17 | ||
18 | 18 | abstract class Tag implements TagInterface |
|
19 | 19 | { |
|
20 | - | /** |
|
21 | - | * @var string|null |
|
22 | - | */ |
|
23 | - | protected $name; |
|
20 | + | protected ?string $name = null; |
|
24 | 21 | ||
25 | - | /** |
|
26 | - | * @var string|null |
|
27 | - | */ |
|
28 | - | protected $slug; |
|
22 | + | protected ?string $slug = null; |
|
29 | 23 | ||
30 | - | /** |
|
31 | - | * @var \DateTime|null |
|
32 | - | */ |
|
33 | - | protected $createdAt; |
|
24 | + | protected ?\DateTimeInterface $createdAt = null; |
|
34 | 25 | ||
35 | - | /** |
|
36 | - | * @var \DateTime|null |
|
37 | - | */ |
|
38 | - | protected $updatedAt; |
|
26 | + | protected ?\DateTimeInterface $updatedAt = null; |
|
39 | 27 | ||
40 | - | /** |
|
41 | - | * @var bool |
|
42 | - | */ |
|
43 | - | protected $enabled; |
|
28 | + | protected bool $enabled = false; |
|
44 | 29 | ||
45 | - | /** |
|
46 | - | * @var ContextInterface|null |
|
47 | - | */ |
|
48 | - | protected $context; |
|
30 | + | protected ?ContextInterface $context = null; |
|
49 | 31 | ||
50 | - | public function __toString() |
|
32 | + | public function __toString(): string |
|
51 | 33 | { |
|
52 | - | return $this->getName() ?: 'n/a'; |
|
34 | + | return $this->getName() ?? 'n/a'; |
|
53 | 35 | } |
|
54 | 36 | ||
55 | - | /** |
|
56 | - | * @final since sonata-project/classification-bundle 3.18 |
|
57 | - | */ |
|
58 | - | public function setName($name) |
|
37 | + | final public function setName(?string $name): void |
|
59 | 38 | { |
|
60 | 39 | $this->name = $name; |
|
61 | 40 | ||
62 | 41 | $this->setSlug($name); |
|
63 | 42 | } |
|
64 | 43 | ||
65 | - | /** |
|
66 | - | * @final since sonata-project/classification-bundle 3.18 |
|
67 | - | */ |
|
68 | - | public function getName() |
|
44 | + | final public function getName(): ?string |
|
69 | 45 | { |
|
70 | 46 | return $this->name; |
|
71 | 47 | } |
|
72 | 48 | ||
73 | - | /** |
|
74 | - | * @final since sonata-project/classification-bundle 3.18 |
|
75 | - | */ |
|
76 | - | public function setEnabled($enabled) |
|
49 | + | final public function setEnabled(bool $enabled): void |
|
77 | 50 | { |
|
78 | 51 | $this->enabled = $enabled; |
|
79 | 52 | } |
|
80 | 53 | ||
81 | - | /** |
|
82 | - | * @final since sonata-project/classification-bundle 3.18 |
|
83 | - | */ |
|
84 | - | public function getEnabled() |
|
54 | + | final public function getEnabled(): bool |
|
85 | 55 | { |
|
86 | 56 | return $this->enabled; |
|
87 | 57 | } |
|
88 | 58 | ||
89 | - | /** |
|
90 | - | * @final since sonata-project/classification-bundle 3.18 |
|
91 | - | */ |
|
92 | - | public function setSlug($slug) |
|
59 | + | final public function setSlug(?string $slug): void |
|
93 | 60 | { |
|
94 | - | $this->slug = self::slugify($slug); |
|
61 | + | $this->slug = self::slugify($slug ?? ''); |
|
95 | 62 | } |
|
96 | 63 | ||
97 | - | /** |
|
98 | - | * @final since sonata-project/classification-bundle 3.18 |
|
99 | - | */ |
|
100 | - | public function getSlug() |
|
64 | + | final public function getSlug(): ?string |
|
101 | 65 | { |
|
102 | 66 | return $this->slug; |
|
103 | 67 | } |
|
104 | 68 | ||
105 | - | /** |
|
106 | - | * @final since sonata-project/classification-bundle 3.18 |
|
107 | - | */ |
|
108 | - | public function setCreatedAt(?\DateTime $createdAt = null) |
|
69 | + | final public function setCreatedAt(?\DateTimeInterface $createdAt): void |
|
109 | 70 | { |
|
110 | 71 | $this->createdAt = $createdAt; |
|
111 | 72 | } |
|
112 | 73 | ||
113 | - | /** |
|
114 | - | * @final since sonata-project/classification-bundle 3.18 |
|
115 | - | */ |
|
116 | - | public function getCreatedAt() |
|
74 | + | final public function getCreatedAt(): ?\DateTimeInterface |
|
117 | 75 | { |
|
118 | 76 | return $this->createdAt; |
|
119 | 77 | } |
|
120 | 78 | ||
121 | - | /** |
|
122 | - | * @final since sonata-project/classification-bundle 3.18 |
|
123 | - | */ |
|
124 | - | public function setUpdatedAt(?\DateTime $updatedAt = null) |
|
79 | + | final public function setUpdatedAt(?\DateTimeInterface $updatedAt): void |
|
125 | 80 | { |
|
126 | 81 | $this->updatedAt = $updatedAt; |
|
127 | 82 | } |
|
128 | 83 | ||
129 | - | /** |
|
130 | - | * @final since sonata-project/classification-bundle 3.18 |
|
131 | - | */ |
|
132 | - | public function getUpdatedAt() |
|
84 | + | final public function getUpdatedAt(): ?\DateTimeInterface |
|
133 | 85 | { |
|
134 | 86 | return $this->updatedAt; |
|
135 | 87 | } |
|
136 | 88 | ||
137 | - | public function preUpdate() |
|
89 | + | public function preUpdate(): void |
|
138 | 90 | { |
|
139 | 91 | $this->setUpdatedAt(new \DateTime()); |
|
140 | 92 | } |
|
141 | 93 | ||
142 | 94 | /** |
|
143 | - | * @final since sonata-project/classification-bundle 3.18 |
|
144 | - | * |
|
145 | 95 | * @see http://snipplr.com/view/22741/slugify-a-string-in-php/. |
|
146 | - | * |
|
147 | - | * @param string $text |
|
148 | - | * |
|
149 | - | * @return string |
|
150 | 96 | */ |
|
151 | - | public static function slugify($text) |
|
97 | + | final public static function slugify(string $text): string |
|
152 | 98 | { |
|
153 | 99 | $text = Slugify::create()->slugify($text); |
|
154 | 100 | ||
155 | - | if (empty($text)) { |
|
101 | + | if ('' === $text) { |
|
156 | 102 | return 'n-a'; |
|
157 | 103 | } |
|
158 | 104 | ||
159 | 105 | return $text; |
|
160 | 106 | } |
|
161 | 107 | ||
162 | - | /** |
|
163 | - | * @final since sonata-project/classification-bundle 3.18 |
|
164 | - | */ |
|
165 | - | public function setContext(ContextInterface $context) |
|
108 | + | final public function setContext(?ContextInterface $context): void |
|
166 | 109 | { |
|
167 | 110 | $this->context = $context; |
|
168 | 111 | } |
|
169 | 112 | ||
170 | - | /** |
|
171 | - | * @final since sonata-project/classification-bundle 3.18 |
|
172 | - | */ |
|
173 | - | public function getContext() |
|
113 | + | final public function getContext(): ?ContextInterface |
|
174 | 114 | { |
|
175 | 115 | return $this->context; |
|
176 | 116 | } |
Learn more Showing 7 files with coverage changes found.
src/DependencyInjection/SonataClassificationExtension.php
src/Entity/BaseTag.php
src/Resources/config/admin.php
src/Resources/config/orm.php
src/Resources/config/form.php
src/Resources/config/controllers.php
src/Resources/config/command.php
92cea37
5c03958
bd371d1
4585736
f9bbb44
b67256a
f35bc32
7d4cabe
1b84a95
ae001e0
3af9d41
47927da
5d7ae91
145dde4
a8f7cb2
d293660
fbb4acd
b3b8882
0d65489
07dd559
e75bb9a
df4ed6c
5ba227a
ada37c1
e72d05d
3ce5c4a
8ef10f0
0bcbaae
6bd4b8f
31b40e3
ad30ce7
74d937c
3479046
d65136c
3e91abb
6f74dda
9654768
39be461
10550de
39f81dc
4456695
9001df8
1b1082a
a76cc8a
9ddd8bd
5eeddce
0772751
e00453f
395d10e
83bae33
7c39534
af52890
ee21b21
95c6836
4837974
cdebbd3
a38d939
4832ca2
bcb5d60
fbf2aff
f45f621
b2396c5
365523e
1872395
c7862e4
2db098c
655c0a7
b6f3379
28fd59d
6dc6321
6b12d84
87b9943
ab36dc0
517cc92
5db321b
f118622
57ee952
86d2a07
c01fa7e
23283dd
759da94
fb9c9b1
ba60ef7
97d7bf6
26c6258
8001494
4a336cf
8ea0418
dff2ac5
9c208ef
36c8311
3c9b18c
29d653f
2705072
1028819
a586491
60776d7
e3e73a9
99a8c1b
4bbb91e
abe9609
959a477
8286911
689a600
14c3015
291747f
5e4e7c8
afdaf08
d89cf38
11b4543
9c6598b
57b16ee
6b37eeb
92c195d
be4c856
0ae2a97
ee8ee97
6629089
00adf91
02d68b0
1b309b2
4ac4046
8e44265
887128a
907edbb
d13a41b
5eaca2c
1f811f2
6290e92
58842bd
ccb86cd
5f7ca1b
e3a5b74
fb103de
8eac679
44421aa
06cc725
d315919
01eda04
87a883b
49412fc
c7ef24e
cd60fe6
db7e6f5
172f454
ed20fe9
1f766b0
753870b
ebaab04
68454a7
b3c8c66
56442d6
98fe2a8
cf4155b
a6b6871
39f2b3e
f9e477f
c59c629
67e0eb7
f5df47c
725e193
a080876
aa05164
4595d63
213b81f
b7bb475
f13cdac
b47d0c5
60efa34
dee33ba
71c6d44
657dc91
f2f164b
25cbcd3
025cb9d
3811fd0
326d24d
67b4e04
75a61d9
da5bcfb
40043e7
cc276ec
7680746
1971f8c
59c1688
47b73c4
a9dc20f
9660fd3
269521d
59e51b9
6be7928
4f076ac
d0fd5b6
69cbb3c
ddedfe2
818d8d2
514ca66
664f21c
eb7626f
e46699d
65d44e5
89d27e8
ba05c61
9fc7001
171b255
b1dd98c
8c3fdfd
c21cc9e
6693e45
0be7949
80c3029
a1b9f9b
0ca3a14
b175bae
729c2aa
7467881
8eb017c
3648b14
b5bd33d
37ebcab
b5e7b1c
0a80040
9b3a7bb
3cdcf5f
01fdcc3
b20443d