Test Failed
Push — master ( 40c64c...4518ff )
by Dimas
09:34
created

helper   B

Complexity

Total Complexity 48

Size/Duplication

Total Lines 284
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 96
dl 0
loc 284
rs 8.5599
c 0
b 0
f 0
wmc 48

16 Methods

Rating   Name   Duplication   Size   Complexity  
A domain() 0 3 1
A __call() 0 24 4
A secure() 0 3 1
A get_current_url() 0 17 4
A has() 0 11 4
B set() 0 32 10
A hours() 0 3 1
A all() 0 3 1
A destroy() 0 18 6
A del() 0 12 2
A get_current_path() 0 5 2
A mins() 0 3 1
A one() 0 6 3
A reconstruct_url() 0 6 2
A get() 0 15 5
A day() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like helper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use helper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Cookie;
4
5
/**
6
 * Cookie helper.
7
 */
8
class helper
9
{
10
  public static $domain = '/';
11
  public static $secure = false;
12
13
  public static function secure(bool $secure)
14
  {
15
    self::$secure = $secure;
16
  }
17
18
  public static function domain(string $domain)
19
  {
20
    self::$domain = $domain;
21
  }
22
23
  /** This magic method is called everytime an inaccessible method is called
24
   * (either by visibility contrains or it doesn't exist)
25
   * Here we are simulating shared protected methods across "package" classes
26
   * This method is inherited by all child classes of Package.
27
   */
28
  public function __call($method, $args)
29
  {
30
    //class name
31
    $class = get_class($this);
32
33
    /* we check if a method exists, if not we throw an exception
34
     * similar to the default error
35
     */
36
    if (method_exists($this, $method)) {
37
      /** The method exists so now we want to know if the
38
       * caller is a child of our Package class. If not we throw an exception
39
       * Note: This is a kind of a dirty way of finding out who's
40
       * calling the method by using debug_backtrace and reflection.
41
       */
42
      $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
43
      if (isset($trace[2])) {
44
        $ref = new \ReflectionClass($trace[2]['class']);
45
        if ($ref->isSubclassOf(__CLASS__)) {
46
          return $this->$method($args);
47
        }
48
      }
49
      throw new \Exception("Call to private method $class::$method()");
50
    } else {
51
      throw new \Exception("Call to undefined method $class::$method()");
52
    }
53
  }
54
55
  /**
56
   * Set cookie helper.
57
   *
58
   * @param string    $name
59
   * @param mixed     $value
60
   * @param int|float|string $expire 1m/1h/1d/1y
61
   * @param string    $path
62
   * @param string    $domain   default $_SERVER['HTTP_HOST']
63
   * @param bool      $secure
64
   * @param bool      $httponly
65
   *
66
   * @return setcookie
0 ignored issues
show
Bug introduced by
The type Cookie\setcookie was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
67
   */
68
  public static function set(string $name, $value, $expire, string $path = '/', $domain = '', $secure = false, $httponly = false)
69
  {
70
    if (empty($domain)) {
71
      $domain = $_SERVER['HTTP_HOST'];
72
    }
73
    if (empty($path)) {
74
      $path = '/';
75
    }
76
77
    if (is_string($expire)) {
78
      if (endsWith($expire, "h")) {
79
        $expire = time() + (toNumber($expire) * 3600);
80
      } else if (endsWith($expire, "d")) {
81
        $expire = time() + (toNumber($expire) * 86400);
82
      } else if (endsWith($expire, "m")) {
83
        $expire = time() + (toNumber($expire) * 60);
84
      } else if (endsWith($expire, "y")) {
85
        $expire = time() + (toNumber($expire) * 31556926); // where 31556926 is total seconds for a year.
86
      }
87
    }
88
89
    try {
90
      //$value = gzdeflate(json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), 9);
91
      $value = base64_encode(json_encode($value));
92
    } catch (\MVC\Exception $E) {
93
      $value = $value;
94
    }
95
96
    if (!setcookie($name, $value, $expire, $path, $domain, $secure, $httponly)) {
0 ignored issues
show
Bug introduced by
It seems like $expire can also be of type double and string; however, parameter $expire of setcookie() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

96
    if (!setcookie($name, $value, /** @scrutinizer ignore-type */ $expire, $path, $domain, $secure, $httponly)) {
Loading history...
97
      return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type Cookie\setcookie.
Loading history...
98
    } else {
99
      return true;
0 ignored issues
show
Bug Best Practice introduced by
The expression return true returns the type true which is incompatible with the documented return type Cookie\setcookie.
Loading history...
100
    }
101
  }
102
103
  /**
104
   * Get Cookie By Name.
105
   *
106
   * @param string cookie value
0 ignored issues
show
Bug introduced by
The type Cookie\cookie was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
107
   * * if value is json, auto convert them into Array
108
   * @return null|string|array
109
   */
110
  public static function get(string $name, bool $AllowEmpty = true)
111
  {
112
    $ret = null;
113
    if (isset($_COOKIE[$name])) {
114
      $ret = $_COOKIE[$name];
115
    }
116
    if ($ret) {
117
      //$ret = json_decode(gzinflate($ret), true);
118
      $ret = json_decode(base64_decode($ret), true);
119
    }
120
    if (!$AllowEmpty && empty($ret)) {
121
      $ret = null;
122
    }
123
124
    return $ret;
125
  }
126
127
  /**
128
   * Destroy all cookies except php session and spesific cookies name.
129
   *
130
   * @param array $except
131
   *
132
   * @return void
133
   */
134
  public static function destroy(array $except = [])
135
  {
136
    if (isset($_SERVER['HTTP_COOKIE'])) {
137
      $cookies = explode(';', $_SERVER['HTTP_COOKIE']);
138
      $i = 0;
139
      foreach ($cookies as $cookie) {
140
        ++$i;
141
        $parts = explode('=', $cookie);
142
        $name = trim($parts[0]);
143
        //var_dump($name);
144
        if (preg_match('/PHPSESSID/s', $name) || in_array($name, $except)) {
145
          continue;
146
        }
147
        setcookie($name, '', time() - 1000);
148
        setcookie($name, '', time() - 1000, '/');
149
        setcookie($name, '', time() - 1000, self::get_current_path());
150
        if (20 == $i) {
151
          break;
152
        }
153
      }
154
    }
155
  }
156
157
  public static function all()
158
  {
159
    return $_COOKIE;
160
  }
161
162
  public static function get_current_url()
163
  {
164
    $pageURL = 'http';
165
    if (isset($_SERVER['HTTPS']) && 'on' == $_SERVER['HTTPS']) {
166
      $pageURL .= 's';
167
    }
168
    $pageURL .= '://';
169
    if ('80' != $_SERVER['SERVER_PORT']) {
170
      $pageURL .= $_SERVER['SERVER_NAME']
171
        . ':'
172
        . $_SERVER['SERVER_PORT']
173
        . $_SERVER['REQUEST_URI'];
174
    } else {
175
      $pageURL .= $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
176
    }
177
178
    return $pageURL;
179
  }
180
181
  public static function get_current_path()
182
  {
183
    $url_parts = \MVC\helper::parse_url2(self::get_current_url());
184
185
    return isset($url_parts['path']) ? $url_parts['path'] : '';
186
  }
187
188
  public static function reconstruct_url(string $url)
189
  {
190
    $url_parts = \MVC\helper::parse_url2($url);
191
    $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['path']) ? $url_parts['path'] : '');
192
193
    return $constructed_url;
194
  }
