Completed
Push — master ( 7df504...c0d6aa )
by Iman
02:52
created

Normalizer::normalizeCacheLifeTime()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 4
nop 0
1
<?php
2
3
namespace Imanghafoori\Widgets\Utils;
4
5
6
use Imanghafoori\Widgets\BaseWidget;
7
8
class Normalizer
9
{
10
    private $widget;
11
12
    public function normalizeWidgetConfig(BaseWidget $widget)
13
    {
14
        // to avoid normalizing a widget multiple times unnecessarily :
15
        if(isset($widget->isNormalized)){
16
            return null;
17
        }
18
19
        $this->widget = $widget;
20
        $this->normalizeControllerMethod();
21
        $this->normalizePresenterName();
22
        $this->normalizeTemplateName();
23
        $this->normalizeContextAs();
24
        $this->normalizeCacheLifeTime();
25
        $this->normalizeCacheTags();
26
        $widget->isNormalized = true;
0 ignored issues
show
Bug introduced by
The property isNormalized does not seem to exist in Imanghafoori\Widgets\BaseWidget.

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...
27
    }
28
29
    /**
30
     * Figures out which method should be called as the controller.
31
     * @return null
32
     */
33
    private function normalizeControllerMethod()
34
    {
35
        // We decide to call data method on widget object by default.
36
        $controllerMethod = [$this->widget, 'data'];
37
        $ctrlClass = get_class($this->widget);
38
39
        // If the user has explicitly declared controller class path on widget
40
        // then we decide to call data method on that instead.
41
        if ($this->widget->controller) {
42
            $ctrlClass = $this->widget->controller;
43
            $controllerMethod = ($this->widget->controller) . '@data';
44
        }
45
46
        if (!method_exists($ctrlClass, 'data')) {
47
            throw new \BadMethodCallException("'data' method not found on " . class_basename($this->widget));
48
        }
49
50
        if (!class_exists($ctrlClass)) {
51
            throw new \InvalidArgumentException("Controller class: [{$ctrlClass}] not found.");
52
        }
53
54
        $this->widget->controller = $controllerMethod;
55
    }
56
57
    /**
58
     * Figures out which method should be called as the presenter
59
     * @return null
60
     */
61
    private function normalizePresenterName()
62
    {
63
        if ($this->widget->presenter === 'default') {
64
            $presenter = class_basename($this->widget) . 'Presenter';
65
66
            if (class_exists($presenter)) {
67
                $this->widget->presenter = $presenter . '@presenter';
68
            } else {
69
                $this->widget->presenter = null;
70
            }
71
        } else {
72
            if (!class_exists($this->widget->presenter)) {
73
                throw new \InvalidArgumentException("Presenter Class [{$this->widget->presenter}] not found.");
74
            }
75
            $this->widget->presenter = $this->widget->presenter . '@present';
76
        }
77
78
    }
79
80
    /**
81
     * Figures out which template to render.
82
     * @return null
83
     */
84
    private function normalizeTemplateName()
85
    {
86
        // class name without namespace.
87
        $className = str_replace('App\\Widgets\\', '', class_basename($this->widget));
88
        // replace slashes with dots
89
        $className = str_replace(['\\', '/'], '.', $className);
90
91
        if ($this->widget->template === null) {
92
            $this->widget->template = 'Widgets::' . $className . 'View';
93
        }
94
95
        if (!view()->exists($this->widget->template)) {
0 ignored issues
show
Bug introduced by
The method exists does only exist in Illuminate\Contracts\View\Factory, but not in Illuminate\View\View.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
96
            throw new \InvalidArgumentException("View file [{$className}View] not found by: '" . class_basename($this->widget) . " '");
97
        }
98
    }
99
100
    /**
101
     * Figures out what the variable name should be in view file.
102
     * @return null
103
     */
104
    private function normalizeContextAs()
105
    {
106
        // removes the $ sign.
107
        $this->widget->contextAs = str_replace('$', '', (string)$this->widget->contextAs);
108
    }
109
110
    /**
111
     * ّFigures out how long the cache life time should be.
112
     * @return null
113
     */
114
    private function normalizeCacheLifeTime()
115
    {
116
        if ($this->widget->cacheLifeTime === 'env_default') {
117
            $this->widget->cacheLifeTime = (int)(env('WIDGET_DEFAULT_CACHE_LIFETIME', 0));
0 ignored issues
show
Documentation Bug introduced by
The property $cacheLifeTime was declared of type string, but (int) env('WIDGET_DEFAULT_CACHE_LIFETIME', 0) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
118
        }
119
120
        if ($this->widget->cacheLifeTime === 'forever') {
121
            $this->widget->cacheLifeTime = -1;
0 ignored issues
show
Documentation Bug introduced by
The property $cacheLifeTime was declared of type string, but -1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
122
        }
123
124
    }
125
126
    /**
127
     * ّFigures out what the cache tags should be.
128
     * @return null
129
     */
130
    private function normalizeCacheTags()
131
    {
132
        if (!$this->cacheShouldBeTagged()) {
133
            return null;
134
        }
135
136
        if (is_string($this->widget->cacheTags)) {
137
            $this->widget->cacheTags = [$this->widget->cacheTags];
138
        }
139
140
        if (!is_array($this->widget->cacheTags)) {
141
            throw new \InvalidArgumentException('Cache Tags should be of type String or Array.');
142
        }
143
    }
144
    /**
145
     * Determine whether cache tags should be applied or not
146
     * @return bool
147
     */
148
    private function cacheShouldBeTagged()
149
    {
150
        return !in_array(env('CACHE_DRIVER', 'file'), ['file', 'database']) && $this->widget->cacheTags;
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->widget->cacheTags of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
151
    }
152
153
}