Completed
Push — master ( 4926b6...552c81 )
by Saulius
10s
created

WidgetFactory::resolveDependencies()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
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 function Sauls\Component\Helper\array_remove_key;
17
use function Sauls\Component\Helper\class_uses_trait;
18
use Sauls\Component\Widget\Exception\CollectionItemNotFoundException;
19
use Sauls\Component\Widget\Exception\WidgetNotFoundException;
20
use Sauls\Component\Widget\Factory\Traits\WidgetFactoryAwareTrait;
21
use Sauls\Component\Widget\ViewWidgetInterface;
22
use Sauls\Component\Widget\WidgetInterface;
23
24
class WidgetFactory implements WidgetFactoryInterface
25
{
26
    private $widgetCollection;
27
    private $viewCollection;
28
29 8
    public function __construct(Collection $widgetCollection, Collection $viewCollection)
30
    {
31 8
        $this->widgetCollection = $widgetCollection;
32 8
        $this->viewCollection = $viewCollection;
33 8
    }
34
35
    /**
36
     * @throws WidgetNotFoundException
37
     */
38 8
    public function create(string $name, array $options = []): WidgetInterface
39
    {
40
        try {
41 8
            $widget = clone $this->widgetCollection->get($name);
42
43 7
            return $this->configureWidget($widget, $options);
44
45 4
        } catch (CollectionItemNotFoundException $e) {
46 3
            throw new WidgetNotFoundException(sprintf('Widget `%s` not found or is not registered.', $name));
47 2
        } catch (\Exception $e) {
48 2
            throw new \RuntimeException($e->getMessage());
49
        }
50
    }
51
52
    /**
53
     * @throws \Exception
54
     */
55 7
    private function configureWidget(WidgetInterface $widget, array $options): WidgetInterface
56
    {
57 7
        $viewName = $this->resolveViewName($options);
58 7
        $this->injectWidgetFactory($widget);
59
60 7
        $widget = $widget->widget($options);
61
62 5
        return $this->resolveDependencies($widget, $viewName);
63
    }
64
65 7
    private function resolveViewName($options): string
66
    {
67 7
        return array_remove_key($options, 'view', '');
68
    }
69
70 5
    private function resolveDependencies(WidgetInterface $widget, string $viewName): WidgetInterface
71
    {
72 5
        $this->injectView($widget, $viewName);
73
74 5
        return $widget;
75
    }
76
77 2
    private function resolveWidgetViewName(WidgetInterface $widget): string
78
    {
79 2
        $info = new \SplFileInfo($widget->getOption('viewFile'));
80 2
        $fileExtension = $info->getExtension();
81
82 2
        return $this->viewCollection->keyExists($fileExtension) ? $fileExtension : 'string';
83
84
    }
85
86 5
    private function injectView(WidgetInterface $widget, string $viewName): void
87
    {
88 5
        if (is_subclass_of($widget, ViewWidgetInterface::class)) {
89 2
            $viewName = $this->viewCollection->keyExists($viewName) ? $viewName : $this->resolveWidgetViewName($widget);
90 2
            $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 5
    }
93
94 7
    private function injectWidgetFactory($widget): void
95
    {
96 7
        if (class_uses_trait(\get_class($widget), WidgetFactoryAwareTrait::class)) {
97 2
            $widget->setWidgetFactory($this);
98
        }
99 7
    }
100
}
101