Completed
Push — master ( 596cad...5cddda )
by Nekrasov
03:01
created

AbstractWidgetFactory   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 22
Bugs 5 Features 0
Metric Value
wmc 12
c 22
b 5
f 0
lcom 1
cbo 6
dl 0
loc 172
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A parseFullWidgetNameFromString() 0 4 1
A __construct() 0 6 1
A __call() 0 6 1
A instantiateWidget() 0 20 3
A wrapContentInContainer() 0 13 3
A encryptWidgetParams() 0 4 1
A decryptWidgetParams() 0 6 2
1
<?php
2
3
namespace Arrilot\Widgets\Factories;
4
5
use Arrilot\Widgets\AbstractWidget;
6
use Arrilot\Widgets\Contracts\ApplicationWrapperContract;
7
use Arrilot\Widgets\Misc\InvalidWidgetClassException;
8
use Arrilot\Widgets\Misc\ViewExpressionTrait;
9
use Arrilot\Widgets\WidgetId;
10
11
abstract class AbstractWidgetFactory
12
{
13
    use ViewExpressionTrait;
14
15
    /**
16
     * Widget object to work with.
17
     *
18
     * @var AbstractWidget
19
     */
20
    protected $widget;
21
22
    /**
23
     * Widget configuration array.
24
     *
25
     * @var array
26
     */
27
    protected $widgetConfig;
28
29
    /**
30
     * The name of the widget being called.
31
     *
32
     * @var string
33
     */
34
    public $widgetName;
35
36
    /**
37
     * Array of widget parameters excluding the first one (config).
38
     *
39
     * @var array
40
     */
41
    public $widgetParams;
42
43
    /**
44
     * Array of widget parameters including the first one (config).
45
     *
46
     * @var array
47
     */
48
    public $widgetFullParams;
49
50
    /**
51
     * Laravel application wrapper for better testability.
52
     *
53
     * @var ApplicationWrapperContract;
54
     */
55
    public $app;
56
57
    /**
58
     * Another factory that produces some javascript.
59
     *
60
     * @var JavascriptFactory
61
     */
62
    protected $javascriptFactory;
63
64
    /**
65
     * The flag for not wrapping content in a special container.
66
     *
67
     * @var bool
68
     */
69
    public static $skipWidgetContainer = false;
70
71
    /**
72
     * Constructor.
73
     *
74
     * @param ApplicationWrapperContract $app
75
     */
76
    public function __construct(ApplicationWrapperContract $app)
77
    {
78
        $this->app = $app;
79
80
        $this->javascriptFactory = new JavascriptFactory($this);
81
    }
82
83
    /**
84
     * Magic method that catches all widget calls.
85
     *
86
     * @param string $widgetName
87
     * @param array  $params
88
     *
89
     * @return mixed
90
     */
91
    public function __call($widgetName, array $params = [])
92
    {
93
        array_unshift($params, $widgetName);
94
95
        return call_user_func_array([$this, 'run'], $params);
96
    }
97
98
    /**
99
     * Set class properties and instantiate a widget object.
100
     *
101
     * @param $params
102
     *
103
     * @throws InvalidWidgetClassException
104
     */
105
    protected function instantiateWidget(array $params = [])
106
    {
107
        WidgetId::increment();
108
109
        $this->widgetName = $this->parseFullWidgetNameFromString(array_shift($params));
110
        $this->widgetFullParams = $params;
111
        $this->widgetConfig = (array) array_shift($params);
112
        $this->widgetParams = $params;
113
114
        $rootNamespace = $this->app->config('laravel-widgets.default_namespace', $this->app->getNamespace().'Widgets');
115
116
        $fqcn = $rootNamespace.'\\'.$this->widgetName;
117
        $widgetClass = class_exists($fqcn) ? $fqcn : $this->widgetName;
118
119
        if (!is_subclass_of($widgetClass, 'Arrilot\Widgets\AbstractWidget')) {
120
            throw new InvalidWidgetClassException('Class "'.$widgetClass.'" must extend "Arrilot\Widgets\AbstractWidget" class');
121
        }
122
123
        $this->widget = new $widgetClass($this->widgetConfig);
124
    }
125
126
    /**
127
     * Convert stuff like 'profile.feedWidget' to 'Profile\FeedWidget'.
128
     *
129
     * @param $widgetName
130
     *
131
     * @return string
132
     */
133
    protected function parseFullWidgetNameFromString($widgetName)
134
    {
135
        return studly_case(str_replace('.', '\\', $widgetName));
136
    }
137
138
    /**
139
     * Wrap the given content in a container if it's not an ajax call.
140
     *
141
     * @param $content
142
     *
143
     * @return string
144
     */
145
    protected function wrapContentInContainer($content)
146
    {
147
        if (self::$skipWidgetContainer) {
148
            return $content;
149
        }
150
151
        $container = $this->widget->container();
152
        if (empty($container['element'])) {
153
            $container['element'] = 'div';
154
        }
155
156
        return '<'.$container['element'].' id="'.$this->javascriptFactory->getContainerId().'" '.$container['attributes'].'>'.$content.'</'.$container['element'].'>';
157
    }
158
    
159
    /**
160
     * Encrypt widget params to be transported via HTTP.
161
     * 
162
     * @param array $params
163
     * @return string 
164
     */
165
    public function encryptWidgetParams($params)
166
    {
167
        return $this->app->make('encrypter')->encrypt(json_encode($params));
168
    }
169
170
    /**
171
     * Decrypt widget params that were transported via HTTP.
172
     *
173
     * @param string $params
174
     * @return array
175
     */
176
    public function decryptWidgetParams($params)
177
    {
178
        $params = json_decode($this->app->make('encrypter')->decrypt($params), true);
179
180
        return $params ? $params : [];
181
    }
182
}
183