PageRenderTime 74ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/libraries/joomla/installer/adapters/component.php

https://github.com/joebushi/joomla
PHP | 1488 lines | 888 code | 163 blank | 437 comment | 167 complexity | 5297988be7f15cd3fa8b2c5d92424137 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * @version $Id$
  4. * @copyright Copyright (C) 2005 - 2010 Open Source Matters, Inc. All rights reserved.
  5. * @license GNU General Public License version 2 or later; see LICENSE.txt
  6. */
  7. // No direct access
  8. defined('JPATH_BASE') or die;
  9. jimport('joomla.base.adapterinstance');
  10. /**
  11. * Component installer
  12. *
  13. * @package Joomla.Framework
  14. * @subpackage Installer
  15. * @since 1.5
  16. */
  17. class JInstallerComponent extends JAdapterInstance
  18. {
  19. protected $manifest = null;
  20. protected $name = null;
  21. protected $element = null;
  22. protected $oldAdminFiles = null;
  23. protected $oldFiles = null;
  24. protected $manifest_script = null;
  25. protected $install_script = null;
  26. /**
  27. * Custom install method for components
  28. *
  29. * @access public
  30. * @return boolean True on success
  31. * @since 1.5
  32. */
  33. public function install()
  34. {
  35. // Get a database connector object
  36. $db = &$this->parent->getDbo();
  37. // Get the extension manifest object
  38. $this->manifest = &$this->parent->getManifest();
  39. /**
  40. * ---------------------------------------------------------------------------------------------
  41. * Manifest Document Setup Section
  42. * ---------------------------------------------------------------------------------------------
  43. */
  44. // Set the extensions name
  45. $name = JFilterInput::getInstance()->clean((string)$this->manifest->name, 'cmd');
  46. $this->set('name', $name);
  47. $this->set('element', strtolower('com_'.$name));
  48. // Get the component description
  49. $this->parent->set('message', JText::_((string)$this->manifest->description));
  50. // Set the installation target paths
  51. $this->parent->setPath('extension_site', JPath::clean(JPATH_SITE.DS.'components'.DS.$this->get('element')));
  52. $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR.DS.'components'.DS.$this->get('element')));
  53. $this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
  54. /**
  55. * ---------------------------------------------------------------------------------------------
  56. * Basic Checks Section
  57. * ---------------------------------------------------------------------------------------------
  58. */
  59. // Make sure that we have an admin element
  60. if ( ! $this->manifest->administration)
  61. {
  62. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('The XML file did not contain an administration element'));
  63. return false;
  64. }
  65. /**
  66. * ---------------------------------------------------------------------------------------------
  67. * Filesystem Processing Section
  68. * ---------------------------------------------------------------------------------------------
  69. */
  70. /*
  71. * If the component site or admin directory already exists, then we will assume that the component is already
  72. * installed or another component is using that directory.
  73. */
  74. if (file_exists($this->parent->getPath('extension_site')) || file_exists($this->parent->getPath('extension_administrator')))
  75. {
  76. // look for an update function or update tag
  77. $updateElement = $this->manifest->update;
  78. // upgrade manually set
  79. // update function available
  80. // update tag detected
  81. if ($this->parent->getUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'update')) || $updateElement) {
  82. return $this->update(); // transfer control to the update function
  83. }
  84. else if (!$this->parent->getOverwrite())
  85. {
  86. // overwrite is set
  87. // we didn't have overwrite set, find an update function or find an update tag so lets call it safe
  88. if (file_exists($this->parent->getPath('extension_site'))) { // if the site exists say that
  89. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('Another component is already using directory').': "'.$this->parent->getPath('extension_site').'"');
  90. }
  91. else { // if the admin exists say that
  92. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('Another component is already using directory').': "'.$this->parent->getPath('extension_administrator').'"');
  93. }
  94. return false;
  95. }
  96. }
  97. /**
  98. * ---------------------------------------------------------------------------------------------
  99. * Installer Trigger Loading
  100. * ---------------------------------------------------------------------------------------------
  101. */
  102. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  103. $manifestScript = (string)$this->manifest->scriptfile;
  104. if ($manifestScript)
  105. {
  106. $manifestScriptFile = $this->parent->getPath('source').DS.$manifestScript;
  107. if (is_file($manifestScriptFile))
  108. {
  109. // load the file
  110. include_once $manifestScriptFile;
  111. }
  112. // Set the class name
  113. $classname = $this->get('element').'InstallerScript';
  114. if (class_exists($classname))
  115. {
  116. // create a new instance
  117. $this->parent->manifestClass = new $classname($this);
  118. // and set this so we can copy it later
  119. $this->set('manifest_script', $manifestScript);
  120. // Note: if we don't find the class, don't bother to copy the file
  121. }
  122. }
  123. // run preflight if possible (since we know we're not an update)
  124. ob_start();
  125. ob_implicit_flush(false);
  126. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight')) {
  127. $this->parent->manifestClass->preflight('install', $this);
  128. }
  129. $msg = ob_get_contents(); // create msg object; first use here
  130. ob_end_clean();
  131. // If the component directory does not exist, lets create it
  132. $created = false;
  133. if (!file_exists($this->parent->getPath('extension_site')))
  134. {
  135. if (!$created = JFolder::create($this->parent->getPath('extension_site')))
  136. {
  137. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('FAILED_TO_CREATE_DIRECTORY').': "'.$this->parent->getPath('extension_site').'"');
  138. return false;
  139. }
  140. }
  141. /*
  142. * Since we created the component directory and will want to remove it if we have to roll back
  143. * the installation, lets add it to the installation step stack
  144. */
  145. if ($created) {
  146. $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
  147. }
  148. // If the component admin directory does not exist, lets create it
  149. $created = false;
  150. if (!file_exists($this->parent->getPath('extension_administrator')))
  151. {
  152. if (!$created = JFolder::create($this->parent->getPath('extension_administrator')))
  153. {
  154. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('FAILED_TO_CREATE_DIRECTORY').': "'.$this->parent->getPath('extension_administrator').'"');
  155. // Install failed, rollback any changes
  156. $this->parent->abort();
  157. return false;
  158. }
  159. }
  160. /*
  161. * Since we created the component admin directory and we will want to remove it if we have to roll
  162. * back the installation, lets add it to the installation step stack
  163. */
  164. if ($created) {
  165. $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_administrator')));
  166. }
  167. // Copy site files
  168. if($this->manifest->files)
  169. {
  170. if ($this->parent->parseFiles($this->manifest->files) === false)
  171. {
  172. // Install failed, rollback any changes
  173. $this->parent->abort();
  174. return false;
  175. }
  176. }
  177. // Copy admin files
  178. if($this->manifest->administration->files)
  179. {
  180. if ($this->parent->parseFiles($this->manifest->administration->files, 1) === false)
  181. {
  182. // Install failed, rollback any changes
  183. $this->parent->abort();
  184. return false;
  185. }
  186. }
  187. // Parse optional tags
  188. $this->parent->parseMedia($this->manifest->media);
  189. $this->parent->parseLanguages($this->manifest->languages);
  190. $this->parent->parseLanguages($this->manifest->administration->languages, 1);
  191. // Deprecated install, remove after 1.6
  192. // If there is an install file, lets copy it.
  193. $installFile = (string)$this->manifest->installfile;
  194. if ($installFile)
  195. {
  196. // Make sure it hasn't already been copied (this would be an error in the xml install file)
  197. if (!file_exists($this->parent->getPath('extension_administrator').DS.$installFile) || $this->parent->getOverwrite())
  198. {
  199. $path['src'] = $this->parent->getPath('source').DS.$installFile;
  200. $path['dest'] = $this->parent->getPath('extension_administrator').DS.$installFile;
  201. if (!$this->parent->copyFiles(array ($path)))
  202. {
  203. // Install failed, rollback changes
  204. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Could_not_copy_PHP_install_file'));
  205. return false;
  206. }
  207. }
  208. $this->set('install_script', $installFile);
  209. }
  210. // Deprecated uninstall, remove after 1.6
  211. // If there is an uninstall file, lets copy it.
  212. $uninstallFile = (string)$this->manifest->uninstallfile;
  213. if ($uninstallFile)
  214. {
  215. // Make sure it hasn't already been copied (this would be an error in the xml install file)
  216. if (!file_exists($this->parent->getPath('extension_administrator').DS.$uninstallFile) || $this->parent->getOverwrite())
  217. {
  218. $path['src'] = $this->parent->getPath('source').DS.$uninstallFile;
  219. $path['dest'] = $this->parent->getPath('extension_administrator').DS.$uninstallFile;
  220. if (!$this->parent->copyFiles(array ($path)))
  221. {
  222. // Install failed, rollback changes
  223. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Could_not_copy_PHP_uninstall_file'));
  224. return false;
  225. }
  226. }
  227. }
  228. // If there is a manifest script, lets copy it.
  229. if ($this->get('manifest_script'))
  230. {
  231. $path['src'] = $this->parent->getPath('source').DS.$this->get('manifest_script');
  232. $path['dest'] = $this->parent->getPath('extension_administrator').DS.$this->get('manifest_script');
  233. if (!file_exists($path['dest']) || $this->parent->getOverwrite())
  234. {
  235. if (!$this->parent->copyFiles(array ($path)))
  236. {
  237. // Install failed, rollback changes
  238. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Could not copy PHP manifest file.'));
  239. return false;
  240. }
  241. }
  242. }
  243. /**
  244. * ---------------------------------------------------------------------------------------------
  245. * Database Processing Section
  246. * ---------------------------------------------------------------------------------------------
  247. */
  248. /*
  249. * Let's run the install queries for the component
  250. * If Joomla 1.5 compatible, with discreet sql files - execute appropriate
  251. * file for utf-8 support or non-utf-8 support
  252. */
  253. // try for Joomla 1.5 type queries
  254. // second argument is the utf compatible version attribute
  255. $utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
  256. if ($utfresult === false)
  257. {
  258. // Install failed, rollback changes
  259. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('SQLERRORORFILE')." ".$db->stderr(true));
  260. return false;
  261. }
  262. /**
  263. * ---------------------------------------------------------------------------------------------
  264. * Custom Installation Script Section
  265. * ---------------------------------------------------------------------------------------------
  266. */
  267. /*
  268. * If we have an install script, lets include it, execute the custom
  269. * install method, and append the return value from the custom install
  270. * method to the installation message.
  271. */
  272. // start legacy support
  273. if ($this->get('install_script'))
  274. {
  275. if (is_file($this->parent->getPath('extension_administrator').DS.$this->get('install_script')) || $this->parent->getOverwrite())
  276. {
  277. ob_start();
  278. ob_implicit_flush(false);
  279. require_once $this->parent->getPath('extension_administrator').DS.$this->get('install_script');
  280. if (function_exists('com_install'))
  281. {
  282. if (com_install() === false)
  283. {
  284. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Custom install routine failure'));
  285. return false;
  286. }
  287. }
  288. $msg .= ob_get_contents(); // append messages
  289. ob_end_clean();
  290. }
  291. }
  292. // end legacy support
  293. // Start Joomla! 1.6
  294. ob_start();
  295. ob_implicit_flush(false);
  296. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'install')) {
  297. $this->parent->manifestClass->install($this);
  298. }
  299. $msg .= ob_get_contents(); // append messages
  300. ob_end_clean();
  301. /**
  302. * ---------------------------------------------------------------------------------------------
  303. * Finalization and Cleanup Section
  304. * ---------------------------------------------------------------------------------------------
  305. */
  306. // Add an entry to the extension table with a whole heap of defaults
  307. $row = & JTable::getInstance('extension');
  308. $row->set('name', $this->get('name'));
  309. $row->set('type', 'component');
  310. $row->set('element', $this->get('element'));
  311. $row->set('folder', ''); // There is no folder for components
  312. $row->set('enabled', 1);
  313. $row->set('protected', 0);
  314. $row->set('access', 0);
  315. $row->set('client_id', 0);
  316. $row->set('params', $this->parent->getParams());
  317. $row->set('manifest_cache', $this->parent->generateManifestCache());
  318. if (!$row->store())
  319. {
  320. // Install failed, roll back changes
  321. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
  322. return false;
  323. }
  324. // Time to build the admin menus
  325. $this->_buildAdminMenus();
  326. // Clobber any possible pending updates
  327. $update = &JTable::getInstance('update');
  328. $uid = $update->find(Array('element'=>$this->get('element'),
  329. 'type'=>'component',
  330. 'client_id'=>'',
  331. 'folder'=>''));
  332. if ($uid) {
  333. $update->delete($uid);
  334. }
  335. // We will copy the manifest file to its appropriate place.
  336. if (!$this->parent->copyManifest())
  337. {
  338. // Install failed, rollback changes
  339. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('COULD_NOT_COPY_SETUP_FILE'));
  340. return false;
  341. }
  342. //TODO: Register the component container just under root in the assets table.
  343. // And now we run the postflight
  344. ob_start();
  345. ob_implicit_flush(false);
  346. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'postflight')) $this->parent->manifestClass->postflight('install', $this);
  347. $msg .= ob_get_contents(); // append messages
  348. ob_end_clean();
  349. if ($msg != '') {
  350. $this->parent->set('extension_message', $msg);
  351. }
  352. return $row->extension_id;
  353. }
  354. /**
  355. * Custom update method for components
  356. *
  357. * @access public
  358. * @return boolean True on success
  359. * @since 1.5
  360. */
  361. function update()
  362. {
  363. // Get a database connector object
  364. $db = &$this->parent->getDbo();
  365. // set the overwrite setting
  366. $this->parent->setOverwrite(true);
  367. // Get the extension manifest object
  368. $this->manifest = $this->parent->getManifest();
  369. /**
  370. * ---------------------------------------------------------------------------------------------
  371. * Manifest Document Setup Section
  372. * ---------------------------------------------------------------------------------------------
  373. */
  374. // Set the extensions name
  375. $name = JFilterInput::getInstance()->clean((string)$this->manifest->name, 'cmd');
  376. $element = strtolower('com_'.$name);
  377. $this->set('name', $name);
  378. $this->set('element', $element);
  379. // Get the component description
  380. $description = (string)$this->manifest->description;
  381. if ($description) {
  382. $this->parent->set('message', JText::_($description));
  383. }
  384. else {
  385. $this->parent->set('message', '');
  386. }
  387. // Set the installation target paths
  388. $this->parent->setPath('extension_site', JPath::clean(JPATH_SITE.DS."components".DS.$this->get('element')));
  389. $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR.DS."components".DS.$this->get('element')));
  390. $this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
  391. /**
  392. * Hunt for the original XML file
  393. */
  394. $oldmanifest = null;
  395. $tmpInstaller = new JInstaller(); // create a new installer because findManifest sets stuff
  396. // look in the administrator first
  397. $tmpInstaller->setPath('source', $this->parent->getPath('extension_administrator'));
  398. if (!$tmpInstaller->findManifest())
  399. {
  400. // then the site
  401. $tmpInstaller->setPath('source', $this->parent->getPath('extension_site'));
  402. if ($tmpInstaller->findManifest()) {
  403. $old_manifest = $tmpInstaller->getManifest();
  404. }
  405. }
  406. else
  407. {
  408. $old_manifest = $tmpInstaller->getManifest();
  409. }
  410. // should do this above perhaps?
  411. if ($old_manifest)
  412. {
  413. $this->oldAdminFiles = $old_manifest->administration->files;
  414. $this->oldFiles = $old_manifest->files;
  415. }
  416. else
  417. {
  418. $this->oldAdminFiles = null;
  419. $this->oldFiles = null;
  420. }
  421. /**
  422. * ---------------------------------------------------------------------------------------------
  423. * Basic Checks Section
  424. * ---------------------------------------------------------------------------------------------
  425. */
  426. // Make sure that we have an admin element
  427. if ( ! $this->manifest->administration)
  428. {
  429. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Update').': '.JText::_('The XML file did not contain an administration element'));
  430. return false;
  431. }
  432. /**
  433. * ---------------------------------------------------------------------------------------------
  434. * Installer Trigger Loading
  435. * ---------------------------------------------------------------------------------------------
  436. */
  437. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  438. $manifestScript = (string)$this->manifest->scriptfile;
  439. if ($manifestScript)
  440. {
  441. $manifestScriptFile = $this->parent->getPath('source').DS.$manifestScript;
  442. if (is_file($manifestScriptFile))
  443. {
  444. // load the file
  445. include_once $manifestScriptFile;
  446. }
  447. // Set the class name
  448. $classname = $element.'InstallerScript';
  449. if (class_exists($classname))
  450. {
  451. // create a new instance
  452. $this->parent->manifestClass = new $classname($this);
  453. // and set this so we can copy it later
  454. $this->set('manifest_script', $manifestScript);
  455. // Note: if we don't find the class, don't bother to copy the file
  456. }
  457. }
  458. // run preflight if possible (since we know we're not an update)
  459. ob_start();
  460. ob_implicit_flush(false);
  461. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight')) {
  462. $this->parent->manifestClass->preflight('update', $this);
  463. }
  464. $msg = ob_get_contents(); // create msg object; first use here
  465. ob_end_clean();
  466. /**
  467. * ---------------------------------------------------------------------------------------------
  468. * Filesystem Processing Section
  469. * ---------------------------------------------------------------------------------------------
  470. */
  471. // If the component directory does not exist, lets create it
  472. $created = false;
  473. if (!file_exists($this->parent->getPath('extension_site')))
  474. {
  475. if (!$created = JFolder::create($this->parent->getPath('extension_site')))
  476. {
  477. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Update').': '.JText::_('FAILED_TO_CREATE_DIRECTORY').': "'.$this->parent->getPath('extension_site').'"');
  478. return false;
  479. }
  480. }
  481. /*
  482. * Since we created the component directory and will want to remove it if we have to roll back
  483. * the installation, lets add it to the installation step stack
  484. */
  485. if ($created) {
  486. $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_site')));
  487. }
  488. // If the component admin directory does not exist, lets create it
  489. $created = false;
  490. if (!file_exists($this->parent->getPath('extension_administrator')))
  491. {
  492. if (!$created = JFolder::create($this->parent->getPath('extension_administrator')))
  493. {
  494. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Update').': '.JText::_('FAILED_TO_CREATE_DIRECTORY').': "'.$this->parent->getPath('extension_administrator').'"');
  495. // Install failed, rollback any changes
  496. $this->parent->abort();
  497. return false;
  498. }
  499. }
  500. /*
  501. * Since we created the component admin directory and we will want to remove it if we have to roll
  502. * back the installation, lets add it to the installation step stack
  503. */
  504. if ($created) {
  505. $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_administrator')));
  506. }
  507. // Find files to copy
  508. if ($this->manifest->files)
  509. {
  510. if ($this->parent->parseFiles($this->manifest->files, 0, $this->oldFiles) === false)
  511. {
  512. // Install failed, rollback any changes
  513. $this->parent->abort();
  514. return false;
  515. }
  516. }
  517. if ($this->manifest->administration->files)
  518. {
  519. if ($this->parent->parseFiles($this->manifest->administration->files, 1, $this->oldAdminFiles) === false)
  520. {
  521. // Install failed, rollback any changes
  522. $this->parent->abort();
  523. return false;
  524. }
  525. }
  526. // Parse optional tags
  527. $this->parent->parseMedia($this->manifest->media);
  528. $this->parent->parseLanguages($this->manifest->languages);
  529. $this->parent->parseLanguages($this->manifest->administration->languages, 1);
  530. // Deprecated install, remove after 1.6
  531. // If there is an install file, lets copy it.
  532. $installFile = (string)$this->manifest->installfile;
  533. if ($installFile)
  534. {
  535. // Make sure it hasn't already been copied (this would be an error in the xml install file)
  536. if (!file_exists($this->parent->getPath('extension_administrator').DS.$installFile) || $this->parent->getOverwrite())
  537. {
  538. $path['src'] = $this->parent->getPath('source').DS.$installFile;
  539. $path['dest'] = $this->parent->getPath('extension_administrator').DS.$installFile;
  540. if (!$this->parent->copyFiles(array ($path)))
  541. {
  542. // Install failed, rollback changes
  543. $this->parent->abort(JText::_('Component').' '.JText::_('Update').': '.JText::_('Could_not_copy_PHP_install_file'));
  544. return false;
  545. }
  546. }
  547. $this->set('install_script', $installFile);
  548. }
  549. // Deprecated uninstall, remove after 1.6
  550. // If there is an uninstall file, lets copy it.
  551. $uninstallFile = (string)$this->manifest->uninstallfile;
  552. if ($uninstallFile)
  553. {
  554. // Make sure it hasn't already been copied (this would be an error in the xml install file)
  555. if (!file_exists($this->parent->getPath('extension_administrator').DS.$uninstallFile) || $this->parent->getOverwrite())
  556. {
  557. $path['src'] = $this->parent->getPath('source').DS.$uninstallFile;
  558. $path['dest'] = $this->parent->getPath('extension_administrator').DS.$uninstallFile;
  559. if (!$this->parent->copyFiles(array ($path)))
  560. {
  561. // Install failed, rollback changes
  562. $this->parent->abort(JText::_('Component').' '.JText::_('Update').': '.JText::_('Could_not_copy_PHP_uninstall_file'));
  563. return false;
  564. }
  565. }
  566. }
  567. // If there is a manifest script, lets copy it.
  568. if ($this->get('manifest_script'))
  569. {
  570. $path['src'] = $this->parent->getPath('source').DS.$this->get('manifest_script');
  571. $path['dest'] = $this->parent->getPath('extension_administrator').DS.$this->get('manifest_script');
  572. if (!file_exists($path['dest']) || $this->parent->getOverwrite())
  573. {
  574. if (!$this->parent->copyFiles(array ($path)))
  575. {
  576. // Install failed, rollback changes
  577. $this->parent->abort(JText::_('Component').' '.JText::_('Update').': '.JText::_('Could not copy PHP manifest file.'));
  578. return false;
  579. }
  580. }
  581. }
  582. /**
  583. * ---------------------------------------------------------------------------------------------
  584. * Database Processing Section
  585. * ---------------------------------------------------------------------------------------------
  586. */
  587. /*
  588. * Let's run the install queries for the component
  589. * If Joomla 1.5 compatible, with discreet sql files - execute appropriate
  590. * file for utf-8 support or non-utf-8 support
  591. */
  592. // second argument is the utf compatible version attribute
  593. $utfresult = $this->parent->parseSQLFiles($this->manifest->update->sql);
  594. if ($utfresult === false)
  595. {
  596. // Install failed, rollback changes
  597. $this->parent->abort(JText::_('Component').' '.JText::_('Update').': '.JText::_('SQLERRORORFILE')." ".$db->stderr(true));
  598. return false;
  599. }
  600. // Time to build the admin menus
  601. $this->_buildAdminMenus();
  602. /**
  603. * ---------------------------------------------------------------------------------------------
  604. * Custom Installation Script Section
  605. * ---------------------------------------------------------------------------------------------
  606. */
  607. /*
  608. * If we have an update script, lets include it, execute the custom
  609. * update method, and append the return value from the custom update
  610. * method to the installation message.
  611. */
  612. // Start Joomla! 1.6
  613. ob_start();
  614. ob_implicit_flush(false);
  615. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'update')) {
  616. $this->parent->manifestClass->update($this);
  617. }
  618. $msg .= ob_get_contents(); // append messages
  619. ob_end_clean();
  620. /**
  621. * ---------------------------------------------------------------------------------------------
  622. * Finalization and Cleanup Section
  623. * ---------------------------------------------------------------------------------------------
  624. */
  625. // Clobber any possible pending updates
  626. $update = &JTable::getInstance('update');
  627. $uid = $update->find(Array('element'=>$this->get('element'),
  628. 'type'=>'component',
  629. 'client_id'=>'',
  630. 'folder'=>''));
  631. if ($uid) $update->delete($uid);
  632. // Update an entry to the extension table
  633. $row = & JTable::getInstance('extension');
  634. $eid = $row->find(Array('element'=>strtolower($this->get('element')),
  635. 'type'=>'component'));
  636. if ($eid) {
  637. $row->load($eid);
  638. }
  639. else
  640. {
  641. // set the defaults
  642. $row->folder = ''; // There is no folder for components
  643. $row->enabled = 1;
  644. $row->protected = 0;
  645. $row->access = 1;
  646. $row->client_id = 0;
  647. $row->params = $this->parent->getParams();
  648. }
  649. $row->name = $this->get('name');
  650. $row->type = 'component';
  651. $row->element = $this->get('element');
  652. $row->manifest_cache = $this->parent->generateManifestCache();
  653. if (!$row->store())
  654. {
  655. // Install failed, roll back changes
  656. $this->parent->abort(JText::_('Component').' '.JText::_('Update').': '.$db->stderr(true));
  657. return false;
  658. }
  659. // We will copy the manifest file to its appropriate place.
  660. if (!$this->parent->copyManifest())
  661. {
  662. // Install failed, rollback changes
  663. $this->parent->abort(JText::_('Component').' '.JText::_('Update').': '.JText::_('COULD_NOT_COPY_SETUP_FILE'));
  664. return false;
  665. }
  666. // And now we run the postflight
  667. ob_start();
  668. ob_implicit_flush(false);
  669. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'postflight')) {
  670. $this->parent->manifestClass->postflight('update', $this);
  671. }
  672. $msg .= ob_get_contents(); // append messages
  673. ob_end_clean();
  674. if ($msg != '') {
  675. $this->parent->set('extension_message', $msg);
  676. }
  677. return $row->extension_id;
  678. }
  679. /**
  680. * Custom uninstall method for components
  681. *
  682. * @access public
  683. * @param int $id The unique extension id of the component to uninstall
  684. * @return mixed Return value for uninstall method in component uninstall file
  685. * @since 1.0
  686. */
  687. public function uninstall($id)
  688. {
  689. // Initialise variables.
  690. $db = &$this->parent->getDbo();
  691. $row = null;
  692. $retval = true;
  693. // First order of business will be to load the component object table from the database.
  694. // This should give us the necessary information to proceed.
  695. $row = & JTable::getInstance('extension');
  696. if (!$row->load((int) $id)) {
  697. JError::raiseWarning(100, JText::_('ERRORUNKOWNEXTENSION'));
  698. return false;
  699. }
  700. // Is the component we are trying to uninstall a core one?
  701. // Because that is not a good idea...
  702. if ($row->protected) {
  703. JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::sprintf('WARNCORECOMPONENT', $row->name)."<br />".JText::_('WARNCORECOMPONENT2'));
  704. return false;
  705. }
  706. // Get the admin and site paths for the component
  707. $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR.DS.'components'.DS.$row->element));
  708. $this->parent->setPath('extension_site', JPath::clean(JPATH_SITE.DS.'components'.DS.$row->element));
  709. $this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
  710. // Attempt to load the admin language file; might have uninstall strings
  711. $lang = &JFactory::getLanguage();
  712. // 1.6
  713. $lang->load($row->element, $this->parent->getPath('extension_administrator'));
  714. // 1.5 or Core
  715. $lang->load($row->element);
  716. /**
  717. * ---------------------------------------------------------------------------------------------
  718. * Manifest Document Setup Section
  719. * ---------------------------------------------------------------------------------------------
  720. */
  721. // Find and load the XML install file for the component
  722. $this->parent->setPath('source', $this->parent->getPath('extension_administrator'));
  723. // Get the package manifest object
  724. $this->manifest = $this->parent->getManifest();
  725. if ( ! $this->manifest)
  726. {
  727. // Make sure we delete the folders if no manifest exists
  728. JFolder::delete($this->parent->getPath('extension_administrator'));
  729. JFolder::delete($this->parent->getPath('extension_site'));
  730. // Remove the menu
  731. $this->_removeAdminMenus($row);
  732. // Raise a warning
  733. JError::raiseWarning(100, JText::_('ERRORREMOVEMANUALLY'));
  734. // Return
  735. return false;
  736. }
  737. // Set the extensions name
  738. $name = JFilterInput::getInstance()->clean((string)$this->manifest->name, 'cmd');
  739. $this->set('name', $name);
  740. /**
  741. * ---------------------------------------------------------------------------------------------
  742. * Installer Trigger Loading and Uninstall
  743. * ---------------------------------------------------------------------------------------------
  744. */
  745. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  746. $scriptFile = (string)$this->manifest->scriptfile;
  747. if ($scriptFile)
  748. {
  749. $manifestScriptFile = $this->parent->getPath('source').DS.$scriptFile;
  750. if (is_file($manifestScriptFile))
  751. {
  752. // load the file
  753. include_once $manifestScriptFile;
  754. }
  755. // Set the class name
  756. $classname = $row->element.'InstallerScript';
  757. if (class_exists($classname))
  758. {
  759. // create a new instance
  760. $this->parent->manifestClass = new $classname($this);
  761. // and set this so we can copy it later
  762. $this->set('manifest_script', $scriptFile);
  763. // Note: if we don't find the class, don't bother to copy the file
  764. }
  765. }
  766. ob_start();
  767. ob_implicit_flush(false);
  768. // run uninstall if possible
  769. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'uninstall')) $this->parent->manifestClass->uninstall($this);
  770. $msg = ob_get_contents();
  771. ob_end_clean();
  772. /**
  773. * ---------------------------------------------------------------------------------------------
  774. * Custom Uninstallation Script Section; Legacy 1.5 Support
  775. * ---------------------------------------------------------------------------------------------
  776. */
  777. // Now lets load the uninstall file if there is one and execute the uninstall function if it exists.
  778. $uninstallFile = (string)$this->manifest->uninstallfile;
  779. if ($uninstallFile)
  780. {
  781. // Element exists, does the file exist?
  782. if (is_file($this->parent->getPath('extension_administrator').DS.$uninstallFile))
  783. {
  784. ob_start();
  785. ob_implicit_flush(false);
  786. require_once $this->parent->getPath('extension_administrator').DS.$uninstallFile;
  787. if (function_exists('com_uninstall'))
  788. {
  789. if (com_uninstall() === false)
  790. {
  791. JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('Custom Uninstall script unsuccessful'));
  792. $retval = false;
  793. }
  794. }
  795. $msg .= ob_get_contents(); // append this in case there was something else
  796. ob_end_clean();
  797. }
  798. }
  799. if ($msg != '') {
  800. $this->parent->set('extension_message', $msg);
  801. }
  802. /**
  803. * ---------------------------------------------------------------------------------------------
  804. * Database Processing Section
  805. * ---------------------------------------------------------------------------------------------
  806. */
  807. /*
  808. * Let's run the uninstall queries for the component
  809. * If Joomla 1.5 compatible, with discreet sql files - execute appropriate
  810. * file for utf-8 support or non-utf support
  811. */
  812. // try for Joomla 1.5 type queries
  813. // second argument is the utf compatible version attribute
  814. $utfresult = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
  815. if ($utfresult === false)
  816. {
  817. // Install failed, rollback changes
  818. JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('SQLERRORORFILE')." ".$db->stderr(true));
  819. $retval = false;
  820. }
  821. $this->_removeAdminMenus($row);
  822. /**
  823. * ---------------------------------------------------------------------------------------------
  824. * Filesystem Processing Section
  825. * ---------------------------------------------------------------------------------------------
  826. */
  827. // Let's remove language files and media in the JROOT/images/ folder that are
  828. // associated with the component we are uninstalling
  829. $this->parent->removeFiles($this->manifest->media);
  830. $this->parent->removeFiles($this->manifest->languages);
  831. $this->parent->removeFiles($this->manifest->administration->languages, 1);
  832. // Clobber any possible pending updates
  833. $update = &JTable::getInstance('update');
  834. $uid = $update->find(Array('element'=>$row->element,
  835. 'type'=>'component',
  836. 'client_id'=>'',
  837. 'folder'=>''));
  838. if ($uid) $update->delete($uid);
  839. // Now we need to delete the installation directories. This is the final step in uninstalling the component.
  840. if (trim($row->element))
  841. {
  842. // Delete the component site directory
  843. if (is_dir($this->parent->getPath('extension_site')))
  844. {
  845. if (!JFolder::delete($this->parent->getPath('extension_site')))
  846. {
  847. JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('UNABLE_TO_REMOVE_THE_COMPONENT_SITE_DIRECTORY'));
  848. $retval = false;
  849. }
  850. }
  851. // Delete the component admin directory
  852. if (is_dir($this->parent->getPath('extension_administrator')))
  853. {
  854. if (!JFolder::delete($this->parent->getPath('extension_administrator')))
  855. {
  856. JError::raiseWarning(100, JText::_('Component').' '.JText::_('Uninstall').': '.JText::_('UNABLE_TO_REMOVE_THE_COMPONENT_ADMIN_DIRECTORY'));
  857. $retval = false;
  858. }
  859. }
  860. // Now we will no longer need the extension object, so lets delete it and free up memory
  861. $row->delete($row->extension_id);
  862. unset ($row);
  863. return $retval;
  864. }
  865. else
  866. {
  867. // No component option defined... cannot delete what we don't know about
  868. JError::raiseWarning(100, 'Component Uninstall: Option field empty, cannot remove files');
  869. return false;
  870. }
  871. }
  872. /**
  873. * Method to build menu database entries for a component
  874. *
  875. * @access private
  876. * @return boolean True if successful
  877. * @since 1.5
  878. */
  879. protected function _buildAdminMenus()
  880. {
  881. // Initialise variables.
  882. $db = &$this->parent->getDbo();
  883. $table = &JTable::getInstance('menu');
  884. $option = $this->get('element');
  885. // If a component exists with this option in the table then we don't need to add menus
  886. $query = new JQuery();
  887. $query->select('m.id, e.extension_id');
  888. $query->from('#__menu AS m');
  889. $query->leftJoin('#__extensions AS e ON m.component_id = e.extension_id');
  890. $query->where('m.parent_id = 1');
  891. $query->where('e.element = '.$db->quote($option));
  892. $db->setQuery($query);
  893. $componentrow = $db->loadObject();
  894. // Check if menu items exist
  895. if ($componentrow)
  896. {
  897. // Don't do anything if overwrite has not been enabled
  898. if (! $this->parent->getOverwrite()) {
  899. return true;
  900. }
  901. // Remove existing menu items if overwrite has been enabled
  902. if ($option)
  903. {
  904. $this->_removeAdminMenus($componentrow);// If something goes wrong, theres no way to rollback TODO: Search for better solution
  905. }
  906. } else {
  907. // Lets Find the extension id
  908. $query = new JQuery();
  909. $query->select('e.extension_id');
  910. $query->from('#__extensions AS e');
  911. $query->where('e.element = '.$db->quote($option));
  912. $db->setQuery($query);
  913. $component_id = $db->loadResult(); // TODO Find Some better way to discover the component_id
  914. }
  915. // Ok, now its time to handle the menus. Start with the component root menu, then handle submenus.
  916. $menuElement = $this->manifest->administration->menu;
  917. if ($menuElement)
  918. {
  919. $data = array();
  920. $data['menutype'] = '_adminmenu';
  921. $data['title'] = $option;
  922. $data['alias'] = (string)$menuElement;
  923. $data['link'] = 'index.php?option='.$option;
  924. $data['type'] = 'component';
  925. $data['published'] = 0;
  926. $data['parent_id'] = 1;
  927. $data['component_id'] = $component_id;
  928. $data['img'] = ((string)$menuElement->attributes()->img) ? (string)$menuElement->attributes()->img : 'class:component';
  929. $data['home'] = 0;
  930. if(!$table->setLocation(1, 'last-child') || !$table->bind($data) || !$table->check() || !$table->store())
  931. {
  932. // Install failed, rollback changes
  933. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
  934. return false;
  935. }
  936. /*
  937. * Since we have created a menu item, we add it to the installation step stack
  938. * so that if we have to rollback the changes we can undo it.
  939. */
  940. $this->parent->pushStep(array ('type' => 'menu'));
  941. }
  942. else
  943. {
  944. // No menu element was specified, Let's make a generic menu item
  945. $data = array();
  946. $data['menutype'] = '_adminmenu';
  947. $data['title'] = $option;
  948. $data['alias'] = $option;
  949. $data['link'] = 'index.php?option='.$option;
  950. $data['type'] = 'component';
  951. $data['published'] = 0;
  952. $data['parent_id'] = 1;
  953. $data['component_id'] = $component_id;
  954. $data['img'] = 'class:component';
  955. $data['home'] = 0;
  956. if(!$table->bind($data) || !$table->check() || !$table->store())
  957. {
  958. // Install failed, rollback changes
  959. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
  960. return false;
  961. }
  962. /*
  963. * Since we have created a menu item, we add it to the installation step stack
  964. * so that if we have to rollback the changes we can undo it.
  965. */
  966. $this->parent->pushStep(array ('type' => 'menu'));
  967. }
  968. /*
  969. * Process SubMenus
  970. */
  971. if ( ! $this->manifest->administration->submenu) {
  972. return true;
  973. }
  974. foreach ($this->manifest->administration->submenu->menu as $child)
  975. {
  976. $data = array();
  977. $data['menutype'] = '_adminmenu';
  978. $data['title'] = ((string)$child->attributes()->view) ? $option.'_'.$child->attributes()->view : $option;
  979. $data['alias'] = (string)$child;
  980. $data['type'] = 'component';
  981. $data['published'] = 0;
  982. $data['parent_id'] = 1;
  983. $data['component_id'] = $component_id;
  984. $data['img'] = ((string)$child->attributes()->img) ? (string)$child->attributes()->img : 'class:component';
  985. $data['home'] = 0;
  986. // Set the sub menu link
  987. if ((string)$child->attributes()->link) {
  988. $data['link'] = (string)$child->attributes()->link;
  989. }
  990. else
  991. {
  992. $request = array();
  993. if ((string)$child->attributes()->act) {
  994. $request[] = 'act='.$child->attributes()->act;
  995. }
  996. if ((string)$child->attributes()->task) {
  997. $request[] = 'task='.$child->attributes()->task;
  998. }
  999. if ((string)$child->attributes()->controller) {
  1000. $request[] = 'controller='.$child->attributes()->controller;
  1001. }
  1002. if ((string)$child->attributes()->view) {
  1003. $request[] = 'view='.$child->attributes()->view;
  1004. }
  1005. if ((string)$child->attributes()->layout) {
  1006. $request[] = 'layout='.$child->attributes()->layout;
  1007. }
  1008. if ((string)$child->attributes()->sub) {
  1009. $request[] = 'sub='.$child->attributes()->sub;
  1010. }
  1011. $qstring = (count($request)) ? '&'.implode('&',$request) : '';
  1012. $data['link'] = "index.php?option=".$option.$qstring;
  1013. }
  1014. if(!$table->bind($data) || !$table->check() || !$table->store())
  1015. {
  1016. // Install failed, rollback changes
  1017. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.$db->stderr(true));
  1018. return false;
  1019. }
  1020. /*
  1021. * Since we have created a menu item, we add it to the installation step stack
  1022. * so that if we have to rollback the changes we can undo it.
  1023. */
  1024. $this->parent->pushStep(array ('type' => 'menu'));
  1025. }
  1026. }
  1027. /**
  1028. * Method to remove admin menu references to a component
  1029. *
  1030. * @access private
  1031. * @param object $component Component table object
  1032. * @return boolean True if successful
  1033. * @since 1.5
  1034. */
  1035. protected function _removeAdminMenus(&$row)
  1036. {
  1037. // Initialise Variables
  1038. $db = &$this->parent->getDbo();
  1039. $table = &JTable::getInstance('menu');
  1040. $id = $row->extension_id;
  1041. // Get the ids of the menu items
  1042. $query = new JQuery();
  1043. $query->select('id');
  1044. $query->from('#__menu');
  1045. $query->where('`menutype` = "_adminmenu"');
  1046. $query->where('`component_id` = "'.$id.'"');
  1047. $db->setQuery($query);
  1048. $ids = $db->loadResultArray();
  1049. // Check for error
  1050. if($error = $db->getErrorMsg() || empty($ids)){
  1051. JError::raiseWarning('Some_code_here', 'Some_message_here');
  1052. return false;
  1053. } else {
  1054. // Iterate the items to delete each one.
  1055. foreach($ids as $menuid){
  1056. if (!$table->delete((int) $menuid))
  1057. {
  1058. $this->setError($table->getError());
  1059. return false;
  1060. }
  1061. }
  1062. // Rebuild the whole tree
  1063. $table->rebuild();
  1064. }
  1065. return true;
  1066. }
  1067. /**
  1068. * Custom rollback method
  1069. * - Roll back the component menu item
  1070. *
  1071. * @access public
  1072. * @param array $arg Installation step to rollback
  1073. * @return boolean True on success
  1074. * @since 1.5
  1075. */
  1076. protected function _rollback_menu()
  1077. {
  1078. return true;
  1079. }
  1080. function discover()
  1081. {
  1082. $results = Array();
  1083. $site_components = JFolder::folders(JPATH_SITE.DS.'components');
  1084. $admin_components = JFolder::folders(JPATH_ADMINISTRATOR.DS.'components');
  1085. foreach ($site_components as $component)
  1086. {
  1087. if (file_exists(JPATH_SITE.DS.'components'.DS.$component.DS.str_replace('com_','', $component).'.xml'))
  1088. {
  1089. $extension = &JTable::getInstance('extension');
  1090. $extension->set('type', 'component');
  1091. $extension->set('client_id', 0);
  1092. $extension->set('element', $component);
  1093. $extension->set('name', $component);
  1094. $extension->set('state', -1);
  1095. $results[] = $extension;
  1096. }
  1097. }
  1098. foreach ($admin_components as $component)
  1099. {
  1100. if (file_exists(JPATH_ADMINISTRATOR.DS.'components'.DS.$component.DS.str_replace('com_','', $component).'.xml'))
  1101. {
  1102. $extension = &JTable::getInstance('extension');
  1103. $extension->set('type', 'component');
  1104. $extension->set('client_id', 1);
  1105. $extension->set('element', $component);
  1106. $extension->set('name', $component);
  1107. $extension->set('state', -1);
  1108. $results[] = $extension;
  1109. }
  1110. }
  1111. return $results;
  1112. }
  1113. function discover_install()
  1114. {
  1115. // Need to find to find where the XML file is since we don't store this normally
  1116. $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
  1117. $short_element = str_replace('com_', '', $this->parent->extension->element);
  1118. $manifestPath = $client->path . DS . 'components'. DS . $this->parent->extension->element . DS . $short_element . '.xml';
  1119. $this->parent->manifest = $this->parent->isManifest($manifestPath);
  1120. $this->parent->setPath('manifest', $manifestPath);
  1121. $this->parent->setPath('source', $client->path . DS . 'components'. DS . $this->parent->extension->element);
  1122. $this->parent->setPath('extension_root', $this->parent->getPath('source'));
  1123. $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
  1124. $this->parent->extension->manifest_cache = serialize($manifest_details);
  1125. $this->parent->extension->state = 0;
  1126. $this->parent->extension->name = $manifest_details['name'];
  1127. $this->parent->extension->enabled = 1;
  1128. $this->parent->extension->params = $this->parent->getParams();
  1129. try {
  1130. $this->parent->extension->store();
  1131. }
  1132. catch(JException $e)
  1133. {
  1134. JError::raiseWarning(101, JText::_('Component').' '.JText::_('Discover Install').': '.JText::_('Failed to store extension details'));
  1135. return false;
  1136. }
  1137. // now we need to run any SQL it has, languages, media or menu stuff
  1138. // Get a database connector object
  1139. $db = &$this->parent->getDbo();
  1140. // Get the extension manifest object
  1141. $this->manifest = $this->parent->getManifest();
  1142. /**
  1143. * ---------------------------------------------------------------------------------------------
  1144. * Manifest Document Setup Section
  1145. * ---------------------------------------------------------------------------------------------
  1146. */
  1147. // Set the extensions name
  1148. $name = JFilterInput::getInstance()->clean((string)$this->manifest->name, 'cmd');
  1149. $element = strtolower('com_'.$name);
  1150. $this->set('name', $name);
  1151. $this->set('element', $element);
  1152. // Get the component description
  1153. $description = (string)$this->manifest->description;
  1154. if ($description) {
  1155. $this->parent->set('message', JText::_((string)$description));
  1156. }
  1157. else {
  1158. $this->parent->set('message', '');
  1159. }
  1160. // Set the installation target paths
  1161. $this->parent->setPath('extension_site', JPath::clean(JPATH_SITE.DS."components".DS.$this->get('element')));
  1162. $this->parent->setPath('extension_administrator', JPath::clean(JPATH_ADMINISTRATOR.DS."components".DS.$this->get('element')));
  1163. $this->parent->setPath('extension_root', $this->parent->getPath('extension_administrator')); // copy this as its used as a common base
  1164. /**
  1165. * ---------------------------------------------------------------------------------------------
  1166. * Basic Checks Section
  1167. * ---------------------------------------------------------------------------------------------
  1168. */
  1169. // Make sure that we have an admin element
  1170. if ( ! $this->manifest->administration)
  1171. {
  1172. JError::raiseWarning(1, JText::_('Component').' '.JText::_('Install').': '.JText::_('The XML file did not contain an administration element'));
  1173. return false;
  1174. }
  1175. /**
  1176. * ---------------------------------------------------------------------------------------------
  1177. * Installer Trigger Loading
  1178. * ---------------------------------------------------------------------------------------------
  1179. */
  1180. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  1181. $manifestScript = (string)$this->manifest->scriptfile;
  1182. if ($manifestScript)
  1183. {
  1184. $manifestScriptFile = $this->parent->getPath('source').DS.$manifestScript;
  1185. if (is_file($manifestScriptFile))
  1186. {
  1187. // load the file
  1188. include_once $manifestScriptFile;
  1189. }
  1190. // Set the class name
  1191. $classname = $element.'InstallerScript';
  1192. if (class_exists($classname))
  1193. {
  1194. // create a new instance
  1195. $this->parent->manifestClass = new $classname($this);
  1196. // and set this so we can copy it later
  1197. $this->set('manifest_script', $manifestScript);
  1198. // Note: if we don't find the class, don't bother to copy the file
  1199. }
  1200. }
  1201. // run preflight if possible (since we know we're not an update)
  1202. ob_start();
  1203. ob_implicit_flush(false);
  1204. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight')) {
  1205. $this->parent->manifestClass->preflight('discover_install', $this);
  1206. }
  1207. $msg = ob_get_contents(); // create msg object; first use here
  1208. ob_end_clean();
  1209. // Normally we would copy files and create directories, lets skip to the optional files
  1210. // Note: need to dereference things!
  1211. // Parse optional tags
  1212. $this->parent->parseMedia($this->manifest->media);
  1213. // We don't do language because 1.6 suggests moving to extension based languages
  1214. //$this->parent->parseLanguages($this->manifest->languages);
  1215. //$this->parent->parseLanguages($this->manifest->administration->languages, 1);
  1216. /**
  1217. * ---------------------------------------------------------------------------------------------
  1218. * Database Processing Section
  1219. * ---------------------------------------------------------------------------------------------
  1220. */
  1221. /*
  1222. * Let's run the install queries for the component
  1223. * If Joomla 1.5 compatible, with discreet sql files - execute appropriate
  1224. * file for utf-8 support or non-utf-8 support
  1225. */
  1226. // try for Joomla 1.5 type queries
  1227. // second argument is the utf compatible version attribute
  1228. $utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
  1229. if ($utfresult === false)
  1230. {
  1231. // Install failed, rollback changes
  1232. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('SQLERRORORFILE')." ".$db->stderr(true));
  1233. return false;
  1234. }
  1235. // Time to build the admin menus
  1236. $this->_buildAdminMenus();
  1237. /**
  1238. * ---------------------------------------------------------------------------------------------
  1239. * Custom Installation Script Section
  1240. * ---------------------------------------------------------------------------------------------
  1241. */
  1242. /*
  1243. * If we have an install script, lets include it, execute the custom
  1244. * install method, and append the return value from the custom install
  1245. * method to the installation message.
  1246. */
  1247. // start legacy support
  1248. if ($this->get('install_script'))
  1249. {
  1250. if (is_file($this->parent->getPath('extension_administrator').DS.$this->get('install_script')))
  1251. {
  1252. ob_start();
  1253. ob_implicit_flush(false);
  1254. require_once $this->parent->getPath('extension_administrator').DS.$this->get('install_script');
  1255. if (function_exists('com_install'))
  1256. {
  1257. if (com_install() === false)
  1258. {
  1259. $this->parent->abort(JText::_('Component').' '.JText::_('Install').': '.JText::_('Custom install routine failure'));
  1260. return false;
  1261. }
  1262. }
  1263. $msg .= ob_get_contents(); // append messages
  1264. ob_e

Large files files are truncated, but you can click here to view the full file