Completed
Push — master ( 62de3c...551e8d )
by Ryan
14:54 queued 07:42
created

ViewComposer::getOverloadPath()   C

Complexity

Conditions 9
Paths 22

Size

Total Lines 68
Code Lines 20

Duplication

Lines 10
Ratio 14.71 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 10
loc 68
rs 6.2813
cc 9
eloc 20
nc 22
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Anomaly\Streams\Platform\View;
2
3
use Anomaly\Streams\Platform\Addon\AddonCollection;
4
use Anomaly\Streams\Platform\Addon\Module\Module;
5
use Anomaly\Streams\Platform\Addon\Theme\Theme;
6
use Anomaly\Streams\Platform\View\Event\ViewComposed;
7
use Illuminate\Contracts\Events\Dispatcher;
8
use Illuminate\Contracts\View\Factory;
9
use Illuminate\Http\Request;
10
use Illuminate\View\View;
11
use Mobile_Detect;
12
13
/**
14
 * Class ViewComposer
15
 *
16
 * @link    http://anomaly.is/streams-platform
17
 * @author  AnomalyLabs, Inc. <[email protected]>
18
 * @author  Ryan Thompson <[email protected]>
19
 * @package Anomaly\Streams\Platform\Support
20
 */
21
class ViewComposer
22
{
23
24
    /**
25
     * Runtime cache.
26
     *
27
     * @var array
28
     */
29
    protected $cache = [];
30
31
    /**
32
     * The view factory.
33
     *
34
     * @var Factory
35
     */
36
    protected $view;
37
38
    /**
39
     * The agent utility.
40
     *
41
     * @var Mobile_Detect
42
     */
43
    protected $agent;
44
45
    /**
46
     * The event dispatcher.
47
     *
48
     * @var Dispatcher
49
     */
50
    protected $events;
51
52
    /**
53
     * The current theme.
54
     *
55
     * @var Theme|null
56
     */
57
    protected $theme;
58
59
    /**
60
     * The active module.
61
     *
62
     * @var Module|null
63
     */
64
    protected $module;
65
66
    /**
67
     * The addon collection.
68
     *
69
     * @var AddonCollection
70
     */
71
    protected $addons;
72
73
    /**
74
     * The request object.
75
     *
76
     * @var Request
77
     */
78
    protected $request;
79
80
    /**
81
     * The view overrides collection.
82
     *
83
     * @var ViewOverrides
84
     */
85
    protected $overrides;
86
87
    /**
88
     * The view mobile overrides.
89
     *
90
     * @var ViewMobileOverrides
91
     */
92
    protected $mobiles;
93
94
    /**
95
     * @param Factory             $view
96
     * @param Mobile_Detect       $agent
97
     * @param Dispatcher          $events
98
     * @param AddonCollection     $addons
99
     * @param Request             $request
100
     * @param ViewOverrides       $overrides
101
     * @param ViewMobileOverrides $mobiles
102
     */
103
    function __construct(
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
104
        Factory $view,
105
        Mobile_Detect $agent,
106
        Dispatcher $events,
107
        AddonCollection $addons,
108
        ViewOverrides $overrides,
109
        Request $request,
0 ignored issues
show
Bug introduced by
You have injected the Request via parameter $request. This is generally not recommended as there might be multiple instances during a request cycle (f.e. when using sub-requests). Instead, it is recommended to inject the RequestStack and retrieve the current request each time you need it via getCurrentRequest().
Loading history...
110
        ViewMobileOverrides $mobiles
111
    ) {
112
        $this->view      = $view;
113
        $this->agent     = $agent;
114
        $this->events    = $events;
115
        $this->addons    = $addons;
116
        $this->mobiles   = $mobiles;
117
        $this->request   = $request;
118
        $this->overrides = $overrides;
119
120
        $area = $request->segment(1) == 'admin' ? 'admin' : 'standard';
121
122
        $this->theme  = $this->addons->themes->active($area);
0 ignored issues
show
Documentation introduced by
The property themes does not exist on object<Anomaly\Streams\P...\Addon\AddonCollection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
123
        $this->module = $this->addons->modules->active();
0 ignored issues
show
Documentation introduced by
The property modules does not exist on object<Anomaly\Streams\P...\Addon\AddonCollection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
124
125
        $this->mobile = $this->agent->isMobile();
0 ignored issues
show
Bug introduced by
The property mobile does not seem to exist. Did you mean mobiles?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
126
    }
127
128
    /**
129
     * Compose the view before rendering.
130
     *
131
     * @param  View $view
132
     * @return View
133
     */
134
    public function compose(View $view)
135
    {
136
        if (!$this->theme) {
137
138
            $this->events->fire(new ViewComposed($view));
139
140
            return $view;
141
        }
142
143
        $mobile    = $this->mobiles->get($this->theme->getNamespace(), []);
144
        $overrides = $this->overrides->get($this->theme->getNamespace(), []);
145
146 View Code Duplication
        if ($this->mobile && $path = array_get($mobile, $view->getName(), null)) {
0 ignored issues
show
Bug introduced by
The property mobile does not seem to exist. Did you mean mobiles?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
            $view->setPath($path);
148
        } elseif ($path = array_get($overrides, $view->getName(), null)) {
149
            $view->setPath($path);
150
        }
151
152
        if ($this->module) {
153
154
            $mobile    = $this->mobiles->get($this->module->getNamespace(), []);
155
            $overrides = $this->overrides->get($this->module->getNamespace(), []);
156
157 View Code Duplication
            if ($this->mobile && $path = array_get($mobile, $view->getName(), null)) {
0 ignored issues
show
Bug introduced by
The property mobile does not seem to exist. Did you mean mobiles?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
158
                $view->setPath($path);
159
            } elseif ($path = array_get($overrides, $view->getName(), null)) {
160
                $view->setPath($path);
161
            }
162
        }
163
164
        if ($overload = $this->getOverloadPath($view)) {
165
            $view->setPath($overload);
166
        }
167
168
        $this->events->fire(new ViewComposed($view));
169
170
        return $view;
171
    }
172
173
    /**
174
     * Get the override view path.
175
     *
176
     * @param  $view
177
     * @return null|string
178
     */
179
    public function getOverloadPath(View $view)
180
    {
181
182
        /**
183
         * We can only overload namespaced
184
         * views right now.
185
         */
186
        if (!str_contains($view->getName(), '::')) {
187
            return null;
188
        }
189
190
        /**
191
         * Split the view into it's
192
         * namespace and path.
193
         */
194
        list($namespace, $path) = explode('::', $view->getName());
195
196
        $path = str_replace('.', '/', $path);
197
198
        /**
199
         * If the view is already in
200
         * the theme then skip it.
201
         */
202
        if ($namespace == 'theme' || str_is('*.theme.*', $namespace)) {
203
            return null;
204
        }
205
206
        /**
207
         * If the view is a streams view then
208
         * it's real easy to guess what the
209
         * override path should be.
210
         */
211
        if ($namespace == 'streams') {
212
            $path = $this->theme->getNamespace('streams/' . $path);
213
        }
214
215
        /**
216
         * If the view uses a dot syntax namespace then
217
         * transform it all into the override view path.
218
         */
219 View Code Duplication
        if ($addon = $this->addons->get($namespace)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
220
            $path = $this->theme->getNamespace(
221
                "addons/{$addon->getVendor()}/{$addon->getSlug()}-{$addon->getType()}/" . $path
222
            );
223
        }
224
225
        if ($this->view->exists($path)) {
226
            return $path;
227
        }
228
229
        /**
230
         * If the view uses a dot syntax namespace then
231
         * transform it all into the override view path.
232
         *
233
         * @deprecated since v3.0.0
234
         */
235 View Code Duplication
        if ($addon) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
236
            $path = $this->theme->getNamespace(
237
                "addon/{$addon->getVendor()}/{$addon->getSlug()}-{$addon->getType()}/" . $path
238
            );
239
        }
240
241
        if ($this->view->exists($path)) {
242
            return $path;
243
        }
244
245
        return null;
246
    }
247
}
248