Completed
Push — master ( 8f2afd...b38d46 )
by Arjay
01:46
created

Helper::isItemOrderInvalid()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Yajra\Datatables;
4
5
use DateTime;
6
use Illuminate\Contracts\Support\Arrayable;
7
use Illuminate\Support\Str;
8
9
/**
10
 * Class Helper.
11
 *
12
 * @package Yajra\Datatables
13
 * @author  Arjay Angeles <[email protected]>
14
 */
15
class Helper
16
{
17
    /**
18
     * Places item of extra columns into results by care of their order.
19
     *
20
     * @param array $item
21
     * @param array $array
22
     * @return array
23
     */
24
    public static function includeInArray($item, $array)
25
    {
26
        if (self::isItemOrderInvalid($item, $array)) {
27
            return array_merge($array, [$item['name'] => $item['content']]);
28
        } else {
29
            $count = 0;
30
            $last  = $array;
31
            $first = [];
32
            foreach ($array as $key => $value) {
33
                if ($count == $item['order']) {
34
                    return array_merge($first, [$item['name'] => $item['content']], $last);
35
                }
36
37
                unset($last[$key]);
38
                $first[$key] = $value;
39
40
                $count++;
41
            }
42
        }
43
    }
44
45
    /**
46
     * Check if item order is valid.
47
     *
48
     * @param array $item
49
     * @param array $array
50
     * @return bool
51
     */
52
    protected static function isItemOrderInvalid($item, $array)
53
    {
54
        return $item['order'] === false || $item['order'] >= count($array);
55
    }
56
57
    /**
58
     * Determines if content is callable or blade string, processes and returns.
59
     *
60
     * @param string|callable $content Pre-processed content
61
     * @param array           $data data to use with blade template
62
     * @param mixed           $param parameter to call with callable
63
     * @return string Processed content
64
     */
65
    public static function compileContent($content, array $data, $param)
66
    {
67
        if (is_string($content)) {
68
            return static::compileBlade($content, static::getMixedValue($data, $param));
0 ignored issues
show
Bug Compatibility introduced by
The expression static::compileBlade($co...dValue($data, $param)); of type Illuminate\View\View|Ill...cts\View\Factory|string adds the type Illuminate\Contracts\View\Factory to the return on line 68 which is incompatible with the return type documented by Yajra\Datatables\Helper::compileContent of type string.
Loading history...
69
        } elseif (is_callable($content)) {
70
            return $content($param);
71
        }
72
73
        return $content;
74
    }
75
76
    /**
77
     * Parses and compiles strings by using Blade Template System.
78
     *
79
     * @param string $str
80
     * @param array  $data
81
     * @return mixed
82
     * @throws \Exception
83
     */
84
    public static function compileBlade($str, $data = [])
85
    {
86
        if (view()->exists($str)) {
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...
87
            return view($str, $data);
88
        }
89
90
        ob_start() && extract($data, EXTR_SKIP);
91
        eval('?>' . resolve('blade.compiler')->compileString($str));
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
92
        $str = ob_get_contents();
93
        ob_end_clean();
94
95
        return $str;
96
    }
97
98
    /**
99
     * Get a mixed value of custom data and the parameters.
100
     *
101
     * @param  array $data
102
     * @param  mixed $param
103
     * @return array
104
     */
105
    public static function getMixedValue(array $data, $param)
106
    {
107
        $casted = self::castToArray($param);
108
109
        $data['model'] = $param;
110
111
        foreach ($data as $key => $value) {
112
            if (isset($casted[$key])) {
113
                $data[$key] = $casted[$key];
114
            }
115
        }
116
117
        return $data;
118
    }
119
120
    /**
121
     * Cast the parameter into an array.
122
     *
123
     * @param mixed $param
124
     * @return array
125
     */
126
    public static function castToArray($param)
127
    {
128
        if ($param instanceof \stdClass) {
129
            $param = (array) $param;
130
131
            return $param;
132
        }
133
134
        if ($param instanceof Arrayable) {
135
            return $param->toArray();
136
        }
137
138
        return $param;
139
    }
140
141
    /**
142
     * Get equivalent or method of query builder.
143
     *
144
     * @param string $method
145
     * @return string
146
     */
147
    public static function getOrMethod($method)
148
    {
149
        if (!Str::contains(Str::lower($method), 'or')) {
150
            return 'or' . ucfirst($method);
151
        }
152
153
        return $method;
154
    }
155
156
    /**
157
     * Converts array object values to associative array.
158
     *
159
     * @param mixed $row
160
     * @return array
161
     */
162
    public static function convertToArray($row)
163
    {
164
        $data = $row instanceof Arrayable ? $row->toArray() : (array) $row;
165
        foreach (array_keys($data) as $key) {
166
            if (is_object($data[$key]) || is_array($data[$key])) {
167
                $data[$key] = self::convertToArray($data[$key]);
168
            }
169
        }
170
171
        return $data;
172
    }
173
174
    /**
175
     * @param array $data
176
     * @return array
177
     */
178
    public static function transform(array $data)
179
    {
180
        return array_map(function ($row) {
181
            return self::transformRow($row);
182
        }, $data);
183
    }
184
185
    /**
186
     * Transform row data into an array.
187
     *
188
     * @param mixed $row
189
     * @return array
190
     */
191
    protected static function transformRow($row)
192
    {
193
        foreach ($row as $key => $value) {
194
            if ($value instanceof DateTime) {
195
                $row[$key] = $value->format('Y-m-d H:i:s');
196
            } else {
197
                if (is_object($value)) {
198
                    $row[$key] = (string) $value;
199
                } else {
200
                    $row[$key] = $value;
201
                }
202
            }
203
        }
204
205
        return $row;
206
    }
207
208
    /**
209
     * Build parameters depending on # of arguments passed.
210
     *
211
     * @param array $args
212
     * @return array
213
     */
214
    public static function buildParameters(array $args)
215
    {
216
        $parameters = [];
217
218
        if (count($args) > 2) {
219
            $parameters[] = $args[0];
220
            foreach ($args[1] as $param) {
221
                $parameters[] = $param;
222
            }
223
        } else {
224
            foreach ($args[0] as $param) {
225
                $parameters[] = $param;
226
            }
227
        }
228
229
        return $parameters;
230
    }
231
232
    /**
233
     * Replace all pattern occurrences with keyword
234
     *
235
     * @param array  $subject
236
     * @param string $keyword
237
     * @param string $pattern
238
     * @return array
239
     */
240
    public static function replacePatternWithKeyword(array $subject, $keyword, $pattern = '$1')
241
    {
242
        $parameters = [];
243
        foreach ($subject as $param) {
244
            if (is_array($param)) {
245
                $parameters[] = self::replacePatternWithKeyword($param, $keyword, $pattern);
246
            } else {
247
                $parameters[] = str_replace($pattern, $keyword, $param);
248
            }
249
        }
250
251
        return $parameters;
252
    }
253
254
    /**
255
     * Get column name from string.
256
     *
257
     * @param string $str
258
     * @param bool   $wantsAlias
259
     * @return string
260
     */
261
    public static function extractColumnName($str, $wantsAlias)
262
    {
263
        $matches = explode(' as ', Str::lower($str));
264
265
        if (!empty($matches)) {
266
            if ($wantsAlias) {
267
                return array_pop($matches);
268
            } else {
269
                return array_shift($matches);
270
            }
271
        } elseif (strpos($str, '.')) {
272
            $array = explode('.', $str);
273
274
            return array_pop($array);
275
        }
276
277
        return $str;
278
    }
279
280
    /**
281
     * Adds % wildcards to the given string.
282
     *
283
     * @param string $str
284
     * @param bool   $lowercase
285
     * @return string
286
     */
287
    public static function wildcardLikeString($str, $lowercase = true)
288
    {
289
        $wild  = '%';
290
        $chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
291
292
        if (count($chars) > 0) {
293
            foreach ($chars as $char) {
294
                $wild .= $char . '%';
295
            }
296
        }
297
298
        if ($lowercase) {
299
            $wild = Str::lower($wild);
300
        }
301
302
        return $wild;
303
    }
304
}
305