PageRenderTime 48ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/content/code/trunk/administrator/components/com_artofcontent/install/helper.php

https://bitbucket.org/eddieajau/the-art-of-joomla-archive
PHP | 646 lines | 403 code | 70 blank | 173 comment | 64 complexity | ec1210006a942f328560941e929a60b8 MD5 | raw file
  1. <?php
  2. /**
  3. * @version $Id: helper.php 496 2010-12-29 00:44:10Z eddieajau $
  4. * @package NewLifeInIT
  5. * @subpackage com_artofcontent
  6. * @copyright Copyright 2010 New Life in IT Pty Ltd. All rights reserved.
  7. * @license GNU General Public License version 2 or later.
  8. */
  9. // No direct access.
  10. defined('_JEXEC') or die;
  11. /**
  12. * Installation helper.
  13. *
  14. * Changelog:
  15. * + Modules won't be added to the table if they exist already.
  16. * + Added showtitle attribute for modules.
  17. * + Added published attribute for modules.
  18. *
  19. * @package NewLifeInIT
  20. * @subpackage com_artofcontent
  21. * @version 1.0.1
  22. */
  23. abstract class PackageInstallerHelper
  24. {
  25. /**
  26. * Display the results of the package install.
  27. *
  28. * @param array $modules An array of the modules that were installed.
  29. * @param array $plugins An array of the plugins that were installed.
  30. * @param string $title The page title.
  31. * @param string $name The name of the component.
  32. *
  33. * @return void
  34. * @since 1.0
  35. */
  36. public static function displayInstalled(&$modules, &$plugins, $title, $name)
  37. {
  38. ?>
  39. <?php echo $title;?>
  40. <table class="adminlist">
  41. <thead>
  42. <tr>
  43. <th class="title" colspan="2"><?php echo JText::_('J_INSTALL_EXTENSION'); ?></th>
  44. <th width="30%"><?php echo JText::_('J_INSTALL_STATUS'); ?></th>
  45. </tr>
  46. </thead>
  47. <tfoot>
  48. <tr>
  49. <td colspan="3"></td>
  50. </tr>
  51. </tfoot>
  52. <tbody>
  53. <tr class="row0">
  54. <td class="key" colspan="2"><?php echo JText::sprintf('J_INSTALL_COMPONENT', $name); ?></td>
  55. <td><strong><?php echo JText::_('J_INSTALL_INSTALLED'); ?></strong></td>
  56. </tr>
  57. <?php if ($modules) : ?>
  58. <tr>
  59. <th><?php echo JText::_('J_INSTALL_MODULE'); ?></th>
  60. <th><?php echo JText::_('J_INSTALL_CLIENT'); ?></th>
  61. <th></th>
  62. </tr>
  63. <?php foreach ($modules as $i => $module) : ?>
  64. <tr class="row<?php echo ($i % 2); ?>">
  65. <td class="key"><?php echo $module['name']; ?></td>
  66. <td class="key"><?php echo ucfirst($module['client']); ?></td>
  67. <td><strong><?php echo JText::_('J_INSTALL_INSTALLED'); ?></strong></td>
  68. </tr>
  69. <?php endforeach;
  70. endif;
  71. if ($plugins) : ?>
  72. <tr>
  73. <th><?php echo JText::_('J_INSTALL_PLUGIN'); ?></th>
  74. <th><?php echo JText::_('J_INSTALL_GROUP'); ?></th>
  75. <th></th>
  76. </tr>
  77. <?php foreach ($plugins as $i => $plugin) : ?>
  78. <tr class="row<?php echo ($i % 2); ?>">
  79. <td class="key"><?php echo ucfirst($plugin['name']); ?></td>
  80. <td class="key"><?php echo ucfirst($plugin['group']); ?></td>
  81. <td><strong><?php echo JText::_('J_INSTALL_INSTALLED'); ?></strong></td>
  82. </tr>
  83. <?php endforeach;
  84. endif; ?>
  85. </tbody>
  86. </table>
  87. <?php
  88. }
  89. /**
  90. * Display the results of the package uninstall.
  91. *
  92. * @param array $modules An array of the modules that were installed.
  93. * @param array $plugins An array of the plugins that were installed.
  94. * @param string $title The page title.
  95. * @param string $name The name of the component.
  96. *
  97. * @return void
  98. * @since 1.0
  99. */
  100. public static function displayUninstalled(&$modules, &$plugins, $title, $name)
  101. {
  102. ?>
  103. <h2><?php echo $title;?></h2>
  104. <table class="adminlist">
  105. <thead>
  106. <tr>
  107. <th class="title" colspan="2"><?php echo JText::_('J_INSTALL_EXTENSION'); ?></th>
  108. <th width="30%"><?php echo JText::_('J_INSTALL_STATUS'); ?></th>
  109. </tr>
  110. </thead>
  111. <tfoot>
  112. <tr>
  113. <td colspan="3"></td>
  114. </tr>
  115. </tfoot>
  116. <tbody>
  117. <tr class="row0">
  118. <td class="key" colspan="2"><?php echo JText::sprintf('J_INSTALL_COMPONENT', $name); ?></td>
  119. <td><strong><?php echo JText::_('J_INSTALL_REMOVED'); ?></strong></td>
  120. </tr>
  121. <?php if ($modules) : ?>
  122. <tr>
  123. <th><?php echo JText::_('J_INSTALL_MODULE'); ?></th>
  124. <th><?php echo JText::_('J_INSTALL_CLIENT'); ?></th>
  125. <th></th>
  126. </tr>
  127. <?php foreach ($modules as $i => $module) : ?>
  128. <tr class="row<?php echo ($i % 2); ?>">
  129. <td class="key"><?php echo $module['name']; ?></td>
  130. <td class="key"><?php echo ucfirst($module['client']); ?></td>
  131. <td><strong><?php echo JText::_('J_INSTALL_REMOVED'); ?></strong></td>
  132. </tr>
  133. <?php endforeach;
  134. endif;
  135. if ($plugins) : ?>
  136. <tr>
  137. <th><?php echo JText::_('J_INSTALL_PLUGIN'); ?></th>
  138. <th><?php echo JText::_('J_INSTALL_GROUP'); ?></th>
  139. <th></th>
  140. </tr>
  141. <?php foreach ($plugins as $i => $plugin) : ?>
  142. <tr class="row<?php echo ($i % 2); ?>">
  143. <td class="key"><?php echo ucfirst($plugin['name']); ?></td>
  144. <td class="key"><?php echo ucfirst($plugin['group']); ?></td>
  145. <td><strong><?php echo JText::_('J_INSTALL_REMOVED'); ?></strong></td>
  146. </tr>
  147. <?php endforeach;
  148. endif; ?>
  149. </tbody>
  150. </table>
  151. <?php
  152. }
  153. /**
  154. * Fixes a bug in the components table for backend only extensions.
  155. *
  156. * @param string $option The name of the component folder.
  157. *
  158. * @return void
  159. * @since 1.0
  160. */
  161. public static function fixLink($option)
  162. {
  163. // Insert a new installation record in the version log if no rows are present.
  164. $db = JFactory::getDBO();
  165. // Correct bug in components table for backend only extenions
  166. $db->setQuery(
  167. 'UPDATE `#__components` SET `link` = '.$db->quote('').' WHERE `option` = '.$db->quote($option)
  168. );
  169. if (!$db->query()) {
  170. JError::raiseWarning(500, $db->getErrorMsg());
  171. }
  172. }
  173. /**
  174. * Install packaged modules.
  175. *
  176. * @param object $installer The parent installer object.
  177. *
  178. * @return array An array of the installed modules.
  179. * @since 1.0
  180. */
  181. public static function installModules(&$installer)
  182. {
  183. $result = array();
  184. $modules = &$installer->manifest->getElementByPath('modules');
  185. if (is_a($modules, 'JSimpleXMLElement') && count($modules->children())) {
  186. foreach ($modules->children() as $module)
  187. {
  188. $mname = $module->attributes('module');
  189. $mclient = JApplicationHelper::getClientInfo($module->attributes('client'), true);
  190. // Set the installation path
  191. if (!empty ($mname)) {
  192. $installer->parent->setPath('extension_root', $mclient->path.'/modules/'.$mname);
  193. }
  194. else {
  195. $installer->parent->abort(JText::_('J_Install_Module').' '.JText::_('J_INSTALL_INSTALL').': '.JText::_('J_INSTALL_MODULE_FILE_MISSING'));
  196. return false;
  197. }
  198. // If the module directory already exists, then we will assume that the
  199. // module is already installed or another module is using that directory.
  200. if (file_exists($installer->parent->getPath('extension_root'))&&!$installer->parent->getOverwrite()) {
  201. $installer->parent->abort(JText::_('J_Install_Module').' '.JText::_('J_INSTALL_INSTALL').': '.JText::sprintf('J_INSTALL_MODULE_PATH_CONFLICT', $installer->parent->getPath('extension_root')));
  202. return false;
  203. }
  204. // If the module directory does not exist, lets create it
  205. $created = false;
  206. if (!file_exists($installer->parent->getPath('extension_root'))) {
  207. if (!$created = JFolder::create($installer->parent->getPath('extension_root'))) {
  208. $installer->parent->abort(JText::_('J_Install_Module').' '.JText::_('J_INSTALL_INSTALL').': '.JText::sprintf('J_INSTALL_MODULE_PATH_CREATE_FAILURE', $installer->parent->getPath('extension_root')));
  209. return false;
  210. }
  211. }
  212. // Since we created the module directory and will want to remove it if
  213. // we have to roll back the installation, lets add it to the
  214. // installation step stack
  215. if ($created) {
  216. $installer->parent->pushStep(array ('type' => 'folder', 'path' => $installer->parent->getPath('extension_root')));
  217. }
  218. // Copy all necessary files
  219. $element = &$module->getElementByPath('files');
  220. if ($installer->parent->parseFiles($element, -1) === false) {
  221. // Install failed, roll back changes
  222. $installer->parent->abort();
  223. return false;
  224. }
  225. // Copy language files
  226. $element = &$module->getElementByPath('languages');
  227. if ($installer->parent->parseLanguages($element, $mclient->id) === false) {
  228. // Install failed, roll back changes
  229. $installer->parent->abort();
  230. return false;
  231. }
  232. // Copy media files
  233. $element = &$module->getElementByPath('media');
  234. if ($installer->parent->parseMedia($element, $mclient->id) === false) {
  235. // Install failed, roll back changes
  236. $installer->parent->abort();
  237. return false;
  238. }
  239. $mtitle = $module->attributes('title');
  240. $mposition = $module->attributes('position');
  241. $mShowTitle = $module->attributes('showtitle');
  242. $mPublished = $module->attributes('published');
  243. $mAccess = $module->attributes('access');
  244. if ($mtitle && $mposition) {
  245. // Check if module is already installed.
  246. $db = JFactory::getDBO();
  247. $db->setQuery(
  248. 'SELECT id' .
  249. ' FROM #__modules' .
  250. ' WHERE client_id = '.(int) $mclient->id.
  251. ' AND module = '.$db->quote($mname)
  252. );
  253. $installed = $db->loadResult();
  254. $error = $db->getErrorMsg();
  255. if ($error) {
  256. $installer->parent->abort(JText::_('J_INSTALL_MODULE').' '.JText::_('J_INSTALL_INSTALL').': '.$error);
  257. return false;
  258. }
  259. if (!$installed) {
  260. $row = JTable::getInstance('module');
  261. $row->title = $mtitle;
  262. $row->ordering = $row->getNextOrder("position='".$mposition."'");
  263. $row->position = $mposition;
  264. $row->showtitle = (boolean) $mShowTitle;
  265. $row->iscore = 0;
  266. $row->access = ($mclient->id) == 1 ? 2 : (int) $mAccess;
  267. $row->client_id = $mclient->id;
  268. $row->module = $mname;
  269. $row->published = (boolean) $mPublished;
  270. $row->params = '';
  271. if (!$row->store()) {
  272. // Install failed, roll back changes
  273. $installer->parent->abort(JText::_('J_INSTALL_MODULE').' '.JText::_('J_INSTALL_INSTALL').': '.$row->getError());
  274. return false;
  275. }
  276. }
  277. }
  278. $result[] = array('name'=>$mname,'client'=>$mclient->name);
  279. }
  280. }
  281. return $result;
  282. }
  283. /**
  284. * Install packaged modules.
  285. *
  286. * @param object $installer The parent installer object.
  287. *
  288. * @return array An array of the installed modules.
  289. * @since 1.0
  290. */
  291. public static function installPlugins(&$installer)
  292. {
  293. $result = array();
  294. $plugins = &$installer->manifest->getElementByPath('plugins');
  295. if (is_a($plugins, 'JSimpleXMLElement') && count($plugins->children())) {
  296. foreach ($plugins->children() as $plugin)
  297. {
  298. $pname = $plugin->attributes('plugin');
  299. $pgroup = $plugin->attributes('group');
  300. $pState = $plugin->attributes('published');
  301. // Set the installation path
  302. if (!empty($pname) && !empty($pgroup)) {
  303. $installer->parent->setPath('extension_root', JPATH_ROOT.'/plugins/'.$pgroup);
  304. } else {
  305. $installer->parent->abort(JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_INSTALL').': '.JText::_('J_INSTALL_PLUGIN_FILE_MISSING'));
  306. return false;
  307. }
  308. /**
  309. * ---------------------------------------------------------------------------------------------
  310. * Filesystem Processing Section
  311. * ---------------------------------------------------------------------------------------------
  312. */
  313. // If the plugin directory does not exist, lets create it
  314. $created = false;
  315. if (!file_exists($installer->parent->getPath('extension_root'))) {
  316. if (!$created = JFolder::create($installer->parent->getPath('extension_root'))) {
  317. $installer->parent->abort(JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_INSTALL').': '.JText::sprintf('J_INSTALL_PLUGIN_PATH_CREATE_FAILURE', $installer->parent->getPath('extension_root')));
  318. return false;
  319. }
  320. }
  321. // If we created the plugin directory and will want to remove it if we
  322. // have to roll back the installation, lets add it to the installation
  323. // step stack
  324. if ($created) {
  325. $installer->parent->pushStep(array ('type' => 'folder', 'path' => $installer->parent->getPath('extension_root')));
  326. }
  327. // Copy all necessary files
  328. $element = &$plugin->getElementByPath('files');
  329. if ($installer->parent->parseFiles($element, -1) === false) {
  330. // Install failed, roll back changes
  331. $installer->parent->abort();
  332. return false;
  333. }
  334. // Copy all necessary files
  335. $element = &$plugin->getElementByPath('languages');
  336. if ($installer->parent->parseLanguages($element, 1) === false) {
  337. // Install failed, roll back changes
  338. $installer->parent->abort();
  339. return false;
  340. }
  341. // Copy media files
  342. $element = &$plugin->getElementByPath('media');
  343. if ($installer->parent->parseMedia($element, 1) === false) {
  344. // Install failed, roll back changes
  345. $installer->parent->abort();
  346. return false;
  347. }
  348. /**
  349. * ---------------------------------------------------------------------------------------------
  350. * Database Processing Section
  351. * ---------------------------------------------------------------------------------------------
  352. */
  353. $db = &JFactory::getDBO();
  354. // Check to see if a plugin by the same name is already installed
  355. $query = 'SELECT `id`' .
  356. ' FROM `#__plugins`' .
  357. ' WHERE folder = '.$db->Quote($pgroup) .
  358. ' AND element = '.$db->Quote($pname);
  359. $db->setQuery($query);
  360. if (!$db->Query()) {
  361. // Install failed, roll back changes
  362. $installer->parent->abort(JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_INSTALL').': '.$db->stderr(true));
  363. return false;
  364. }
  365. $id = $db->loadResult();
  366. // Was there a plugin already installed with the same name?
  367. if ($id) {
  368. if (!$installer->parent->getOverwrite()) {
  369. // Install failed, roll back changes
  370. $installer->parent->abort(JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_INSTALL').': '.JText::sprintf('J_INSTALL_PLUGIN_ALREADY_EXISTS', $pname));
  371. return false;
  372. }
  373. } else {
  374. $row =& JTable::getInstance('plugin');
  375. $row->name = JText::_(ucfirst($pgroup)).' - '.JText::_(ucfirst($pname));
  376. $row->ordering = 0;
  377. $row->folder = $pgroup;
  378. $row->iscore = 0;
  379. $row->access = 0;
  380. $row->client_id = 0;
  381. $row->element = $pname;
  382. $row->published = (int) $pState;
  383. $row->params = '';
  384. if (!$row->store()) {
  385. // Install failed, roll back changes
  386. $installer->parent->abort(JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_INSTALL').': '.$db->stderr(true));
  387. return false;
  388. }
  389. }
  390. $result[] = array('name'=>$pname,'group'=>$pgroup);
  391. }
  392. }
  393. return $result;
  394. }
  395. /**
  396. * Check if a component exists.
  397. *
  398. * @param string $option The name of the component folder.
  399. *
  400. * @return void
  401. * @since 1.0
  402. */
  403. public static function componentExists($option)
  404. {
  405. $db = JFactory::getDbo();
  406. $db->setQuery(
  407. 'SELECT id' .
  408. ' FROM #__components' .
  409. ' WHERE `option` = '.$db->quote($option) .
  410. ' AND parent = 0'
  411. );
  412. $result = $db->loadResult();
  413. if ($error = $db->getErrorMsg()) {
  414. JError::raiseError(500, $error);
  415. }
  416. return (boolean) $result;
  417. }
  418. /**
  419. * Uninstall packaged modules.
  420. *
  421. * @param object $installer The parent installer object.
  422. *
  423. * @return array An array of the installed modules.
  424. * @since 1.0
  425. */
  426. public static function uninstallModules($installer)
  427. {
  428. $modules = &$installer->manifest->getElementByPath('modules');
  429. if (is_a($modules, 'JSimpleXMLElement') && count($modules->children())) {
  430. foreach ($modules->children() as $module)
  431. {
  432. $mname = $module->attributes('module');
  433. $mclient = JApplicationHelper::getClientInfo($module->attributes('client'), true);
  434. $mposition = $module->attributes('position');
  435. // Set the installation path
  436. if (!empty ($mname)) {
  437. $installer->parent->setPath('extension_root', $mclient->path.'/modules/'.$mname);
  438. }
  439. else {
  440. $installer->parent->abort(JText::_('J_INSTALL_MODULE').' '.JText::_('J_INSTALL_UNINSTALL').': '.JText::_('J_INSTALL_MODULE_FILE_MISSING'));
  441. return false;
  442. }
  443. /**
  444. * ---------------------------------------------------------------------------------------------
  445. * Database Processing Section
  446. * ---------------------------------------------------------------------------------------------
  447. */
  448. $db = &JFactory::getDBO();
  449. // Lets delete all the module copies for the type we are uninstalling
  450. $query = 'SELECT `id`' .
  451. ' FROM `#__modules`' .
  452. ' WHERE module = '.$db->Quote($mname) .
  453. ' AND client_id = '.(int)$mclient->id;
  454. $db->setQuery($query);
  455. $modules = $db->loadResultArray();
  456. // Do we have any module copies?
  457. if (count($modules)) {
  458. JArrayHelper::toInteger($modules);
  459. $modID = implode(',', $modules);
  460. $query = 'DELETE' .
  461. ' FROM #__modules_menu' .
  462. ' WHERE moduleid IN ('.$modID.')';
  463. $db->setQuery($query);
  464. if (!$db->query()) {
  465. JError::raiseWarning(100, JText::_('J_INSTALL_MODULE').' '.JText::_('J_INSTALL_UNINSTALL').': '.$db->stderr(true));
  466. $retval = false;
  467. }
  468. }
  469. // Delete the modules in the #__modules table
  470. $query = 'DELETE FROM #__modules WHERE module = '.$db->Quote($mname);
  471. $db->setQuery($query);
  472. if (!$db->query()) {
  473. JError::raiseWarning(100, JText::_('J_INSTALL_MODULE').' '.JText::_('J_INSTALL_UNINSTALL').': '.$db->stderr(true));
  474. $retval = false;
  475. }
  476. /**
  477. * ---------------------------------------------------------------------------------------------
  478. * Filesystem Processing Section
  479. * ---------------------------------------------------------------------------------------------
  480. */
  481. // Remove all necessary files
  482. $element = &$module->getElementByPath('files');
  483. if (is_a($element, 'JSimpleXMLElement') && count($element->children())) {
  484. $installer->parent->removeFiles($element, -1);
  485. }
  486. // Remove all necessary files
  487. $element = &$module->getElementByPath('media');
  488. if (is_a($element, 'JSimpleXMLElement') && count($element->children())) {
  489. $installer->parent->removeFiles($element, -1);
  490. }
  491. $element = &$module->getElementByPath('languages');
  492. if (is_a($element, 'JSimpleXMLElement') && count($element->children())) {
  493. $installer->parent->removeFiles($element, $mclient->id);
  494. }
  495. // Remove the installation folder
  496. if (!JFolder::delete($installer->parent->getPath('extension_root'))) {
  497. }
  498. $status->modules[] = array('name'=>$mname,'client'=>$mclient->name);
  499. }
  500. }
  501. }
  502. /**
  503. * Uninstall packaged plugins.
  504. *
  505. * @param object $installer The parent installer object.
  506. *
  507. * @return array An array of the installed modules.
  508. * @since 1.0
  509. */
  510. public static function uninstallPlugins(&$installer)
  511. {
  512. $plugins = &$installer->manifest->getElementByPath('plugins');
  513. if (is_a($plugins, 'JSimpleXMLElement') && count($plugins->children())) {
  514. foreach ($plugins->children() as $plugin)
  515. {
  516. $pname = $plugin->attributes('plugin');
  517. $pgroup = $plugin->attributes('group');
  518. // Set the installation path
  519. if (!empty($pname) && !empty($pgroup)) {
  520. $installer->parent->setPath('extension_root', JPATH_ROOT.'/plugins/'.$pgroup);
  521. } else {
  522. $installer->parent->abort(JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_UNINSTALL').': '.JText::_('J_INSTALL_PLUGIN_FILE_MISSING'));
  523. return false;
  524. }
  525. /**
  526. * ---------------------------------------------------------------------------------------------
  527. * Database Processing Section
  528. * ---------------------------------------------------------------------------------------------
  529. */
  530. $db = &JFactory::getDBO();
  531. // Delete the plugins in the #__plugins table
  532. $query = 'DELETE FROM #__plugins WHERE element = '.$db->Quote($pname).' AND folder = '.$db->Quote($pgroup);
  533. $db->setQuery($query);
  534. if (!$db->query()) {
  535. JError::raiseWarning(100, JText::_('J_INSTALL_PLUGIN').' '.JText::_('J_INSTALL_UNINSTALL').': '.$db->stderr(true));
  536. $retval = false;
  537. }
  538. /**
  539. * ---------------------------------------------------------------------------------------------
  540. * Filesystem Processing Section
  541. * ---------------------------------------------------------------------------------------------
  542. */
  543. // Remove all necessary files
  544. $element = &$plugin->getElementByPath('files');
  545. if (is_a($element, 'JSimpleXMLElement') && count($element->children())) {
  546. $installer->parent->removeFiles($element, -1);
  547. }
  548. $element = &$plugin->getElementByPath('languages');
  549. if (is_a($element, 'JSimpleXMLElement') && count($element->children())) {
  550. $installer->parent->removeFiles($element, 1);
  551. }
  552. // If the folder is empty, let's delete it
  553. $files = JFolder::files($installer->parent->getPath('extension_root'));
  554. if (!count($files)) {
  555. JFolder::delete($installer->parent->getPath('extension_root'));
  556. }
  557. $status->plugins[] = array('name'=>$pname,'group'=>$pgroup);
  558. }
  559. }
  560. }
  561. /**
  562. * Upgrade the database with an XML schema file.
  563. *
  564. * @param string $xml The XML string.
  565. *
  566. * @return array Returns the database upgrade log.
  567. * @since 1.0
  568. */
  569. public static function upgrade($xml)
  570. {
  571. // Include dependancies.
  572. require_once dirname(dirname(__FILE__)).'/libraries/joomla/database/database/mysqlxml.php';
  573. JDatabaseMySQLXML::import($xml);
  574. return JDatabaseMySQLXML::getLog();
  575. }
  576. }