Completed
Push — develop ( 8bd0dd...97bd6f )
by Stuart
06:10
created

IsCompatibleWith::checkString()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 7
nc 4
nop 2
dl 0
loc 15
rs 9.4285
c 1
b 0
f 1
1
<?php
2
3
/**
4
 * Copyright (c) 2016-present Ganbaro Digital Ltd
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 *
11
 *   * Redistributions of source code must retain the above copyright
12
 *     notice, this list of conditions and the following disclaimer.
13
 *
14
 *   * Redistributions in binary form must reproduce the above copyright
15
 *     notice, this list of conditions and the following disclaimer in
16
 *     the documentation and/or other materials provided with the
17
 *     distribution.
18
 *
19
 *   * Neither the names of the copyright holders nor the names of his
20
 *     contributors may be used to endorse or promote products derived
21
 *     from this software without specific prior written permission.
22
 *
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 *
36
 * @category  Libraries
37
 * @package   MissingBits/TypeChecks
38
 * @author    Stuart Herbert <[email protected]>
39
 * @copyright 2016-present Ganbaro Digital Ltd www.ganbarodigital.com
40
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
41
 * @link      http://ganbarodigital.github.io/php-the-missing-bits
42
 */
43
44
namespace GanbaroDigital\MissingBits\TypeChecks;
45
46
use GanbaroDigital\MissingBits\Checks\Check;
47
use GanbaroDigital\MissingBits\Checks\ListCheck;
48
use GanbaroDigital\MissingBits\Checks\ListCheckHelper;
49
use GanbaroDigital\MissingBits\TypeInspectors\GetClassTypes;
50
use GanbaroDigital\MissingBits\TypeInspectors\GetPrintableType;
51
use InvalidArgumentException;
52
53
/**
54
 * is class or object compatible with a given type?
55
 */
56
class IsCompatibleWith implements Check, ListCheck
57
{
58
    // saves us having to implement inspectList() ourselves
59
    use ListCheckHelper;
60
61
    /**
62
     * the classname or object that we want to check for
63
     * @var string|object
64
     */
65
    private $expectedType;
66
67
    /**
68
     * our constructor
69
     *
70
     * @param  string|object $expectedType
71
     *         the classname or object that we want to check for
72
     */
73
    public function __construct($expectedType)
74
    {
75
        $this->expectedType = $expectedType;
76
    }
77
78
    /**
79
     * is $fieldOrVar compatible with $expectedType?
80
     *
81
     * @param  mixed $fieldOrVar
82
     *         the classname or object to check
83
     * @param  string|object $expectedType
84
     *         the classname or object that we want to check for
85
     * @return bool
86
     *         TRUE if $fieldOrVar is compatible
87
     *         FALSE otherwise
88
     */
89
    public static function check($fieldOrVar, $expectedType)
90
    {
91
        // robustness
92
        if (!IsStringy::check($expectedType) && !is_object($expectedType)) {
93
            throw new InvalidArgumentException("\$expectedType must be a classname or an object, is a " . GetPrintableType::of($expectedType));
94
        }
95
96
        if (is_object($fieldOrVar)) {
97
            return self::checkObject($fieldOrVar, $expectedType);
98
        }
99
        else if (is_string($fieldOrVar)) {
100
            return self::checkString($fieldOrVar, $expectedType);
101
        }
102
        else {
103
            return false;
104
        }
105
    }
106
107
    /**
108
     * is $fieldOrVar compatible with $expectedType?
109
     *
110
     * @param  object $fieldOrVar
111
     *         the object to check
112
     * @param  string|object $expectedType
113
     *         the class or object that $fieldOrVar must be compatible with
114
     * @return bool
115
     *         TRUE if $fieldOrVar is compatible
116
     *         FALSE otherwise
117
     */
118
    private static function checkObject($fieldOrVar, $expectedType)
119
    {
120
        // this is the easiest test case of all :)
121
        return $fieldOrVar instanceof $expectedType;
122
    }
123
124
    /**
125
     * is $fieldOrVar compatible with $expectedType?
126
     *
127
     * @param  string $fieldOrVar
128
     *         the class name to check
129
     * @param  string|object $expectedType
130
     *         the class or object that $fieldOrVar must be compatible with
131
     * @return bool
132
     *         TRUE if $fieldOrVar is compatible
133
     *         FALSE otherwise
134
     */
135
    private static function checkString($fieldOrVar, $expectedType)
136
    {
137
        $compatibleTypes = GetClassTypes::from($fieldOrVar);
138
        if (is_object($expectedType)) {
139
            $expectedType = get_class($expectedType);
140
        }
141
142
        // is our expectedType in the list of data types that $fieldOrVar can be?
143
        if (isset($compatibleTypes[$expectedType])) {
144
            return true;
145
        }
146
147
        // if we get here, we have run out of ideas
148
        return false;
149
    }
150
151
    /**
152
     * is $fieldOrVar compatible with $expectedType?
153
     *
154
     * @param  mixed $fieldOrVar
155
     *         the classname or object to check
156
     * @return bool
157
     *         TRUE if $fieldOrVar is compatible
158
     *         FALSE otherwise
159
     */
160
    public function inspect($fieldOrVar)
161
    {
162
        return static::check($fieldOrVar, $this->expectedType);
163
    }
164
165
    /**
166
     * is every entry in $list compatible with $expectedType?
167
     *
168
     * @param  mixed $list
169
     *         the list of items to be checked
170
     * @param  string $expectedType
171
     *         the class or interface that we want to check against
172
     * @return bool
173
     *         TRUE if every item in $list is a classname or object of
174
     *         a given type
175
     *         FALSE otherwise
176
     */
177
    public static function checkList($list, $expectedType)
178
    {
179
        $check = new static;
0 ignored issues
show
Bug introduced by
The call to IsCompatibleWith::__construct() misses a required argument $expectedType.

This check looks for function calls that miss required arguments.

Loading history...
180
        return $check->inspectList($list, $expectedType);
0 ignored issues
show
Unused Code introduced by
The call to IsCompatibleWith::inspectList() has too many arguments starting with $expectedType.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
181
    }
182
}
183