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

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

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

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