Completed
Pull Request — master (#3)
by Akpé Aurelle Emmanuel Moïse
01:39
created

Shortcut::GetTheRightExceptionMessage()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 5
nc 3
nop 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
namespace EZAMA
3
4
/**
5
*
6
* @Name : Shortcut
7
* @Version : 1.0.0
8
* @Programmer : Akpé Aurelle Emmanuel Moïse Zinsou
9
* @Date : 2019-04-01
10
* @Released under : https://github.com/manuwhat/Shortcut/blob/master/LICENSE
11
* @Repository : https://github.com/manuwhat/Shortcut
12
*
13
**/
14
{
15
16
    class Shortcut
17
    {
18
       
19
20
21
    	const VALID_PHP_FUNCTION_NAME_PATTERN = '#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#';
22
        const CAN_NEVER_EVER_CHOOSE_THIS_AS_FUNCTION_NAME= "new";
23
        const PLACEHOLDER_FOR_INTERNALS_CLASSES_OPTIONALS_PARAMETERS ="This is internal and thus sucks we must do something ClassShortcutDesigner";
24
        private static $DIR=null;
25
        
26
        public static function create($classname, $name=self::CAN_NEVER_EVER_CHOOSE_THIS_AS_FUNCTION_NAME)
27
        {
28
            if (is_string($classname)&&class_exists($classname, true)) {
29
                $reflectionClass=new \reflectionClass($classname);
30
                $classname=$reflectionClass->getName();
31
                $fullQualifiedClassname=str_replace('\\', '_', $classname);
32
                if ($Dir=self::$DIR) {
33
                    $file=self::$DIR.DIRECTORY_SEPARATOR.$fullQualifiedClassname.".Shortcut.php";
34
                } else {
35
                    $Dir=dirname(__DIR__).DIRECTORY_SEPARATOR.'ClassShortcuts';
36
                    $file=$Dir.DIRECTORY_SEPARATOR.$fullQualifiedClassname.".Shortcut.php";
37
                }
38
                $fileExists=file_exists($file);
39
                if (!function_exists($classname)&&!function_exists($name)) {
40
                    if (!$fileExists) {
41
                        $name=trim($name);
42
                        if (!file_exists($Dir)) {
43
                            mkdir($Dir);
44
                        }
45
                        $reflectionMethod=$reflectionClass->getConstructor();
46
                        $notInstantiable=false;
47
                        if (is_null($reflectionMethod)||$notInstantiable=!$reflectionClass->isInstantiable()) {
48
                            if ($notInstantiable) {
49
                                throw new \InvalidArgumentException('Not Instantiable class '.$fullQualifiedClassname.' passed as Argument');
50
                            } else {
51
                                self::useTheRightName($Shortcut, $name, $fullQualifiedClassname, '');
52
                                
53
                                $Shortcut.="return new $classname();
54
                                        }";
55
                                return self::pushAndShow($file, $Shortcut);
56
                            }
57
                        }
58
                        self::getSignature($reflectionMethod, $signature, $parameters, $paramsNum, $count);
59
                        
60
                        $hasInternal='';
61
                        if ($count) {
62
                            self::BuildTheSwitch($hasInternal, $count, $paramsNum, $parameters, $classname);
63
                        }
64
                        self::useTheRightName($Shortcut, $name, $fullQualifiedClassname, $signature);
65
                        
66
                        self::handleInternals($Shortcut, $hasInternal, $parameters, $signature, $classname);
67
                            
68
                        return self::pushAndShow($file, $Shortcut);
69
                    } else {
70
                        return include_once($file);
71
                    }
72
                } else {
73
                    GetTheRightExceptionMessage($fileExists,$name,$fullQualifiedClassname);
0 ignored issues
show
Bug introduced by
The function GetTheRightExceptionMessage was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

73
                    /** @scrutinizer ignore-call */ GetTheRightExceptionMessage($fileExists,$name,$fullQualifiedClassname);
Loading history...
74
                }
75
            }
76
        }
77
78
        private static function getSignature(\ReflectionMethod $method, &$signature, &$parameters, &$paramsNum, &$count)
79
        {
80
            $params=$method->getParameters();
81
            $paramsNum=count($params);
82
            $signature='';
83
            $parameters=array();
84
            $count=0;
85
            foreach ($params as $k=>$param) {
86
                if ($param->isPassedByReference()) {
87
                    $tmp='&$'.$param->getName();
88
                } else {
89
                    $tmp='$'.$param->getName();
90
                }
91
92
                if ($param->isOptional()) {
93
                    $count++;
94
                    if ($method->isInternal()) {
95
                        $tmp.='="This is internal and thus sucks we must do something ClassShortcutDesigner"';
96
                    } elseif ($param->isDefaultValueConstant()) {
97
                        $tmp.='='.$param->getDefaultValueConstantName();
98
                    } elseif ($param->isDefaultValueAvailable()) {
99
                        $tmp.='='.var_export($param->getDefaultValue(), true);
100
                    } elseif ($param->allowsNull()) {
101
                        $tmp.='=null';
102
                    }
103
                }
104
                
105
                $signature.=$tmp;
106
                $parameters[]='$'.$param->getName();
107
                $tmp='';
108
                if ($k<$paramsNum-1) {
109
                    $signature.=',';
110
                }
111
            }
112
        }
113
        private static function BuildTheSwitch(&$hasInternal, $count, $paramsNum, $parameters, $classname)
114
        {
115
            $hasInternal.='switch($count){';
116
            while ($count>0) {
117
                $hasInternal.="case $count:return new $classname(".join(',', array_slice($parameters, 0, $paramsNum-$count))."); break;";
118
                $count--;
119
            }
120
            $hasInternal.='default:return new '. $classname.'('.join(',', $parameters).');break;}';
121
        }
122
        
123
        private static function useTheRightName(&$Shortcut, $name, $fullQualifiedClassname, $signature)
124
        {
125
            if (strtolower($name)!=='new'&&preg_match(self::VALID_PHP_FUNCTION_NAME_PATTERN, $name)) {
126
                $Shortcut="<?php
127
							function $name($signature){";
128
            } else {
129
                $Shortcut="<?php
130
							function $fullQualifiedClassname($signature){";
131
            }
132
        }
133
        
134
        private static function handleInternals(&$Shortcut, $hasInternal, $parameters, $signature, $classname)
135
        {
136
            if (!strpos($signature, "This is internal and thus sucks we must do something ClassShortcutDesigner")) {
137
                $Shortcut.="return new $classname(".join(',', $parameters).");
138
							}";
139
            } else {
140
                $Shortcut.='
141
							$count=count(array_keys(get_defined_vars(),"'.self::PLACEHOLDER_FOR_INTERNALS_CLASSES_OPTIONALS_PARAMETERS.'"));
142
							'.$hasInternal.'
143
							}';
144
            }
145
        }
146
        
147
        private static function pushAndShow($file, $Shortcut)
148
        {
149
            file_put_contents($file, str_replace("\t", '    ', $Shortcut));
150
            file_put_contents($file, php_strip_whitespace($file));//just for cleanliness of the generated code
151
            return include_once($file);
152
        }
153
		
154
		private static function GetTheRightExceptionMessage($fileExists,$name,$fullQualifiedClassname){
0 ignored issues
show
Unused Code introduced by
The method GetTheRightExceptionMessage() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
155
			if (!$fileExists) {
156
				if (strtolower($name)!=='new'&&preg_match(self::VALID_PHP_FUNCTION_NAME_PATTERN, $name)) {
157
					throw new \InvalidArgumentException('function '.$name.' passed as second Argument already exists.
158
					Can\'t create a shortcut with the same name');
159
				} else {
160
					throw new \InvalidArgumentException('function '.$fullQualifiedClassname.' already exists and An alias has not been provided as Argument 2.
161
					Can\'t create a shortcut function with this name');
162
				}
163
			}
164
		}
165
        
166
        public static function setDir($dirname)
167
        {
168
            if (is_dir($dirname)&&is_writable($dirname)&&!self::$DIR) {
169
                self::$DIR=$dirname;
170
            }
171
        }
172
		
173
        
174
        private function __construct()
175
        {
176
        }
177
    }
178
}
179
180
namespace{
181
    function create_Shortcut($classname, $name='new')
182
    {
183
        return EZAMA\Shortcut::create($classname, $name);
184
    }
185
}
186