Completed
Push — master ( b62689...86c921 )
by Lars
06:47 queued 39s
created

StaticArrayy   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 99
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Test Coverage

Coverage 87.1%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 14
c 1
b 0
f 0
lcom 0
cbo 1
dl 0
loc 99
ccs 27
cts 31
cp 0.871
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A repeat() 0 9 2
B __callStatic() 0 28 6
B range() 0 19 6
1
<?php
2
3
namespace Arrayy;
4
5
/**
6
 * Class StaticArrayy
7
 *
8
 * INFO: "Method Parameter Information" via PhpStorm |
9
 * https://www.jetbrains.com/phpstorm/help/viewing-method-parameter-information.html
10
 *
11
 */
12
class StaticArrayy
13
{
14
  /**
15
   * A mapping of method names to the numbers of arguments it accepts. Each
16
   * should be two more than the equivalent Arrayy method. Necessary as
17
   * static methods place the optional $encoding as the last parameter.
18
   *
19
   * @var string[]
20
   */
21
  protected static $methodArgs = null;
22
23
  /**
24
   * Creates an instance of Arrayy and invokes the given method
25
   *
26
   * @param string  $name
27
   * @param mixed[] $arguments
28
   *
29
   * @return Arrayy
30
   */
31 5
  public static function __callStatic($name, $arguments)
32
  {
33 5
    if (!static::$methodArgs) {
0 ignored issues
show
Bug Best Practice introduced by
The expression static::$methodArgs 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...
34 1
      $arrayyClass = new \ReflectionClass('Arrayy\Arrayy');
35 1
      $methods = $arrayyClass->getMethods(\ReflectionMethod::IS_PUBLIC);
36
37 1
      foreach ($methods as $method) {
38 1
        $params = $method->getNumberOfParameters() + 2;
39 1
        static::$methodArgs[$method->name] = $params;
40
      }
41
    }
42
43 5
    if (!isset(static::$methodArgs[$name])) {
44 1
      throw new \BadMethodCallException($name . ' is not a valid method');
45
    }
46
47 4
    $numArgs = count($arguments);
48 4
    $array = $numArgs ? $arguments[0] : '';
49
50 4
    if ($numArgs === static::$methodArgs[$name]) {
51
      $args = array_slice($arguments, 1, -1);
52
    } else {
53 4
      $args = array_slice($arguments, 1);
54
    }
55
56 4
    $arrayy = Arrayy::create($array);
57 4
    return call_user_func_array(array($arrayy, $name), $args);
58
  }
59
60
  ////////////////////////////////////////////////////////////////////
61
  ///////////////////////////// GENERATE /////////////////////////////
62
  ////////////////////////////////////////////////////////////////////
63
64
  /**
65
   * Generate an array from a range.
66
   *
67
   * @param int      $base The base number
68
   * @param int|null $stop The stopping point
69
   * @param int      $step How many to increment of
70
   *
71
   * @return Arrayy
72
   */
73 4
  public static function range($base, $stop = null, $step = 1)
74
  {
75 4
    if (!is_int($base) || !is_int($step)) {
76
      throw new \InvalidArgumentException('Passed value must be a int');
77
    }
78
79 4
    if (!is_int($stop) && null !== $stop) {
80
      throw new \InvalidArgumentException('Passed value must be a int or nul');
81
    }
82
83 4
    if (null !== $stop) {
84 2
      $start = $base;
85
    } else {
86 2
      $start = 1;
87 2
      $stop = $base;
88
    }
89
90 4
    return Arrayy::create(range($start, $stop, $step));
91
  }
92
93
  /**
94
   * Fill an array with $times times some $data.
95
   *
96
   * @param mixed $data
97
   * @param int   $times
98
   *
99
   * @return Arrayy
100
   */
101 3
  public static function repeat($data, $times)
102
  {
103 3
    $times = abs($times);
104 3
    if ($times === 0) {
105
      return array();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return array(); (array) is incompatible with the return type documented by Arrayy\StaticArrayy::repeat of type Arrayy\Arrayy.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
106
    }
107
108 3
    return Arrayy::create(array_fill(0, $times, $data));
109
  }
110
}
111