Passed
Push — master ( 4adf6f...6cecae )
by Akpé Aurelle Emmanuel Moïse
39s
created

Shortcut::BuildCacheAndShow()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 6
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
namespace EZAMA
3
4
/**
5
*
6
* @Name : Shortcut
7
* @Programmer : Akpé Aurelle Emmanuel Moïse Zinsou
8
* @Date : 2019-04-01
9
* @Released under : https://github.com/manuwhat/Shortcut/blob/master/LICENSE
10
* @Repository : https://github.com/manuwhat/Shortcut
11
*
12
**/
13
{
14
    
15
16
    class Shortcut extends shortcutQueryBuilder
17
    {
18
        const VALID_PHP_FUNCTION_NAME_PATTERN='#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$#';
19
        const CAN_NEVER_EVER_CHOOSE_THIS_AS_FUNCTION_NAME="new";
20
        const PLACEHOLDER_FOR_INTERNALS_CLASSES_OPTIONALS_PARAMETERS="acce91966cd8eee995ee1ac30c98c3d89d8f9235";
21
        private static $DIR=null;
22
        private static $SHORTCUT_FOR_ALL=false;
23
        
24
        public static function SetShortcutForAll($bool)
25
        {
26
            self::$SHORTCUT_FOR_ALL=(bool)$bool;
27
        }
28
        public static function create($classname, $name=self::CAN_NEVER_EVER_CHOOSE_THIS_AS_FUNCTION_NAME)
29
        {
30
            if (is_string($classname)&&class_exists($classname, true)) {
31
                return self::_create($classname, $name);
32
            }
33
        }
34
        
35
        
36
        private static function _create($classname, $name)
37
        {
38
            extract(self::_init($classname));
39
            self::getTheRightDir($file, $Dir, $fullQualifiedClassname);
40
            $fileExists=file_exists($file);
41
            if (!function_exists($classname)&&!function_exists($name)) {
42
                return self::handleNewShortcut($classname, $name, $file, $Dir, $fullQualifiedClassname, $fileExists, $reflectionClass);
43
            } else {
44
                self::GetTheRightExceptionMessage($fileExists, $name, $fullQualifiedClassname);
45
            }
46
        }
47
        
48
        private static function handleNewShortcut($classname, $name, $file, $Dir, $fullQualifiedClassname, $fileExists, \ReflectionClass $reflectionClass)
49
        {
50
            if ($fileExists) {
51
                return include_once($file);
52
            }
53
            extract(self::forwardInit($name, $Dir, $reflectionClass));
54
            if (is_null($reflectionMethod)||$notInstantiable=!$reflectionClass->isInstantiable()) {
55
                self::HandleNotInstantiableAndHasNoConstructor($Shortcut, $fullQualifiedClassname, $name, $notInstantiable, $classname);
56
                if ($Shortcut) {
57
                    return self::pushAndShow($file, $Shortcut);
58
                }
59
                $private_scope=true;
60
            }
61
62
            return  self::BuildCacheAndShow($classname, $name, $file, $fullQualifiedClassname, $reflectionMethod, $private_scope);
63
        }
64
        
65
        private static function BuildCacheAndShow($classname, $name, $file, $fullQualifiedClassname, \ReflectionMethod $reflectionMethod, $private_scope)
66
        {
67
            self::getSignature($reflectionMethod, $signature, $parameters, $paramsNum, $count);
68
            $hasInternal='';
69
            if ($count) {
70
                self::BuildTheSwitch($hasInternal, $count, $paramsNum, $parameters, $classname);
71
            }
72
            self::useTheRightNameAndScope($Shortcut, $name, $fullQualifiedClassname, $signature, $private_scope, $classname);
73
                    
74
            self::handleInternals($Shortcut, $hasInternal, $parameters, $signature, $classname);
75
                        
76
            return self::pushAndShow($file, $Shortcut);
77
        }
78
79
     
80
        
81
        private static function useTheRightNameAndScope(&$Shortcut, $name, $fullQualifiedClassname, $signature, $scope, $classname)
82
        {
83
            if (strtolower($name)!=='new'&&preg_match(self::VALID_PHP_FUNCTION_NAME_PATTERN, $name)) {
84
                $Shortcut="<?php
85
							function $name($signature){";
86
                if ($scope) {
87
                    $Shortcut.="if(".'@get_class()'."!==$classname){
88
									throw new scopeException(\"Shortcut function $name can only be called in class $classname scope\");
89
								}";
90
                }
91
            } else {
92
                $Shortcut="<?php
93
							function $fullQualifiedClassname($signature){";
94
                if ($scope) {
95
                    $Shortcut.="if(@get_class()!==\"$classname\"){
96
							throw new scopeException(\"Shortcut function $fullQualifiedClassname can only be called in class $classname scope\");
97
						}";
98
                }
99
            }
100
        }
101
        
102
        private static function handleInternals(&$Shortcut, $hasInternal, $parameters, $signature, $classname)
103
        {
104
            if (!strpos($signature, "acce91966cd8eee995ee1ac30c98c3d89d8f9235")) {
105
                $Shortcut.="return new $classname(".join(',', $parameters).");
106
							}";
107
            } else {
108
                $Shortcut.='
109
							$count=count(array_keys(get_defined_vars(),"'.self::PLACEHOLDER_FOR_INTERNALS_CLASSES_OPTIONALS_PARAMETERS.'"));
110
							'.$hasInternal.'
111
							}';
112
            }
113
        }
114
        
115
        private static function pushAndShow($file, $Shortcut)
116
        {
117
            file_put_contents($file, str_replace("\t", '    ', $Shortcut));
118
            file_put_contents($file, php_strip_whitespace($file)); //just for cleanliness of the generated code
119
            return include_once($file);
120
        }
121
        
122
        private static function GetTheRightExceptionMessage($fileExists, $name, $fullQualifiedClassname)
123
        {
124
            if (!$fileExists) {
125
                if (strtolower($name)!=='new'&&preg_match(self::VALID_PHP_FUNCTION_NAME_PATTERN, $name)) {
126
                    throw new \InvalidArgumentException('function '.$name.' passed as second Argument already exists.
127
					Can\'t create a shortcut with the same name');
128
                } else {
129
                    throw new \InvalidArgumentException('function '.$fullQualifiedClassname.' already exists and An alias has not been provided as Argument 2.
130
					Can\'t create a shortcut function with this name');
131
                }
132
            }
133
        }
134
        
135
        private static function HandleNotInstantiableAndHasNoConstructor(&$Shortcut, $fullQualifiedClassname, $name, $notInstantiable, $classname)
136
        {
137
            if ($notInstantiable) {
138
                if (!self::$SHORTCUT_FOR_ALL) {
139
                    throw new \InvalidArgumentException('Not Instantiable class '.$fullQualifiedClassname.' passed as Argument');
140
                }
141
            } else {
142
                self::useTheRightNameAndScope($Shortcut, $name, $fullQualifiedClassname, '', false, $classname);
143
                $Shortcut.="return new $classname();
144
						}";
145
            }
146
        }
147
        
148
        private static function getTheRightDir(&$file, &$Dir, $fullQualifiedClassname)
149
        {
150
            if ($Dir=self::$DIR) {
151
                $file=self::$DIR.DIRECTORY_SEPARATOR.$fullQualifiedClassname.".Shortcut.php";
152
            } else {
153
                $Dir=dirname(__DIR__).DIRECTORY_SEPARATOR.'ClassShortcuts';
154
                $file=$Dir.DIRECTORY_SEPARATOR.$fullQualifiedClassname.".Shortcut.php";
155
            }
156
        }
157
        
158
        public static function setDir($dirname)
159
        {
160
            if (is_dir($dirname)&&is_writable($dirname)&&!self::$DIR) {
161
                self::$DIR=$dirname;
162
            }
163
        }
164
        
165
        private function __construct()
166
        {
167
        }
168
    }
169
      
170
}
171
172
namespace{
173
    function create_Shortcut($classname, $name='new')
174
    {
175
        return EZAMA\Shortcut::create($classname, $name);
176
    }
177
    class scopeException extends \Exception
178
    {
179
    }
180
}
181