WidgetFactory::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
/**
3
 * This file is part of the sauls/widget package.
4
 *
5
 * @author    Saulius Vaičeliūnas <[email protected]>
6
 * @link      http://saulius.vaiceliunas.lt
7
 * @copyright 2018
8
 *
9
 * For the full copyright and license information, please view the LICENSE
10
 * file that was distributed with this source code.
11
 */
12
13
namespace Sauls\Component\Widget\Factory;
14
15
use Sauls\Component\Collection\Collection;
16
use Sauls\Component\Widget\Exception\CollectionItemNotFoundException;
17
use Sauls\Component\Widget\Exception\WidgetNotFoundException;
18
use Sauls\Component\Widget\Factory\Traits\WidgetFactoryAwareTrait;
19
use Sauls\Component\Widget\ViewWidgetInterface;
20
use Sauls\Component\Widget\WidgetInterface;
21
use SplFileInfo;
22
23
use function get_class;
24
use function Sauls\Component\Helper\array_remove_key;
25
use function Sauls\Component\Helper\class_uses_trait;
26
27
class WidgetFactory implements WidgetFactoryInterface
28
{
29
    private $widgetCollection;
30
    private $viewCollection;
31
32 12
    public function __construct(Collection $widgetCollection, Collection $viewCollection)
33
    {
34 12
        $this->widgetCollection = $widgetCollection;
35 12
        $this->viewCollection = $viewCollection;
36 12
    }
37
38
    /**
39
     * @throws WidgetNotFoundException
40
     */
41 9
    public function create(string $name, array $options = []): WidgetInterface
42
    {
43
        try {
44 9
            $widget = clone $this->widgetCollection->get($name);
45
46 8
            return $this->configureWidget($widget, $options);
47 4
        } catch (CollectionItemNotFoundException $e) {
48 3
            throw new WidgetNotFoundException(sprintf('Widget `%s` not found or is not registered.', $name));
49 2
        } catch (\Exception $e) {
50 2
            throw new \RuntimeException($e->getMessage());
51
        }
52
    }
53
54
    /**
55
     * @throws \Exception
56
     */
57 8
    private function configureWidget(WidgetInterface $widget, array $options): WidgetInterface
58
    {
59 8
        $viewName = $this->resolveViewName($options);
60 8
        $this->injectWidgetFactory($widget);
61
62 8
        $widget = $widget->widget($options);
63
64 6
        return $this->resolveDependencies($widget, $viewName);
65
    }
66
67 8
    private function resolveViewName($options): string
68
    {
69 8
        return array_remove_key($options, 'view', '');
70
    }
71
72 8
    private function injectWidgetFactory($widget): void
73
    {
74 8
        if (class_uses_trait(get_class($widget), WidgetFactoryAwareTrait::class)) {
75 2
            $widget->setWidgetFactory($this);
76
        }
77 8
    }
78
79 6
    private function resolveDependencies(WidgetInterface $widget, string $viewName): WidgetInterface
80
    {
81 6
        $this->injectView($widget, $viewName);
82
83 6
        return $widget;
84
    }
85
86 6
    private function injectView(WidgetInterface $widget, string $viewName): void
87
    {
88 6
        if (is_subclass_of($widget, ViewWidgetInterface::class)) {
89 3
            $viewName = $this->viewCollection->keyExists($viewName) ? $viewName : $this->resolveWidgetViewName($widget);
90 3
            $widget->setView($this->viewCollection->get($viewName));
0 ignored issues
show
Bug introduced by
The method setView() does not exist on Sauls\Component\Widget\WidgetInterface. It seems like you code against a sub-type of Sauls\Component\Widget\WidgetInterface such as Sauls\Component\Widget\ViewWidgetInterface or Sauls\Component\Widget\ViewWidget. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

90
            $widget->/** @scrutinizer ignore-call */ 
91
                     setView($this->viewCollection->get($viewName));
Loading history...
91
        }
92 6
    }
93
94 3
    private function resolveWidgetViewName(WidgetInterface $widget): string
95
    {
96 3
        $info = new SplFileInfo($widget->getOption('viewFile'));
97 3
        $fileExtension = $info->getExtension();
98
99 3
        return $this->viewCollection->keyExists($fileExtension) ? $fileExtension : 'string';
100
    }
101
}
102