PageRenderTime 26ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/PackageMgr/package.php

https://code.google.com/p/nuked-klan/
PHP | 381 lines | 337 code | 32 blank | 12 comment | 52 complexity | e2196f6ab8d19e6aea8d9f50a36868ec MD5 | raw file
Possible License(s): GPL-3.0, BSD-3-Clause, GPL-2.0, LGPL-3.0, LGPL-2.1
  1. <?php
  2. /***********************************************
  3. * PckageMgr - Gestionnaire de patch
  4. * ---------------------------------------------
  5. * Auteur : Bontiv <prog.bontiv@gmail.com>
  6. * Site web : http://remi.bonnetchangai.free.fr/
  7. * ---------------------------------------------
  8. * Ce fichier fait parti d'un module libre. Toutefois
  9. * je vous demanderez de respecter mon travail en ne
  10. * supprimant pas mon pseudo.
  11. ***********************************************/
  12. if (!defined("INDEX_CHECK"))
  13. {
  14. die ("<div style=\"text-align: center;\">You cannot open this page directly</div>");
  15. }
  16. if(extension_loaded('zip')){
  17. require_once 'extractors/zip.php';
  18. }
  19. require_once 'patcher.php';
  20. class PackageException extends Exception
  21. {
  22. public function __construct($code)
  23. {
  24. $this->code = $code;
  25. switch ($this->code)
  26. {
  27. case Package::E_FILENAME:
  28. $this->message = 'Nom de fichier incorrect';
  29. break;
  30. case Package::E_FILEEXIST:
  31. $this->message = 'Fichier inexistant';
  32. break;
  33. case Package::E_NOTINSTALLED:
  34. $this->message = 'Patch non install&#233;';
  35. break;
  36. case Package::E_TMPDIR:
  37. $this->message = 'Dossier temporaire inexistant';
  38. break;
  39. case Package::E_APPLI:
  40. $this->message = 'Fichier n&#233;cessaire au patch introuvable';
  41. break;
  42. case Package::E_ISACTIVE:
  43. $this->message = 'Ce patch est d&#233;j&agrave; activ&#233;.';
  44. break;
  45. case Package::E_XMLLOAD:
  46. $this->message = 'Impossible de charger la description XML.';
  47. break;
  48. case Package::E_NOTACTIVE:
  49. $this->message = 'Ce patch est d&#233;j&agrave; d&#233;sactiv&#233;';
  50. break;
  51. case Package::E_NOCODEC:
  52. $this->message = 'Format non pris en charge';
  53. break;
  54. case Package::E_NOZIP:
  55. $this->message = 'Votre h&#233;bergement ne permet la gestion des fichiers zip.';
  56. break;
  57. default:
  58. $this->message = 'Erreur inconnue';
  59. break;
  60. }
  61. }
  62. }
  63. class ExtractError extends PackageException
  64. {
  65. public function __construct($message, $code = null)
  66. {
  67. if ($code === null)
  68. {
  69. $this->message = $message;
  70. }
  71. else
  72. switch ($code)
  73. {
  74. default:
  75. $this->message = $message;
  76. }
  77. }
  78. }
  79. class Package
  80. {
  81. protected $action = array();
  82. protected $cfiles = array();
  83. protected $cdirectory = array();
  84. protected $install = null;
  85. protected $uninstall = null;
  86. protected $name = '';
  87. protected $author = '';
  88. protected $link = '';
  89. protected $file;
  90. protected $active;
  91. protected $extractor;
  92. public $table;
  93. public $directory;
  94. const E_FILENAME = 1;
  95. const E_FILEEXIST = 2;
  96. const E_NOTINSTALLED = 3;
  97. const E_TMPDIR = 4;
  98. const E_XMLLOAD = 5;
  99. const E_APPLI = 6;
  100. const E_ISACTIVE = 7;
  101. const E_NOTACTIVE = 8;
  102. const E_NOCODEC = 9;
  103. const E_NOZIP = 10;
  104. public function __construct ($file, $directory = null)
  105. {
  106. $this->file = $file;
  107. if ($directory === null)
  108. $directory = dirname(__FILE__) . '/../../upload/';
  109. $this->directory = $directory;
  110. $this->file = $file;
  111. $this->table = '`' . $GLOBALS['nuked']['prefix'] . '_packages`';
  112. if (!file_exists($this->directory) || !is_dir($this->directory))
  113. {
  114. throw new PackageException (self::E_TMPDIR);
  115. }
  116. elseif (preg_match('`^[a-z0-9_.-]+$`i', $this->file) == 0)
  117. {
  118. throw new PackageException (self::E_FILENAME);
  119. }
  120. elseif (!file_exists($this->directory . $this->file) || !is_file($this->directory . $this->file))
  121. {
  122. throw new PackageException (self::E_FILEEXIST);
  123. }
  124. $file = strtolower($this->file);
  125. $this->extractor = $this->getExtractor();
  126. echo $this->extractor->Load($this->directory . $this->file);
  127. }
  128. protected function getExtractor()
  129. {
  130. $ext = substr(strtolower(strrchr($this->file, '.')), 1);
  131. $driver = dirname(__FILE__) . '/extractors/' . $ext . '.php';
  132. if(!extension_loaded('zip') && $ext == 'zip'){
  133. throw new PackageException(self::E_NOZIP);
  134. }
  135. $class = ucfirst($ext) . 'Extractor';
  136. if (file_exists($driver) && is_file($driver))
  137. {
  138. require_once $driver;
  139. return new $class();
  140. }
  141. else
  142. throw new PackageException(self::E_NOCODEC);
  143. }
  144. protected function readHeader ()
  145. {
  146. $tmp = $this->directory . 'package.xml';
  147. @unlink($tmp);
  148. $this->extractor->ExtractFile('package.xml', $this->directory);
  149. $xml = simplexml_load_file($tmp);
  150. $header = $xml->header;
  151. if ($header->link != null)
  152. $this->link = $header->link[0];
  153. if ($header->author != null)
  154. $this->author = $header->author[0];
  155. if ($header->name != null)
  156. $this->name = $header->name[0];
  157. }
  158. protected function readPack ()
  159. {
  160. $tmp = $this->directory . 'package.xml';
  161. @unlink($tmp);
  162. $this->extractor->ExtractFile('package.xml', $this->directory);
  163. $xml = simplexml_load_file($tmp);
  164. $body = $xml->body;
  165. if (isset($body->files))
  166. {
  167. foreach ($body->files->copy as $copy)
  168. {
  169. $attr = $copy->attributes();
  170. if (isset($attr['from']))
  171. {
  172. $this->cfiles[] = array('to' => $attr['to']->__toString(), 'from' => $attr['from']->__toString(), 'content' => null);
  173. }
  174. else
  175. $this->cfiles[] = array('to' => $attr['to']->__toString(), 'content' => $copy->__toString());
  176. }
  177. foreach ($body->files->directory as $dir)
  178. $this->cdirectory[] = dirname(__FILE__) . '/../../' . $dir->__toString();
  179. }
  180. if (isset($body->patcher))
  181. {
  182. foreach ($body->patcher->file as $file)
  183. {
  184. $name = $file->attributes();
  185. foreach ($file as $patch)
  186. $this->action[$name['name']->__toString()][] = new Patch($patch);
  187. }
  188. }
  189. if (isset($body->oninstall))
  190. $this->install = $body->oninstall;
  191. if (isset($body->onremove))
  192. $this->uninstall = $body->onremove;
  193. }
  194. protected function exec($list)
  195. {
  196. if ($list !== null)
  197. {
  198. foreach ($list->children() as $action => $content)
  199. {
  200. $content = $content->__toString();
  201. switch ($action)
  202. {
  203. case 'sql':
  204. $content = str_replace('{PREFIX}', $GLOBALS['nuked']['prefix'], $content);
  205. mysql_query($content);
  206. break;
  207. case 'eval':
  208. eval ($content);
  209. break;
  210. case 'exec':
  211. include dirname(__FILE__) . '/../../' . $content;
  212. break;
  213. }
  214. }
  215. }
  216. }
  217. public function activate()
  218. {
  219. if ($this->isInstalled() && $this->active == 0)
  220. {
  221. $this->readPack();
  222. foreach ($this->cfiles as $file)
  223. {
  224. if ($file['content'] == null && file_exists($file['to']))
  225. throw new PackageException(self::E_APPLI);
  226. }
  227. foreach ($this->action as $file => $patchers)
  228. {
  229. $file = dirname(__FILE__) . '/../../' . $file;
  230. if (!file_exists($file) || !is_file($file))
  231. throw new PackageException(self::E_APPLI);
  232. $content = file_get_contents($file);
  233. foreach ($patchers as $patch)
  234. $patch->test($content);
  235. }
  236. /* Start Activation */
  237. foreach ($this->cdirectory as $dir)
  238. if (!file_exists($dir))
  239. mkdir($dir);
  240. foreach ($this->cfiles as $file)
  241. {
  242. if ($file['content'] != null)
  243. {
  244. file_put_contents($file['to'], $file['content']);
  245. }
  246. else
  247. $this->extractor->ExtractFile($file['from'], dirname($file['to']));
  248. }
  249. foreach ($this->action as $file => $patchers)
  250. {
  251. $file = dirname(__FILE__) . '/../../' . $file;
  252. $content = file_get_contents($file);
  253. foreach ($patchers as $patch)
  254. $content = $patch->doPatch($content);
  255. file_put_contents($file, $content);
  256. }
  257. $this->exec($this->install);
  258. mysql_query('UPDATE ' . $this->table . ' SET active = 1 WHERE file=\'' . $this->file . '\'');
  259. $this->active == 1;
  260. }
  261. else
  262. {
  263. throw new PackageException (self::E_ISACTIVE);
  264. }
  265. }
  266. public function deactivate()
  267. {
  268. if ($this->isInstalled() && $this->active == 1)
  269. {
  270. $this->readPack();
  271. foreach ($this->action as $file => $patchers)
  272. {
  273. $file = dirname(__FILE__) . '/../../' . $file;
  274. if (!file_exists($file) || !is_file($file))
  275. throw new PackageException(self::E_APPLI);
  276. $content = file_get_contents($file);
  277. foreach ($patchers as $patch)
  278. $patch->testUnpatch($content);
  279. }
  280. /* Start Activation */
  281. foreach ($this->cfiles as $file)
  282. {
  283. @unlink ($file['to']);
  284. }
  285. foreach ($this->cdirectory as $dir)
  286. if (file_exists($dir))
  287. rmdir($dir);
  288. foreach ($this->action as $file => $patchers)
  289. {
  290. $file = dirname(__FILE__) . '/../../' . $file;
  291. $content = file_get_contents($file);
  292. foreach ($patchers as $patch)
  293. $content = $patch->doUnPatch($content);
  294. file_put_contents($file, $content);
  295. }
  296. $this->exec($this->uninstall);
  297. mysql_query('UPDATE ' . $this->table . ' SET active = 0 WHERE file=\'' . $this->file . '\'');
  298. $this->active == 0;
  299. }
  300. else
  301. {
  302. throw new PackageException (self::E_NOTACTIVE);
  303. }
  304. }
  305. private function isInstalled ($error = true)
  306. {
  307. $cnt = mysql_query('SELECT * FROM ' . $this->table . ' WHERE file=\'' . $this->file . '\'');
  308. if (mysql_num_rows($cnt) == 1)
  309. {
  310. $pkg = mysql_fetch_assoc($cnt);
  311. $this->active = $pkg['active'];
  312. return true;
  313. }
  314. elseif ($error)
  315. {
  316. throw new PackageException (self::E_NOTINSTALLED);
  317. }
  318. else
  319. {
  320. return false;
  321. }
  322. }
  323. public function install()
  324. {
  325. $this->readHeader();
  326. mysql_query('INSERT INTO ' . $this->table . ' (file, name, author, link, active) VALUES ('
  327. . '\'' . $this->file . '\','
  328. . '\'' . $this->name . '\','
  329. . '\'' . $this->author . '\','
  330. . '\'' . $this->link . '\','
  331. . '\'0\')'
  332. );
  333. echo mysql_error();
  334. }
  335. public function uninstall()
  336. {
  337. if ($this->isInstalled())
  338. {
  339. if ($this->active == 1)
  340. $this->deactivate();
  341. mysql_query('DELETE FROM ' . $this->table . ' WHERE file = \'' . $this->file . '\' LIMIT 1');
  342. unlink($this->directory . $this->file);
  343. }
  344. else
  345. {
  346. throw new PackageException (self::E_ISACTIVE);
  347. }
  348. }
  349. }