JuKu /
JuKuCMS
| 1 | <?php |
||||
| 2 | |||||
| 3 | /** |
||||
| 4 | * Copyright (c) 2018 Justin Kuenzel (jukusoft.com) |
||||
| 5 | * |
||||
| 6 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||||
| 7 | * you may not use this file except in compliance with the License. |
||||
| 8 | * You may obtain a copy of the License at |
||||
| 9 | * |
||||
| 10 | * http://www.apache.org/licenses/LICENSE-2.0 |
||||
| 11 | * |
||||
| 12 | * Unless required by applicable law or agreed to in writing, software |
||||
| 13 | * distributed under the License is distributed on an "AS IS" BASIS, |
||||
| 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
| 15 | * See the License for the specific language governing permissions and |
||||
| 16 | * limitations under the License. |
||||
| 17 | */ |
||||
| 18 | |||||
| 19 | class ClassLoader { |
||||
| 20 | |||||
| 21 | public static $classlist = array(); |
||||
| 22 | |||||
| 23 | public static $loadedClasses = 0; |
||||
| 24 | |||||
| 25 | public static $namespace_autoloader = array(); |
||||
| 26 | |||||
| 27 | /** |
||||
| 28 | * initialize classloader (called only once / request) |
||||
| 29 | */ |
||||
| 30 | public static function init () { |
||||
| 31 | |||||
| 32 | //register autoloader |
||||
| 33 | spl_autoload_register('cms_autoloader'); |
||||
| 34 | |||||
| 35 | if (!file_exists(ROOT_PATH . "cache")) { |
||||
| 36 | mkdir(ROOT_PATH . "cache"); |
||||
| 37 | } |
||||
| 38 | |||||
| 39 | if (!file_exists(ROOT_PATH . "cache/classloader/classlist.php")) { |
||||
| 40 | self::rebuildCache(); |
||||
| 41 | } |
||||
| 42 | |||||
| 43 | require(ROOT_PATH . "cache/classloader/classlist.php"); |
||||
| 44 | self::$classlist = $classlist; |
||||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||||
| 45 | |||||
| 46 | } |
||||
| 47 | |||||
| 48 | public static function rebuildCache () { |
||||
| 49 | |||||
| 50 | require_once(ROOT_PATH . "system/core/classes/packages.php"); |
||||
| 51 | |||||
| 52 | if (file_exists(ROOT_PATH . "cache/classloader/classlist.php")) { |
||||
| 53 | @unlink(ROOT_PATH . "cache/classloader/classlist.php"); |
||||
|
0 ignored issues
–
show
It seems like you do not handle an error condition for
unlink(). This can introduce security issues, and is generally not recommended.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||||
| 54 | } |
||||
| 55 | |||||
| 56 | if (!file_exists(ROOT_PATH . "cache/classloader")) { |
||||
| 57 | mkdir(ROOT_PATH . "cache/classloader"); |
||||
| 58 | } |
||||
| 59 | |||||
| 60 | $packages = Packages::listPackages(); |
||||
| 61 | |||||
| 62 | $classlist = array(); |
||||
| 63 | |||||
| 64 | foreach ($packages as $path) { |
||||
| 65 | $path = ROOT_PATH . "system/packages/" . $path . "/"; |
||||
| 66 | |||||
| 67 | if (file_exists($path . "classloader.xml")) { |
||||
| 68 | $xml = simplexml_load_file($path . "classloader.xml"); |
||||
| 69 | |||||
| 70 | foreach ($xml->xpath("//class") as $classname) { |
||||
| 71 | $classlist[(String) $classname] = $path . "classes/" . strtolower((String) $classname) . ".php"; |
||||
| 72 | } |
||||
| 73 | } |
||||
| 74 | } |
||||
| 75 | |||||
| 76 | $handle = fopen(ROOT_PATH . "cache/classloader/classlist.php", "w"); |
||||
| 77 | |||||
| 78 | fwrite($handle, "<" . "?" . "php\r\n\r\n"); |
||||
|
0 ignored issues
–
show
It seems like
$handle can also be of type false; however, parameter $handle of fwrite() does only seem to accept resource, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 79 | |||||
| 80 | fwrite($handle, "$" . "classlist = array(\r\n"); |
||||
| 81 | |||||
| 82 | foreach ($classlist as $classname=>$classpath) { |
||||
| 83 | fwrite($handle, "\t'" . $classname . "' => \"" . $classpath . "\",\r\n"); |
||||
| 84 | } |
||||
| 85 | |||||
| 86 | fwrite($handle, ");\r\n\r\n"); |
||||
| 87 | |||||
| 88 | fwrite($handle, "?" . ">"); |
||||
| 89 | |||||
| 90 | fclose($handle); |
||||
|
0 ignored issues
–
show
It seems like
$handle can also be of type false; however, parameter $handle of fclose() does only seem to accept resource, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 91 | |||||
| 92 | } |
||||
| 93 | |||||
| 94 | /** |
||||
| 95 | * add classloader for specific namespace prefix |
||||
| 96 | */ |
||||
| 97 | public static function addLoader (string $prefix, callable $func) { |
||||
| 98 | $prefix = strtolower($prefix); |
||||
| 99 | self::$namespace_autoloader[$prefix] = $func; |
||||
| 100 | } |
||||
| 101 | |||||
| 102 | public static function removeLoader (string $prefix) { |
||||
| 103 | $prefix = strtolower($prefix); |
||||
| 104 | unset(self::$namespace_autoloader[$prefix]); |
||||
| 105 | } |
||||
| 106 | |||||
| 107 | } |
||||
| 108 | |||||
| 109 | /** |
||||
| 110 | * autoload function |
||||
| 111 | */ |
||||
| 112 | function cms_autoloader ($classname) { |
||||
| 113 | |||||
| 114 | ClassLoader::$loadedClasses++; |
||||
| 115 | |||||
| 116 | if (isset(Classloader::$classlist[$classname])) { |
||||
| 117 | require(Classloader::$classlist[$classname]); |
||||
| 118 | return null; |
||||
| 119 | } |
||||
| 120 | |||||
| 121 | if (file_exists(ROOT_PATH . "system/core/classes/" . strtolower($classname) . ".php")) { |
||||
| 122 | require(ROOT_PATH . "system/core/classes/" . strtolower($classname) . ".php"); |
||||
| 123 | return null; |
||||
| 124 | } else if (file_exists(ROOT_PATH . "system/core/exception/" . strtolower($classname) . ".php")) { |
||||
| 125 | require(ROOT_PATH . "system/core/exception/" . strtolower($classname) . ".php"); |
||||
| 126 | return null; |
||||
| 127 | } else if (file_exists(ROOT_PATH . "system/core/driver/" . strtolower($classname) . ".php")) { |
||||
| 128 | require(ROOT_PATH . "system/core/driver/" . strtolower($classname) . ".php"); |
||||
| 129 | return null; |
||||
| 130 | } |
||||
| 131 | |||||
| 132 | //check, if class belongs to dwoo template engine |
||||
| 133 | if (PHPUtils::startsWith($classname, "Dwoo")) { |
||||
| 134 | if (class_exists("DwooAutoloader", true)) { |
||||
| 135 | DwooAutoloader::loadClass($classname); |
||||
| 136 | return; |
||||
| 137 | } else { |
||||
| 138 | echo "Could not load Dwoo template engine class " . $classname . "!"; |
||||
| 139 | } |
||||
| 140 | } |
||||
| 141 | |||||
| 142 | //check, if we have to use namespace classloading |
||||
| 143 | if (PHPUtils::containsStr($classname, "\\")) { |
||||
| 144 | //we have to use namespace classloading |
||||
| 145 | if (PHPUtils::startsWith($classname, "\\")) { |
||||
| 146 | //use normal class loading |
||||
| 147 | $classname = substr($classname, 1); |
||||
| 148 | } else { |
||||
| 149 | $array = explode("\\", strtolower($classname)); |
||||
| 150 | |||||
| 151 | if ($array[0] === "plugin") { |
||||
| 152 | $array1 = array(); |
||||
| 153 | |||||
| 154 | for ($i = 2; $i < count($array); $i++) { |
||||
|
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
|
|||||
| 155 | $array1[] = $array[$i]; |
||||
| 156 | } |
||||
| 157 | |||||
| 158 | $file_name = implode("/", $array1); |
||||
| 159 | |||||
| 160 | //load plugin class |
||||
| 161 | $path = PLUGIN_PATH . $array[1] . "/classes/" . $file_name . ".php"; |
||||
| 162 | |||||
| 163 | if (file_exists($path)) { |
||||
| 164 | require($path); |
||||
| 165 | } else { |
||||
| 166 | $expected_str = (DEBUG_MODE ? " (expected path: " . $path . ")" : ""); |
||||
| 167 | echo "Could not load plugin-class with namespace " . $classname . $expected_str . "!"; |
||||
| 168 | } |
||||
| 169 | } else { |
||||
| 170 | //check, if there is a classloader for this prefix |
||||
| 171 | if (isset(ClassLoader::$namespace_autoloader[$array[0]])) { |
||||
| 172 | //get function |
||||
| 173 | $func = ClassLoader::$namespace_autoloader[$array[0]]; |
||||
| 174 | |||||
| 175 | //call func |
||||
| 176 | $func($classname); |
||||
| 177 | } else { |
||||
| 178 | throw new IllegalStateException("Cannot load namespace class '" . $classname . "' with unknown prefix '" . $array[0] . "'!"); |
||||
| 179 | } |
||||
| 180 | } |
||||
| 181 | |||||
| 182 | return; |
||||
| 183 | } |
||||
| 184 | } |
||||
| 185 | |||||
| 186 | $array = explode("_", strtolower($classname)); |
||||
| 187 | |||||
| 188 | if (sizeOf($array) == 3) { |
||||
| 189 | |||||
| 190 | if ($array[0] == "plugin") { |
||||
| 191 | if (file_exists(ROOT_PATH . "plugins/" . strtolower($array[1]) . "/classes/" . strtolower($array[2]) . ".php")) { |
||||
| 192 | require(ROOT_PATH . "plugins/" . strtolower($array[1]) . "/classes/" . strtolower($array[2]) . ".php"); |
||||
| 193 | } else { |
||||
| 194 | echo "Could not load plugin-class " . $classname . "!"; |
||||
| 195 | } |
||||
| 196 | } else { |
||||
| 197 | if (file_exists(ROOT_PATH . "system/libs/smarty/sysplugins/" . strtolower($classname) . "php")) { |
||||
| 198 | require ROOT_PATH . "system/libs/smarty/sysplugins/" . strtolower($classname) . ".php"; |
||||
| 199 | } else if ($classname == "Smarty") { |
||||
| 200 | require("system/libs/smarty/Smarty.class.php"); |
||||
| 201 | } else { |
||||
| 202 | //echo "Could not (plugin) load class " . $classname . "!"; |
||||
| 203 | } |
||||
| 204 | } |
||||
| 205 | |||||
| 206 | } else if (sizeof($array) == 2) { |
||||
| 207 | if ($array[0] == "validator") { |
||||
| 208 | if (file_exists(ROOT_PATH . "system/core/validator/" . $array[1] . ".php")) { |
||||
| 209 | require(ROOT_PATH . "system/core/validator/" . $array[1] . ".php"); |
||||
| 210 | } else { |
||||
| 211 | echo "Could not load validator class " . $classname . "!"; |
||||
| 212 | } |
||||
| 213 | } else if ($array[0] == "datatype") { |
||||
| 214 | if (file_exists(ROOT_PATH . "system/core/datatype/" . $array[1] . ".php")) { |
||||
| 215 | require(ROOT_PATH . "system/core/datatype/" . $array[1] . ".php"); |
||||
| 216 | } else { |
||||
| 217 | echo "Could not load datatype class " . $classname . "!"; |
||||
| 218 | } |
||||
| 219 | } else if (strpos($classname, "Plugin")) { |
||||
| 220 | //dwoo tries several times to load a class - with and without namespace, so we hide this error message |
||||
| 221 | } else { |
||||
| 222 | echo "Could not load class " . $classname . ", unknown prefix '" . $array[0] . "'!"; |
||||
| 223 | } |
||||
| 224 | } else if (sizeOf($array) == 1) { |
||||
| 225 | |||||
| 226 | if (file_exists(ROOT_PATH . "system/classes/" . strtolower($classname) . ".php")) { |
||||
| 227 | include ROOT_PATH . "system/classes/" . strtolower($classname) . ".php"; |
||||
| 228 | } else if (file_exists(ROOT_PATH . "system/libs/smarty/sysplugins/" . strtolower($classname) . "php")) { |
||||
| 229 | require ROOT_PATH . "system/libs/smarty/sysplugins/" . strtolower($classname) . ".php"; |
||||
| 230 | } else if (strpos($classname, "Plugin") !== FALSE) { |
||||
| 231 | //dwoo tries several times to load a class - with and without namespace, so we hide this error message |
||||
| 232 | } else { |
||||
| 233 | echo "Could not load class '" . $classname . "'' (array size 1)!"; |
||||
| 234 | } |
||||
| 235 | |||||
| 236 | } |
||||
| 237 | |||||
| 238 | } |
||||
| 239 | |||||
| 240 | |||||
| 241 | ?> |
||||
|
0 ignored issues
–
show
It is not recommended to use PHP's closing tag
?> in files other than templates.
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore. A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever. Loading history...
|
|||||
| 242 |