PageRenderTime 65ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Import.class.php

https://github.com/franc015/open-miage-util
PHP | 385 lines | 237 code | 41 blank | 107 comment | 101 complexity | d8fe81cb755e569afb5b00c24265d6d7 MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. if (!defined("OpenM_LIB_PATH"))
  3. define("OpenM_LIB_PATH", dirname(__FILE__) . "/");
  4. if (!defined("OpenM_EXT_LIB_PATH")) {
  5. $dir = dirname(dirname(dirname(__FILE__)));
  6. if (is_dir($dir . "/lib"))
  7. define("OpenM_EXT_LIB_PATH", $dir . "/lib/");
  8. else
  9. define("OpenM_EXT_LIB_PATH", dirname($dir) . "/");
  10. }
  11. /**
  12. * OpenM system class for class and interface loading
  13. * Manage a [list of] class path.
  14. * @package OpenM
  15. * @copyright (c) 2013, www.open-miage.org
  16. * @license http://www.apache.org/licenses/LICENSE-2.0 Licensed under the Apache License, Version 2.0 (the "License");
  17. * you may not use this file except in compliance with the License.
  18. * You may obtain a copy of the License at
  19. *
  20. * http://www.apache.org/licenses/LICENSE-2.0
  21. *
  22. * Unless required by applicable law or agreed to in writing, software
  23. * distributed under the License is distributed on an "AS IS" BASIS,
  24. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  25. * See the License for the specific language governing permissions and
  26. * limitations under the License.
  27. * @link http://www.open-miage.org
  28. * @author Gael SAUNIER
  29. */
  30. class Import {
  31. const IMPORTED = "imported";
  32. const PATH = OpenM_LIB_PATH;
  33. const LIB = OpenM_EXT_LIB_PATH;
  34. /**
  35. * @var ArrayList
  36. */
  37. private static $classPathList;
  38. /**
  39. * @var array
  40. */
  41. private static $importList;
  42. /**
  43. * @var array
  44. */
  45. private static $importResourceList;
  46. /**
  47. * @ignore
  48. */
  49. public static function resource($import) {
  50. if (!is_string($import))
  51. throw new InvalidArgumentException("argument must be a string");
  52. $imported = self::resourceOnClassPath($import);
  53. if ((!$imported && self::$classPathList !== null)
  54. || (preg_match("/\/\*$/", $import) && self::$classPathList !== null)) {
  55. $e = self::$classPathList->enum();
  56. while ($e->hasNext()) {
  57. $relativePath = $e->next();
  58. if (self::resourceOnClassPath($import, $relativePath . ""))
  59. return true;
  60. }
  61. return false;
  62. }
  63. else
  64. return $imported;
  65. }
  66. /**
  67. * used to know if a resource (no php file) is in classpath
  68. * @param String $import is searched resource
  69. * @param String $relativePath is used by Import class to search in all classpaths
  70. * @return boolean true if resource is in class path, else false
  71. */
  72. private static function resourceOnClassPath($import, $relativePath = "") {
  73. if (self::$importResourceList == null)
  74. self::$importResourceList = array();
  75. if (isset(self::$importResourceList[$import]) && self::$importResourceList[$import] == self::IMPORTED)
  76. return true;
  77. $OpenM_LIB_PATH = ($relativePath == "") ? OpenM_LIB_PATH : (!preg_match("/\/$/", $relativePath) ? ($relativePath . "/") : $relativePath);
  78. if (is_file($OpenM_LIB_PATH . $import)) {
  79. if (!preg_match("/\.php$/", $import)) {
  80. self::$importResourceList[$import] = self::IMPORTED;
  81. return true;
  82. }
  83. else
  84. return self::phpOnClassPath($import, $relativePath);
  85. } else if (preg_match("/\/\*$/", $OpenM_LIB_PATH . $import) && is_dir(substr($OpenM_LIB_PATH . $import, 0, -2))) {
  86. $import = substr($import, 0, -1);
  87. $dir = @opendir($OpenM_LIB_PATH . $import);
  88. if ($dir) {
  89. while (($file = readdir($dir)) !== false) {
  90. if (!preg_match("/^\./", $file)) {
  91. if (is_file($OpenM_LIB_PATH . $import . $file)) {
  92. self::resourceOnClassPath($import . $file, $relativePath);
  93. } else if (is_dir($OpenM_LIB_PATH . $import . $file)) {
  94. self::resourceOnClassPath($import . $file . "/*", $relativePath);
  95. }
  96. }
  97. }
  98. closedir($dir);
  99. }
  100. return true;
  101. }
  102. else
  103. return false;
  104. }
  105. /**
  106. * @ignore
  107. * @param String $import
  108. * @throws Exception
  109. */
  110. public static function lib($import) {
  111. if (is_dir(self::LIB))
  112. self::phpOnClassPath($import, self::LIB);
  113. else
  114. throw new Exception("OpenM_EXT_LIB_PATH not defined and default path not found");
  115. }
  116. /**
  117. * used to import a class or an interface or a direcotyr in class path
  118. * @param String $import class or interface or a directory path in class path
  119. * @return boolean true if class or interface or direcotyr correctly imported from class path
  120. * @throws InvalidArgumentException
  121. */
  122. public static function php($import) {
  123. if (!is_string($import))
  124. throw new InvalidArgumentException("argument must be a string");
  125. $imported = self::phpOnClassPath($import);
  126. if ((!$imported && self::$classPathList !== null)
  127. || (preg_match("/\.\*$/", $import) && self::$classPathList !== null)) {
  128. $e = self::$classPathList->enum();
  129. while ($e->hasNext()) {
  130. $relativePath = $e->next();
  131. if (self::phpOnClassPath($import, $relativePath . ""))
  132. return true;
  133. }
  134. return false;
  135. }
  136. else
  137. return $imported;
  138. }
  139. /**
  140. * used to add a library directory path
  141. * Ex.: 'openid/2.0.2'
  142. * @param String $relativePath relative path from library directory
  143. * to specific library you need to add in class path
  144. * RQ: OpenM_EXT_LIB_PATH must be define
  145. * @throws Exception if OpenM_EXT_LIB_PATH not correctly defined
  146. */
  147. public static function addLibPath($relativePath) {
  148. if (!is_dir(OpenM_EXT_LIB_PATH))
  149. throw new Exception("OpenM_EXT_LIB_PATH not correctly define, OpenM_EXT_LIB_PATH must target the 'lib' path, OpenM_EXT_LIB_PATH must be define (if necessary) before require_once Import class");
  150. if (!is_dir(self::LIB . "/$relativePath"))
  151. throw new Exception("$relativePath not found in '" . self::LIB . "' path");
  152. self::addClassPath(self::LIB . "/$relativePath");
  153. }
  154. /**
  155. * used to add a new class path in declared class path list
  156. * @param String $absoluteRootClassPath
  157. * @throws InvalidArgumentException
  158. */
  159. public static function addClassPath($absoluteRootClassPath = null) {
  160. if ($absoluteRootClassPath == null)
  161. $absoluteRootClassPath = ".";
  162. if (!is_string($absoluteRootClassPath))
  163. throw new InvalidArgumentException("argument must be a string");
  164. if (self::$classPathList == null) {
  165. self::php("util.ArrayList");
  166. self::php("util.wrapper.String");
  167. self::$classPathList = new ArrayList();
  168. }
  169. if (!is_dir($absoluteRootClassPath))
  170. throw new InvalidArgumentException("argument must be a valid directory path");
  171. $absoluteRootClassPath = realpath($absoluteRootClassPath);
  172. if (!self::$classPathList->contains($absoluteRootClassPath)) {
  173. self::$classPathList->add($absoluteRootClassPath);
  174. }
  175. }
  176. /**
  177. * used to add a php class path.
  178. * For example, if exist ./a/b/myFile.php and adding ./a/b with addInPhpClassPath,
  179. * I'll could read myFile.php from require 'myFile.php';
  180. * It's used to load external library that required to set the current path to
  181. * root of library
  182. * @param String $path is path of classpath added
  183. */
  184. public static function addInPhpClassPath($path) {
  185. $absolutePath = self::getAbsolutePath($path);
  186. $paths = ini_get('include_path');
  187. if (!in_array($absolutePath, explode(PATH_SEPARATOR, $paths))) {
  188. $paths = $paths . PATH_SEPARATOR . $absolutePath;
  189. ini_set('include_path', $paths);
  190. }
  191. }
  192. private static function phpOnClassPath($import, $relativePath = "") {
  193. $importNormalized = str_replace(".", "/", $import);
  194. if (self::$importList == null)
  195. self::$importList = array();
  196. if (isset(self::$importList[$importNormalized]) && self::$importList[$importNormalized] == self::IMPORTED)
  197. return true;
  198. $OpenM_LIB_PATH = ($relativePath == "") ? OpenM_LIB_PATH : (!preg_match("/\/$/", $relativePath) ? ($relativePath . "/") : $relativePath);
  199. if (is_file($OpenM_LIB_PATH . $import)) {
  200. if (preg_match("/\.php$/", $import)) {
  201. require_once $OpenM_LIB_PATH . $import;
  202. self::$importList[$import] = self::IMPORTED;
  203. return true;
  204. }
  205. else
  206. return self::resourceOnClassPath($import, $relativePath);
  207. } else {
  208. $import = $importNormalized;
  209. if (is_file($OpenM_LIB_PATH . $import . ".class.php")) {
  210. require_once $OpenM_LIB_PATH . $import . ".class.php";
  211. } else if (is_file($OpenM_LIB_PATH . $import . ".interface.php")) {
  212. require_once $OpenM_LIB_PATH . $import . ".interface.php";
  213. } else if (preg_match("/\/\*$/", $OpenM_LIB_PATH . $import) && is_dir(substr($OpenM_LIB_PATH . $import, 0, -2))) {
  214. $import = substr($import, 0, -1);
  215. $dir = @opendir($OpenM_LIB_PATH . $import);
  216. if ($dir) {
  217. while (($file = readdir($dir)) !== false) {
  218. if (!preg_match("/^\./", $file)) {
  219. if (is_file($OpenM_LIB_PATH . $import . $file)) {
  220. if (preg_match("/\.class\.php$/", $file))
  221. self::phpOnClassPath($import . substr($file, 0, -10), $relativePath);
  222. else if (preg_match("/\.interface\.php$/", $file))
  223. self::phpOnClassPath($import . substr($file, 0, -14), $relativePath);
  224. else
  225. self::php($import . $file);
  226. }
  227. else if (is_dir($OpenM_LIB_PATH . $import . $file)) {
  228. self::phpOnClassPath($import . $file . ".*", $relativePath);
  229. }
  230. }
  231. }
  232. closedir($dir);
  233. }
  234. }
  235. else
  236. return false;
  237. }
  238. self::$importList[$importNormalized] = self::IMPORTED;
  239. return true;
  240. }
  241. /**
  242. * could be used to know if a php file was imported by Import class
  243. * @param String $imported
  244. * @return boolean
  245. */
  246. public static function isImported($imported) {
  247. if (self::$importList == null)
  248. return false;
  249. return self::$importList->contains($imported);
  250. }
  251. /**
  252. * @ignore
  253. */
  254. public static function getPhpImported() {
  255. $array = new ArrayList();
  256. if (self::$importList == null)
  257. return $array;
  258. foreach (self::$importList as $key => $value)
  259. $array->add($key);
  260. return $array;
  261. }
  262. /**
  263. * @ignore
  264. */
  265. public static function getImportedResources() {
  266. $array = new ArrayList();
  267. if (self::$importResourceList == null)
  268. return $array;
  269. foreach (self::$importResourceList as $key => $value)
  270. $array->add($key);
  271. return $array;
  272. }
  273. /**
  274. * @ignore
  275. */
  276. public static function getPhpImportedAbsolutePath() {
  277. $array = new ArrayList();
  278. if (self::$importList == null)
  279. return $array;
  280. foreach (self::$importList as $key => $value) {
  281. $path = self::getAbsolutePath($key . ".class.php");
  282. if ($path == null)
  283. $path = self::getAbsolutePath($key . ".interface.php");
  284. if ($path == null)
  285. $path = self::getAbsolutePath($key);
  286. if ($path != null)
  287. $array->add($path);
  288. }
  289. return $array;
  290. }
  291. /**
  292. * @ignore
  293. */
  294. public static function getImportedResourcesAbsolutePath() {
  295. $array = new ArrayList();
  296. if (self::$importResourceList == null)
  297. return $array;
  298. foreach (self::$importResourceList as $key => $value) {
  299. $path = self::getAbsolutePath($key);
  300. if ($path != null)
  301. $array->add($path);
  302. }
  303. return $array;
  304. }
  305. /**
  306. * used to know list of class path out of Import parent directory
  307. * @return ArrayList contains class path added list
  308. */
  309. public static function getClassPathList() {
  310. return self::$classPathList->copy();
  311. }
  312. /**
  313. * used to recover the absolute path of a file if exist in one of
  314. * class path
  315. * @param String $path is a relative path (could use class loading format)
  316. * @throws InvalidArgumentException
  317. */
  318. public static function getAbsolutePath($path) {
  319. if (is_file($path) || is_dir($path))
  320. return realpath($path);
  321. if ($path == null)
  322. return null;
  323. if (self::$importList == null)
  324. return null;
  325. self::php("util.wrapper.String");
  326. if (!String::isStringOrNull($path))
  327. throw new InvalidArgumentException("the path must be a string");
  328. if (is_file(OpenM_LIB_PATH . $path) || (is_dir(OpenM_LIB_PATH . $path)))
  329. return OpenM_LIB_PATH . $path;
  330. if (self::$classPathList == null)
  331. return null;
  332. $e = self::$classPathList->enum();
  333. while ($e->hasNext()) {
  334. $classPath = $e->next();
  335. $absPath = preg_match("/\/$/", $classPath) ? $classPath . $path : $classPath . "/" . $path;
  336. if (is_file($absPath) || is_dir($absPath))
  337. return $absPath;
  338. }
  339. }
  340. }
  341. Import::php("Import");
  342. Import::php("ImportException");
  343. ?>