国内流行的内容管理系统(CMS)多端全媒体解决方案 https://www.dedebiz.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dedemodule.class.php 21KB

5 months ago
2 years ago
2 years ago
3 years ago
5 years ago
5 years ago
5 years ago
5 years ago
2 years ago
5 years ago
5 years ago
2 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
3 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. <?php
  2. if (!defined('DEDEINC')) exit('dedebiz');
  3. /**
  4. * 模块插件
  5. *
  6. * @version $id:dedemodule.class.php 10:31 2010年7月6日 tianya $
  7. * @package DedeBIZ.Libraries
  8. * @copyright Copyright (c) 2022 DedeBIZ.COM
  9. * @license GNU GPL v2 (https://www.dedebiz.com/license)
  10. * @link https://www.dedebiz.com
  11. */
  12. require_once(DEDEINC.'/charset.func.php');
  13. require_once(DEDEINC.'/dedeatt.class.php');
  14. require_once(DEDEINC.'/libraries/dedehttpdown.class.php');
  15. function base64url_encode($data)
  16. {
  17. return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
  18. }
  19. function base64url_decode($data)
  20. {
  21. return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
  22. }
  23. class DedeModule
  24. {
  25. var $modulesPath;
  26. var $modulesUrl;
  27. var $modules;
  28. var $fileListNames;
  29. var $sysLang;
  30. var $moduleLang;
  31. function __construct($modulespath = '', $modulesUrl = '')
  32. {
  33. global $cfg_soft_lang;
  34. $this->sysLang = $this->moduleLang = $cfg_soft_lang;
  35. $this->fileListNames = array();
  36. $this->modulesPath = $modulespath;
  37. $this->modulesUrl = $modulesUrl;
  38. }
  39. function DedeModule($modulespath = '')
  40. {
  41. $this->__construct($modulespath);
  42. }
  43. /**
  44. * 枚举系统里已经存在的模块,缓存功能实际上只作hash与文件名的解析,在此不特别处理
  45. *
  46. * @access public
  47. * @param string $moduletype 模块类型
  48. * @return array
  49. */
  50. function GetModuleList($moduletype = '')
  51. {
  52. if (is_array($this->modules)) return $this->modules;
  53. $dh = dir($this->modulesPath) or die("没找到模块目录:({$this->modulesPath})");
  54. $fp = @fopen($this->modulesPath.'/modulescache.php', 'w') or die('读取文件权限出错,目录:'.$this->modulesPath.'/modulescache.php文件不可写');
  55. fwrite($fp, "<"."?php\r\n");
  56. fwrite($fp, "global \$allmodules;\r\n");
  57. while ($filename = $dh->read()) {
  58. if (preg_match("/\.xml$/i", $filename)) {
  59. $minfos = $this->GetModuleInfo(str_replace('.xml', '', $filename));
  60. if ($minfos == null) {
  61. continue;
  62. }
  63. if (isset($minfos['moduletype']) && $moduletype != '' && $moduletype != $minfos['moduletype']) {
  64. continue;
  65. }
  66. if ($minfos['hash'] != '') {
  67. $this->modules[$minfos['hash']] = $minfos;
  68. fwrite($fp, '$'."GLOBALS['allmodules']['{$minfos['hash']}']='{$filename}';\r\n");
  69. }
  70. }
  71. }
  72. fwrite($fp, '?'.'>');
  73. fclose($fp);
  74. $dh->Close();
  75. return $this->modules;
  76. }
  77. /**
  78. * 从远程获取模块信息
  79. *
  80. * @access public
  81. * @param string $moduletype 模块类型
  82. * @return string
  83. */
  84. function GetModuleUrlList($moduletype = '', $url = '')
  85. {
  86. return false;
  87. }
  88. /**
  89. * 转换编码
  90. *
  91. * @access public
  92. * @param string $str 字符串
  93. * @return string
  94. */
  95. function AppCode(&$str)
  96. {
  97. if ($this->moduleLang == $this->sysLang) {
  98. return $str;
  99. } else {
  100. if ($this->sysLang == 'utf-8') {
  101. if ($this->moduleLang == 'gbk') return gb2utf8($str);
  102. if ($this->moduleLang == 'big5') return gb2utf8(big52gb($str));
  103. } else if ($this->sysLang == 'gbk') {
  104. if ($this->moduleLang == 'utf-8') return utf82gb($str);
  105. if ($this->moduleLang == 'big5') return big52gb($str);
  106. } else if ($this->sysLang == 'big5') {
  107. if ($this->moduleLang == 'utf-8') return gb2big5(utf82gb($str));
  108. if ($this->moduleLang == 'gbk') return gb2big5($str);
  109. } else {
  110. return $str;
  111. }
  112. }
  113. return $str;
  114. }
  115. /**
  116. * 获得指定hash的模块文件
  117. *
  118. * @access public
  119. * @param string $hash hash文件
  120. * @return string
  121. */
  122. function GetHashFile($hash)
  123. {
  124. include_once($this->modulesPath.'/modulescache.php');
  125. if (isset($GLOBALS['allmodules'][$hash])) return $GLOBALS['allmodules'][$hash];
  126. else return $hash.'.xml';
  127. }
  128. /**
  129. * 获得某模块的基本信息
  130. *
  131. * @access public
  132. * @param string $hash hash
  133. * @param string $ftype 文件类型
  134. * @return array
  135. */
  136. function GetModuleInfo($hash, $ftype = 'hash')
  137. {
  138. if ($ftype == 'file') $filename = $hash;
  139. else if (!empty($this->modulesUrl)) {
  140. $filename = $this->modulesUrl.$hash.'.xml';
  141. } else $filename = $this->modulesPath.'/'.$this->GetHashFile($hash);
  142. $start = 0;
  143. $minfos = array();
  144. $minfos['name'] = $minfos['info'] = $minfos['time'] = '';
  145. $minfos['hash'] = $minfos['indexname'] = $minfos['indexurl'] = '';
  146. $minfos['ismember'] = $minfos['autosetup'] = $minfos['autodel'] = 0;
  147. //$minfos['filename'] = $filename;
  148. if (empty($this->modulesUrl)) {
  149. $minfos['filesize'] = filesize($filename) / 1024;
  150. $minfos['filesize'] = number_format($minfos['filesize'], 2, '.', '').' Kb';
  151. }
  152. $fp = fopen($filename, 'r') or die("文件{$filename}不存在或不可读");
  153. $n = 0;
  154. while (!feof($fp)) {
  155. $n++;
  156. if ($n > 30) break;
  157. $line = fgets($fp, 1024);
  158. if ($start == 0) {
  159. if (preg_match("/<baseinfo/is", $line)) $start = 1;
  160. } else {
  161. if (preg_match("/<\/baseinfo/is", $line)) break;
  162. $line = trim($line);
  163. list($skey, $svalue) = explode('=', $line);
  164. $skey = trim($skey);
  165. $minfos[$skey] = $svalue;
  166. }
  167. }
  168. fclose($fp);
  169. if (empty($minfos['lang'])) {
  170. $minfos['lang'] = "utf-8";
  171. }
  172. if (isset($minfos['lang'])) $this->moduleLang = trim($minfos['lang']);
  173. else $this->moduleLang = 'gbk';
  174. if ($this->sysLang == 'gb2312') $this->sysLang = 'gbk';
  175. if ($this->moduleLang == 'gb2312') $this->moduleLang = 'gbk';
  176. if ($this->sysLang != $this->moduleLang) {
  177. foreach ($minfos as $k => $v) $minfos[$k] = $this->AppCode($v);
  178. }
  179. if (isset($minfos['pubkey'])) {
  180. //验证模块信息
  181. $pubKey = @base64url_decode($minfos['pubkey']);
  182. @openssl_public_decrypt(base64url_decode($minfos['info']), $decontent, $pubKey);
  183. $enInfo = (array)json_decode($decontent);
  184. if (count($enInfo) == 0) {
  185. return array();
  186. }
  187. if ($enInfo['module_name'] != $minfos['name'] || $enInfo['dev_id'] != $minfos['dev_id']) {
  188. return array();
  189. }
  190. }
  191. return $minfos;
  192. }
  193. /**
  194. * 获得某模块的基本信息
  195. *
  196. * @access public
  197. * @param string $hash hash
  198. * @param string $ftype 文件类型
  199. * @return string
  200. */
  201. function GetFileXml($hash, $ftype = 'hash')
  202. {
  203. if ($ftype == 'file') $filename = $hash;
  204. else $filename = $this->modulesPath.'/'.$this->GetHashFile($hash);
  205. $filexml = '';
  206. $fp = fopen($filename, 'r') or die("文件{$filename}不存在或不可读");
  207. $start = 0;
  208. while (!feof($fp)) {
  209. $line = fgets($fp, 1024);
  210. if ($start == 0) {
  211. if (preg_match("/<modulefiles/is", $line)) {
  212. $filexml .= $line;
  213. $start = 1;
  214. }
  215. continue;
  216. } else {
  217. $filexml .= $line;
  218. }
  219. }
  220. fclose($fp);
  221. return $filexml;
  222. }
  223. /**
  224. * 获得系统文件的文档
  225. * 指安装、删除、协议文件
  226. *
  227. * @access public
  228. * @param string $hashcode hash码
  229. * @param string $ntype 文件类型
  230. * @param string $enCode 是否加密
  231. * @return string
  232. */
  233. function GetSystemFile($hashcode, $ntype, $enCode = TRUE)
  234. {
  235. $this->GetModuleInfo($hashcode, $ntype);
  236. $start = FALSE;
  237. $filename = $this->modulesPath.'/'.$this->GetHashFile($hashcode);
  238. $fp = fopen($filename, 'r') or die("文件{$filename}不存在或不可读");
  239. $okdata = '';
  240. while (!feof($fp)) {
  241. $line = fgets($fp, 1024);
  242. if (!$start) {
  243. //2011-6-7修复模块打包程序中上传程序安装生成为空白文件
  244. if (preg_match("#<{$ntype}>#i", $line)) $start = TRUE;
  245. } else {
  246. if (preg_match("#<\/{$ntype}#i", $line)) break;
  247. $okdata .= $line;
  248. unset($line);
  249. }
  250. }
  251. fclose($fp);
  252. $okdata = trim($okdata);
  253. if (!empty($okdata) && $enCode) $okdata = base64_decode($okdata);
  254. $okdata = $this->AppCode($okdata);
  255. return $okdata;
  256. }
  257. /**
  258. * 把某系统文件转换为文件
  259. *
  260. * @access public
  261. * @param string $hashcode hash码
  262. * @param string $ntype 文件类型
  263. * @return string 返回文件名
  264. */
  265. function WriteSystemFile($hashcode, $ntype)
  266. {
  267. $filename = $hashcode."-{$ntype}.php";
  268. $fname = $this->modulesPath.'/'.$filename;
  269. $filect = $this->GetSystemFile($hashcode, $ntype);
  270. $fp = fopen($fname, 'w') or die("生成{$ntype}文件失败");
  271. fwrite($fp, $filect);
  272. fclose($fp);
  273. return $filename;
  274. }
  275. /**
  276. * 删除系统文件
  277. *
  278. * @access public
  279. * @param string $hashcode hash码
  280. * @param string $ntype 文件类型
  281. * @return void
  282. */
  283. function DelSystemFile($hashcode, $ntype)
  284. {
  285. $filename = $this->modulesPath.'/'.$hashcode."-{$ntype}.php";
  286. unlink($filename);
  287. }
  288. /**
  289. * 检查是否已经存在指定的模块
  290. *
  291. * @access public
  292. * @param string $hashcode hash码
  293. * @return bool 如果存在则返回True,否则为False
  294. */
  295. function HasModule($hashcode)
  296. {
  297. $modulefile = $this->modulesPath.'/'.$this->GetHashFile($hashcode);
  298. if (file_exists($modulefile) && !is_dir($modulefile)) return TRUE;
  299. else return FALSE;
  300. }
  301. /**
  302. * 读取文件,返回编码后的文件文档
  303. *
  304. * @access public
  305. * @param string $filename 文件名
  306. * @param string $isremove 是否删除
  307. * @return string
  308. */
  309. function GetEncodeFile($filename, $isremove = FALSE)
  310. {
  311. $fp = fopen($filename, 'r') or die("文件{$filename}不存在或不可读");
  312. $str = @fread($fp, filesize($filename));
  313. fclose($fp);
  314. if ($isremove) @unlink($filename);
  315. if (!empty($str)) return base64_encode($str);
  316. else return '';
  317. }
  318. /**
  319. * 获取模块包里的文件名列表
  320. *
  321. * @access public
  322. * @param string $hashcode hash码
  323. * @return string 返回文件列表
  324. */
  325. function GetFileLists($hashcode)
  326. {
  327. $dap = new DedeAttParse();
  328. $filelists = array();
  329. $modulefile = $this->modulesPath.'/'.$this->GetHashFile($hashcode);
  330. $fp = fopen($modulefile, 'r') or die("文件{$modulefile}不存在或不可读");
  331. $i = 0;
  332. while (!feof($fp)) {
  333. $line = fgets($fp, 1024);
  334. if (preg_match("/^[\s]{0,}<file/i", $line)) {
  335. $i++;
  336. $line = trim(preg_replace("/[><]/", "", $line));
  337. $dap->SetSource($line);
  338. $filelists[$i]['type'] = $dap->CAtt->GetAtt('type');
  339. $filelists[$i]['name'] = $dap->CAtt->GetAtt('name');
  340. }
  341. }
  342. fclose($fp);
  343. return $filelists;
  344. }
  345. /**
  346. * 删除已安装模块附带的文件
  347. *
  348. * @access public
  349. * @param string $hashcode hash码
  350. * @param string $isreplace 是否替换
  351. * @return string
  352. */
  353. function DeleteFiles($hashcode, $isreplace = 0)
  354. {
  355. if ($isreplace == 0) return TRUE;
  356. else {
  357. $dap = new DedeAttParse();
  358. $modulefile = $this->modulesPath.'/'.$this->GetHashFile($hashcode);
  359. $fp = fopen($modulefile, 'r') or die("文件{$modulefile}不存在或不可读");
  360. $i = 0;
  361. $dirs = array();
  362. while (!feof($fp)) {
  363. $line = fgets($fp, 1024);
  364. if (preg_match("/^[\s]{0,}<file/i", $line)) {
  365. $i++;
  366. $line = trim(preg_replace("/[><]/", "", $line));
  367. $dap->SetSource($line);
  368. $filetype = $dap->CAtt->GetAtt('type');
  369. $filename = $dap->CAtt->GetAtt('name');
  370. $filename = str_replace("\\", "/", $filename);
  371. if ($filetype == 'dir') {
  372. $dirs[] = $filename;
  373. } else {
  374. @unlink($filename);
  375. }
  376. }
  377. }
  378. $okdirs = array();
  379. if (is_array($dirs)) {
  380. $st = count($dirs) - 1;
  381. for ($i = $st; $i >= 0; $i--) {
  382. @rmdir($dirs[$i]);
  383. }
  384. }
  385. fclose($fp);
  386. }
  387. return TRUE;
  388. }
  389. /**
  390. * 把模块包里的文件写入服务器
  391. *
  392. * @access public
  393. * @param string $hashcode hash码
  394. * @param string $isreplace 是否替换
  395. * @return string
  396. */
  397. function WriteFiles($hashcode, $isreplace = 3)
  398. {
  399. global $AdminBaseDir;
  400. $dap = new DedeAttParse();
  401. $modulefile = $this->modulesPath.'/'.$this->GetHashFile($hashcode);
  402. $fp = fopen($modulefile, 'r') or die("文件{$modulefile}不存在或不可读");
  403. $i = 0;
  404. while (!feof($fp)) {
  405. $line = fgets($fp, 1024);
  406. if (preg_match("/^[\s]{0,}<file/i", $line)) {
  407. $i++;
  408. $line = trim(preg_replace("/[><]/", "", $line));
  409. $dap->SetSource($line);
  410. $filetype = $dap->CAtt->GetAtt('type');
  411. $filename = $dap->CAtt->GetAtt('name');
  412. $filename = str_replace("\\", "/", $filename);
  413. if (!empty($AdminBaseDir)) $filename = $AdminBaseDir.$filename;
  414. if ($filetype == 'dir') {
  415. if (!is_dir($filename)) {
  416. @mkdir($filename, $GLOBALS['cfg_dir_purview']);
  417. }
  418. @chmod($filename, $GLOBALS['cfg_dir_purview']);
  419. } else {
  420. $this->TestDir($filename);
  421. if ($isreplace == 0) continue;
  422. if ($isreplace == 3) {
  423. if (is_file($filename)) {
  424. $copyname = @preg_replace("/([^\/]{1,}$)/", "bak-$1", $filename);
  425. @copy($filename, $copyname);
  426. }
  427. }
  428. if (!empty($filename)) {
  429. $fw = fopen($filename, 'w') or die("写入文件{$filename}失败,请检查相关目录的权限");
  430. $ct = '';
  431. while (!feof($fp)) {
  432. $l = fgets($fp, 1024);
  433. if (preg_match("/^[\s]{0,}<\/file/i", trim($l))) {
  434. break;
  435. }
  436. $ct .= $l;
  437. }
  438. $ct = base64_decode($ct);
  439. if ($this->sysLang != $this->moduleLang) {
  440. //转换内码
  441. if (preg_match('/\.(xml|php|inc|txt|htm|html|shtml|tpl|css)$/', $filename)) {
  442. $ct = $this->AppCode($ct);
  443. }
  444. //转换HTML编码标识
  445. if (preg_match('/\.(php|htm|html|shtml|inc|tpl)$/i', $filename)) {
  446. if ($this->sysLang == 'big5') $charset = 'charset=big5';
  447. else if ($this->sysLang == 'utf-8') $charset = 'charset=gb2312';
  448. else $charset = 'charset=gb2312';
  449. $ct = preg_match("/charset=([a-z0-9-]*)/i", $charset, $ct);
  450. }
  451. }
  452. fwrite($fw, $ct);
  453. fclose($fw);
  454. }
  455. }
  456. }
  457. }
  458. fclose($fp);
  459. return TRUE;
  460. }
  461. /**
  462. * 测试某文件的文件夹是否创建
  463. *
  464. * @access public
  465. * @param string $filename 文件名称
  466. * @return string
  467. */
  468. function TestDir($filename)
  469. {
  470. $fs = explode('/', $filename);
  471. $fn = count($fs) - 1;
  472. $ndir = '';
  473. for ($i = 0; $i < $fn; $i++) {
  474. if ($ndir != '') $ndir = $ndir.'/'.$fs[$i];
  475. else $ndir = $fs[$i];
  476. $rs = @is_dir($ndir);
  477. if (!$rs) {
  478. @mkdir($ndir, $GLOBALS['cfg_dir_purview']);
  479. @chmod($ndir, $GLOBALS['cfg_dir_purview']);
  480. }
  481. }
  482. return TRUE;
  483. }
  484. /**
  485. * 获取某个目录或文件的打包数据
  486. *
  487. * @access public
  488. * @param string $basedir 基本目录
  489. * @param string $f
  490. * @param resource $fp 文件指针
  491. * @return bool
  492. */
  493. function MakeEncodeFile($basedir, $f, $fp)
  494. {
  495. $this->fileListNames = array();
  496. $this->MakeEncodeFileRun($basedir, $f, $fp);
  497. return TRUE;
  498. }
  499. /**
  500. * 测试目标文件
  501. *
  502. * @access public
  503. * @param string $basedir 基本目录
  504. * @param string $f
  505. * @return bool
  506. */
  507. function MakeEncodeFileTest($basedir, $f)
  508. {
  509. $this->fileListNames = array();
  510. $this->MakeEncodeFileRunTest($basedir, $f);
  511. return TRUE;
  512. }
  513. /**
  514. * 检测某个目录或文件的打包数据,递归
  515. *
  516. * @access public
  517. * @param string $basedir 基本目录
  518. * @param string $f
  519. * @return void
  520. */
  521. function MakeEncodeFileRunTest($basedir, $f)
  522. {
  523. $filename = $basedir.'/'.$f;
  524. if (isset($this->fileListNames[$f])) return;
  525. else if (preg_match("/Thumbs\.db/i", $f)) return;
  526. else $this->fileListNames[$f] = 1;
  527. if (!file_exists($filename)) {
  528. ShowMsg("文件或文件夹{$filename}不存在,无法进行编译", "-1");
  529. exit();
  530. }
  531. if (is_dir($filename)) {
  532. $dh = dir($filename);
  533. while ($filename = $dh->read()) {
  534. if ($filename[0] == '.' || strtolower($filename) == 'cvs') continue;
  535. $nfilename = $f.'/'.$filename;
  536. $this->MakeEncodeFileRunTest($basedir, $nfilename);
  537. }
  538. }
  539. }
  540. /**
  541. * 获取个目录或文件的打包数据,递归
  542. *
  543. * @access public
  544. * @param string $basedir 基本目录
  545. * @param string $f
  546. * @param resource $fp 文件指针
  547. * @return void
  548. */
  549. function MakeEncodeFileRun($basedir, $f, $fp)
  550. {
  551. $filename = $basedir.'/'.$f;
  552. if (isset($this->fileListNames[$f])) return;
  553. else if (preg_match("#Thumbs\.db#i", $f)) return;
  554. else $this->fileListNames[$f] = 1;
  555. $fileList = '';
  556. if (is_dir($filename)) {
  557. $fileList .= "<file type='dir' name='$f'>\r\n";
  558. $fileList .= "</file>\r\n";
  559. fwrite($fp, $fileList);
  560. $dh = dir($filename);
  561. while ($filename = $dh->read()) {
  562. if ($filename[0] == '.' || strtolower($filename) == 'cvs') continue;
  563. $nfilename = $f.'/'.$filename;
  564. $this->MakeEncodeFileRun($basedir, $nfilename, $fp);
  565. }
  566. } else {
  567. $fileList .= "<file type='file' name='$f'>\r\n";
  568. $fileList .= $this->GetEncodeFile($filename);
  569. $fileList .= "\r\n</file>\r\n";
  570. fwrite($fp, $fileList);
  571. }
  572. }
  573. /**
  574. * 清理
  575. *
  576. * @access public
  577. * @return void
  578. */
  579. function Clear()
  580. {
  581. unset($this->modules);
  582. unset($this->fileListNames);
  583. }
  584. }
  585. ?>