Passed
Push — master ( 62fbb4...6eecf2 )
by Akpé Aurelle Emmanuel Moïse
02:00
created

NamedArgs::getParamDefaultValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 3
rs 10
1
<?php
2
namespace EZAMA{
3
    class NamedArgs
4
    {
5
        protected $parameters=array();
6
        
7
        public function __construct($mandatory)
8
        {
9
            if (!\is_array($mandatory)) {
10
                throw new InvalidArgumentException(\sprintf('parameter type must be array, %s given', \gettype($mandatory)));
0 ignored issues
show
Bug introduced by
The type EZAMA\InvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
11
            }
12
            $this->parameters=$mandatory;
13
        }
14
        
15
        protected static function merge(&$arr1, &$arr2)
16
        {
17
            foreach ($arr1 as $k=>$v) {
18
                if (array_key_exists($k, $arr2)) {
19
                    $arr1[$k]=&$arr2[$k];
20
                }
21
            }
22
        }
23
        
24
        protected static function format($OneDarray)
25
        {
26
            if (!\is_array($OneDarray)) {
27
                return '';
28
            }
29
            if (\count($OneDarray)>1) {
30
                $end=array_pop($OneDarray);
31
                return \join(',', $OneDarray)." and $end ";
32
            } else {
33
                return array_pop($OneDarray);
34
            }
35
        }
36
        
37
        protected static function throwError($error)
38
        {
39
            $error=(string)($error);
40
            if (\version_compare(\PHP_VERSION, '7.0.0') < 0) {
41
                \trigger_error($error, \E_USER_ERROR);
42
            } else {
43
                throw new Error($error);
0 ignored issues
show
Bug introduced by
The type EZAMA\Error was not found. Did you mean Error? If so, make sure to prefix the type with \.
Loading history...
44
            }
45
        }
46
         
47
        
48
        protected static function &ProcessParams(&$argument, $required, $default)
49
        {
50
            $missing=array();
51
            if (!\is_array($argument)) {
52
                return \false;
53
            }
54
            $argument=array_intersect_key($argument, $default);//keep only predefined names
55
            //check for missing required parameters
56
            foreach ($required as $k=>$v) {
57
                if (!array_key_exists($v, $argument)) {
58
                    $missing[]=$v;
59
                }
60
            }
61
62
            if (!empty($missing)) {
63
                $function=\debug_backtrace();
64
                $function=\end($function);
65
                $function=$function['function'];
66
                $cm=\count($missing);
67
                $error=\call_user_func_array('sprintf', array('Function  %s\'s  Required '.(($cm>1)?'parameters ':'parameter ').'%s '.(($cm>1)?'are':'is').' missing',$function,NamedArgs::format($missing)));
68
                self::throwError($error);
69
            }
70
            
71
            
72
            self::merge($default, $argument);//assign given values to parameters while keeping references
73
            return $default;
74
        }
75
        
76
        public function &getParams($required, $default)
77
        {
78
            if (self::is_valid_associative($this->parameters)) {
79
                return self::ProcessParams($this->parameters, $required, $default);
80
            } else {
81
                $cp=\count($this->parameters);
82
                if ($cp>=\count($required)) {
83
                    foreach (array_keys($default) as $k=>$v) {
84
                        if ($k===$cp) {
85
                            break;
86
                        }
87
                        $default[$v]=&$this->parameters[$k];
88
                    }
89
                    return self::ProcessParams($default, $required, $default);
90
                } else {
91
                    $function=\debug_backtrace();
92
                    $function=\end($function);
93
                    $function=$function['function'];
94
95
                    self::throwError(\sprintf('Function  %s : Two few parameters supplied', $function));
96
                }
97
            }
98
        }
99
        
100
        protected static function is_valid_associative($array)
101
        {
102
            if (!\is_array($array)) {
103
                return \false;
104
            }
105
            foreach ($array as $k=>$v) {
106
                if (!\preg_match('#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#', (string)$k)) {
107
                    return \false;
108
                }
109
            }
110
            return \true;
111
        }
112
        
113
        public static function __callStatic($name, $mandatory)
114
        {
115
            if (empty($mandatory)) {
116
                $mandatory[0]=[];
117
            }
118
            
119
            if ($mandatory[0] instanceof NamedArgs) {
120
                return self::func($name, $mandatory[0]);
121
            } elseif (\is_array($mandatory[0])) {
122
                return self::func($name, new self($mandatory[0]));
123
            }
124
            return \false;
125
        }
126
        
127
        
128
        protected static function func($func, NamedArgs $mandatory)
129
        {
130
            $args=&$mandatory->parameters;
131
            return self::processParamsAndArgs($func, $args);
132
        }
133
        
134
        protected static function getReflection(&$func)
135
        {
136
            if (!\is_string($func)) {
137
                throw new BadFunctionCallException('Try to call undefined Function');
0 ignored issues
show
Bug introduced by
The type EZAMA\BadFunctionCallException was not found. Did you mean BadFunctionCallException? If so, make sure to prefix the type with \.
Loading history...
138
            }
139
            try {
140
                $func = new \reflectionFunction($func);
141
            } catch (ReflectionException $e) {
0 ignored issues
show
Bug introduced by
The type EZAMA\ReflectionException was not found. Did you mean ReflectionException? If so, make sure to prefix the type with \.
Loading history...
142
                throw new BadFunctionCallException('Try to call undefined Function');
143
            }
144
        }
145
        
146
        protected static function getValues(&$func, &$params, $paramsArgs, &$args, $associative)
147
        {
148
            foreach ((array)$params as $k=> $param) {
149
                $key=$associative?$param->name:$k;
150
                if (array_key_exists($key, $args)) {
151
                    $paramsArgs[]=&$args[$key];
152
                } else {
153
                    self::elseifGetValues($func, $param, $paramsArgs);
154
                }
155
            }
156
            return $paramsArgs;
157
        }
158
        
159
        protected static function handleOptional($notOptional, $func, $param)
160
        {
161
            if ($notOptional) {
162
                self::throwError(\sprintf('Function  %s\'s required parameter %s is missing', $func, $param));
163
            }
164
        }
165
        
166
        protected static function getParamDefaultValue(\reflectionParameter $param)
167
        {
168
            return $param->getDefaultValueConstantName()?\constant($param->getDefaultValueConstantName()):$param->getDefaultValue();
169
        }
170
        
171
        protected static function canGetParamDefaultValue(\reflectionFunction $func, \reflectionParameter $param)
172
        {
173
            return !$func->isInternal()&&($param->isDefaultValueAvailable()||$param->isDefaultValueConstant());
174
        }
175
        
176
        
177
        protected static function elseifGetValues(\reflectionFunction $func, \reflectionParameter $param, &$paramsArgs)
178
        {
179
            if (self::canGetParamDefaultValue($func, $param)) {
180
                $paramsArgs[] = self::getParamDefaultValue($param);
181
            } elseif ($param->allowsNull()) {
182
                $paramsArgs[]=null;
183
            } else {
184
                self::handleOptional(!$param->isOptional(), (string)$func->name, (string)$param->name);
185
            }
186
        }
187
188
        protected static function processParamsAndArgs($func, $args)
189
        {
190
            self::getReflection($func);
191
            $paramsArgs = array();
192
            $params =$func->getParameters();
193
            return $func->invokeArgs(self::getValues($func, $params, $paramsArgs, $args, self::is_valid_associative($args)));
194
        }
195
    }
196
197
}
198