195
196
  /**
197
   * Set cookie by days.
198
   *
199
   * @see \Cookie\helper::set() automatically set expire time to day format
200
   */
201
  public static function day(string $name, $value = true, int $expire, string $path = '/', $domain = '', $secure = false, $httponly = false)
202
  {
203
    return self::set($name, $value, time() + 60 * 60 * 24 * $expire, $path, $domain, $secure, $httponly);
204
  }
205
206
  /**
207
   * Set cookie by minutes.
208
   *
209
   * @see \Cookie\helper::set() automatically set expire time to minutes format
210
   */
211
  public static function mins(string $name, $value = true, int $expire, string $path = '/', $domain = '', $secure = false, $httponly = false)
212
  {
213
    return self::set($name, $value, time() + (60 * $expire), $path, $domain, $secure, $httponly);
214
  }
215
216
  /**
217
   * Set cookie by hours.
218
   *
219
   * @see \Cookie\helper::set() automatically set expire time to hours format
220
   */
221
  public static function hours(string $name, $value = true, int $expire = 1, string $path = '/', $domain = '', $secure = false, $httponly = false)
222
  {
223
    return self::set($name, $value, time() + (60 * 60 * $expire), $path, $domain, $secure, $httponly);
224
  }
225
226
  /**
227
   * Check cookie exist.
228
   *
229
   * @param string $name
230
   * @param bool   $AllowEmpty if true, will return false if cookie value empty
231
   *
232
   * @return boolean|null
233
   *                      `true` indicated exists,
234
   *                      `null` indicated empty value,
235
   *                      `false` indicated not set
236
   */
237
  public static function has(string $name, bool $AllowEmpty = true)
238
  {
239
    $ret = false;
240
    if (isset($_COOKIE[$name])) {
241
      $ret = true;
242
    }
243
    if ((true !== $AllowEmpty) && empty($ret)) {
244
      $ret = null;
245
    }
246
247
    return $ret;
248
  }
249
250
  /**
251
   * one time function when cookie name empty.
252
   *
253
   * @param string   $cookie_name
254
   * @param string   $value
255
   * @param int      $minutes     minute to be expired
256
   * @param callable $callback
257
   *
258
   * @return void
259
   */
260
  public static function one(string $cookie_name, string $value, int $minutes, callable $callback)
261
  {
262
    if (!self::has($cookie_name)) {
263
      if (is_callable($callback)) {
264
        call_user_func($callback, $cookie_name, $minutes);
265
        self::mins($cookie_name, $value, $minutes);
266
      }
267
    }
268
  }
269
270
  /**
271
   * Delete cookie.
272
   *
273
   * @param string $name
274
   *
275
   * @return bool true | false | null
276
   *              * return true if success and exists
277
   *              * return false if cookie not exists
278
   *              * return null if $_COOKIE constant not exists
279
   */
280
  public static function del(string $name)
281
  {
282
    if (isset($_COOKIE[$name])) {
283
      unset($_COOKIE[$name]);
284
      setcookie($name, null, -1, '/');
285
286
      return true;
287
    } else {
288
      return false;
289
    }
290
291
    return null;
0 ignored issues
show
Unused Code introduced by
return null is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
292
  }
293
}
294