PageRenderTime 60ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/application/libraries/joomla/installer/adapters/library.php

https://github.com/nikosdion/Akeeba-Example
PHP | 414 lines | 247 code | 48 blank | 119 comment | 29 complexity | ed1e7989bd99a42b4411be4cb71e1803 MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Installer
  5. *
  6. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die();
  10. jimport('joomla.installer.librarymanifest');
  11. jimport('joomla.base.adapterinstance');
  12. /**
  13. * Library installer
  14. *
  15. * @package Joomla.Platform
  16. * @subpackage Installer
  17. * @since 11.1
  18. */
  19. class JInstallerLibrary extends JAdapterInstance
  20. {
  21. /**
  22. * Custom loadLanguage method
  23. *
  24. * @param string $path The path where to find language files.
  25. *
  26. * @return void
  27. *
  28. * @since 11.1
  29. */
  30. public function loadLanguage($path = null)
  31. {
  32. $source = $this->parent->getPath('source');
  33. if (!$source)
  34. {
  35. $this->parent->setPath('source', JPATH_PLATFORM . '/' . $this->parent->extension->element);
  36. }
  37. $this->manifest = $this->parent->getManifest();
  38. $extension = 'lib_' . strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd'));
  39. $name = strtolower((string) $this->manifest->libraryname);
  40. $lang = JFactory::getLanguage();
  41. $source = $path ? $path : JPATH_PLATFORM . "/$name";
  42. $lang->load($extension . '.sys', $source, null, false, false)
  43. || $lang->load($extension . '.sys', JPATH_SITE, null, false, false)
  44. || $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
  45. || $lang->load($extension . '.sys', JPATH_SITE, $lang->getDefault(), false, false);
  46. }
  47. /**
  48. * Custom install method
  49. *
  50. * @return boolean True on success
  51. *
  52. * @since 11.1
  53. */
  54. public function install()
  55. {
  56. // Get the extension manifest object
  57. $this->manifest = $this->parent->getManifest();
  58. // Manifest Document Setup Section
  59. // Set the extensions name
  60. $name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'string');
  61. $element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
  62. $this->set('name', $name);
  63. $this->set('element', $element);
  64. $db = $this->parent->getDbo();
  65. $db->setQuery('SELECT extension_id FROM #__extensions WHERE type="library" AND element = "' . $element . '"');
  66. $result = $db->loadResult();
  67. if ($result)
  68. {
  69. // Already installed, can we upgrade?
  70. if ($this->parent->getOverwrite() || $this->parent->getUpgrade())
  71. {
  72. // We can upgrade, so uninstall the old one
  73. $installer = new JInstaller(); // we don't want to compromise this instance!
  74. $installer->uninstall('library', $result);
  75. }
  76. else
  77. {
  78. // Abort the install, no upgrade possible
  79. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_ALREADY_INSTALLED'));
  80. return false;
  81. }
  82. }
  83. // Get the libraries description
  84. $description = (string) $this->manifest->description;
  85. if ($description)
  86. {
  87. $this->parent->set('message', JText::_($description));
  88. }
  89. else
  90. {
  91. $this->parent->set('message', '');
  92. }
  93. // Set the installation path
  94. $group = (string) $this->manifest->libraryname;
  95. if (!$group)
  96. {
  97. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_NOFILE'));
  98. return false;
  99. }
  100. else
  101. {
  102. $this->parent->setPath('extension_root', JPATH_PLATFORM . '/' . implode(DS, explode('/', $group)));
  103. }
  104. // Filesystem Processing Section
  105. // If the plugin directory does not exist, let's create it
  106. $created = false;
  107. if (!file_exists($this->parent->getPath('extension_root')))
  108. {
  109. if (!$created = JFolder::create($this->parent->getPath('extension_root')))
  110. {
  111. $this->parent->abort(
  112. JText::sprintf('JLIB_INSTALLER_ABORT_LIB_INSTALL_FAILED_TO_CREATE_DIRECTORY', $this->parent->getPath('extension_root'))
  113. );
  114. return false;
  115. }
  116. }
  117. // If we created the plugin directory and will want to remove it if we
  118. // have to roll back the installation, let's add it to the installation
  119. // step stack
  120. if ($created)
  121. {
  122. $this->parent->pushStep(array('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
  123. }
  124. // Copy all necessary files
  125. if ($this->parent->parseFiles($this->manifest->files, -1) === false)
  126. {
  127. // Install failed, roll back changes
  128. $this->parent->abort();
  129. return false;
  130. }
  131. // Parse optional tags
  132. $this->parent->parseLanguages($this->manifest->languages);
  133. $this->parent->parseMedia($this->manifest->media);
  134. // Extension Registration
  135. $row = JTable::getInstance('extension');
  136. $row->name = $this->get('name');
  137. $row->type = 'library';
  138. $row->element = $this->get('element');
  139. $row->folder = ''; // There is no folder for modules
  140. $row->enabled = 1;
  141. $row->protected = 0;
  142. $row->access = 1;
  143. $row->client_id = 0;
  144. $row->params = $this->parent->getParams();
  145. $row->custom_data = ''; // custom data
  146. $row->manifest_cache = $this->parent->generateManifestCache();
  147. if (!$row->store())
  148. {
  149. // Install failed, roll back changes
  150. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_LIB_INSTALL_ROLLBACK', $db->stderr(true)));
  151. return false;
  152. }
  153. // Finalization and Cleanup Section
  154. // Lastly, we will copy the manifest file to its appropriate place.
  155. $manifest = Array();
  156. $manifest['src'] = $this->parent->getPath('manifest');
  157. $manifest['dest'] = JPATH_MANIFESTS . '/libraries/' . basename($this->parent->getPath('manifest'));
  158. if (!$this->parent->copyFiles(array($manifest), true))
  159. {
  160. // Install failed, rollback changes
  161. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_LIB_INSTALL_COPY_SETUP'));
  162. return false;
  163. }
  164. return $row->get('extension_id');
  165. }
  166. /**
  167. * Custom update method
  168. *
  169. * @return boolean True on success
  170. *
  171. * @since 11.1
  172. */
  173. public function update()
  174. {
  175. // Since this is just files, an update removes old files
  176. // Get the extension manifest object
  177. $this->manifest = $this->parent->getManifest();
  178. // Manifest Document Setup Section
  179. // Set the extensions name
  180. $name = (string) $this->manifest->name;
  181. $name = JFilterInput::getInstance()->clean($name, 'string');
  182. $element = str_replace('.xml', '', basename($this->parent->getPath('manifest')));
  183. $this->set('name', $name);
  184. $this->set('element', $element);
  185. $installer = new JInstaller(); // we don't want to compromise this instance!
  186. $db = $this->parent->getDbo();
  187. $db->setQuery('SELECT extension_id FROM #__extensions WHERE type="library" AND element = "' . $element . '"');
  188. $result = $db->loadResult();
  189. if ($result)
  190. {
  191. // Already installed, which would make sense
  192. $installer->uninstall('library', $result);
  193. }
  194. // Now create the new files
  195. return $this->install();
  196. }
  197. /**
  198. * Custom uninstall method
  199. *
  200. * @param string $id The id of the library to uninstall.
  201. *
  202. * @return boolean True on success
  203. *
  204. * @since 11.1
  205. */
  206. public function uninstall($id)
  207. {
  208. // Initialise variables.
  209. $retval = true;
  210. // First order of business will be to load the module object table from the database.
  211. // This should give us the necessary information to proceed.
  212. $row = JTable::getInstance('extension');
  213. if (!$row->load((int) $id) || !strlen($row->element))
  214. {
  215. JError::raiseWarning(100, JText::_('ERRORUNKOWNEXTENSION'));
  216. return false;
  217. }
  218. // Is the library we are trying to uninstall a core one?
  219. // Because that is not a good idea...
  220. if ($row->protected)
  221. {
  222. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_WARNCORELIBRARY'));
  223. return false;
  224. }
  225. $manifestFile = JPATH_MANIFESTS . '/libraries/' . $row->element . '.xml';
  226. // Because libraries may not have their own folders we cannot use the standard method of finding an installation manifest
  227. if (file_exists($manifestFile))
  228. {
  229. $manifest = new JLibraryManifest($manifestFile);
  230. // Set the plugin root path
  231. $this->parent->setPath('extension_root', JPATH_PLATFORM . '/' . $manifest->libraryname);
  232. $xml = JFactory::getXML($manifestFile);
  233. // If we cannot load the XML file return null
  234. if (!$xml)
  235. {
  236. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_LOAD_MANIFEST'));
  237. return false;
  238. }
  239. // Check for a valid XML root tag.
  240. // TODO: Remove backwards compatability in a future version
  241. // Should be 'extension', but for backward compatability we will accept 'install'.
  242. if ($xml->getName() != 'install' && $xml->getName() != 'extension')
  243. {
  244. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_MANIFEST'));
  245. return false;
  246. }
  247. $this->parent->removeFiles($xml->files, -1);
  248. JFile::delete($manifestFile);
  249. }
  250. else
  251. {
  252. // Remove this row entry since its invalid
  253. $row->delete($row->extension_id);
  254. unset($row);
  255. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_LIB_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
  256. return false;
  257. }
  258. // TODO: Change this so it walked up the path backwards so we clobber multiple empties
  259. // If the folder is empty, let's delete it
  260. if (JFolder::exists($this->parent->getPath('extension_root')))
  261. {
  262. if (is_dir($this->parent->getPath('extension_root')))
  263. {
  264. $files = JFolder::files($this->parent->getPath('extension_root'));
  265. if (!count($files))
  266. {
  267. JFolder::delete($this->parent->getPath('extension_root'));
  268. }
  269. }
  270. }
  271. $this->parent->removeFiles($xml->languages);
  272. $row->delete($row->extension_id);
  273. unset($row);
  274. return $retval;
  275. }
  276. /**
  277. * Custom discover method
  278. *
  279. * @return array JExtension list of extensions available
  280. *
  281. * @since 11.1
  282. */
  283. public function discover()
  284. {
  285. $results = Array();
  286. $file_list = JFolder::files(JPATH_MANIFESTS . '/libraries', '\.xml$');
  287. foreach ($file_list as $file)
  288. {
  289. $manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_MANIFESTS . '/libraries/' . $file);
  290. $file = JFile::stripExt($file);
  291. $extension = JTable::getInstance('extension');
  292. $extension->set('type', 'library');
  293. $extension->set('client_id', 0);
  294. $extension->set('element', $file);
  295. $extension->set('name', $file);
  296. $extension->set('state', -1);
  297. $extension->set('manifest_cache', json_encode($manifest_details));
  298. $results[] = $extension;
  299. }
  300. return $results;
  301. }
  302. /**
  303. * Custom discover_install method
  304. *
  305. * @return void
  306. *
  307. * @since 11.1
  308. */
  309. public function discover_install()
  310. {
  311. /* Libraries are a strange beast; they are actually references to files
  312. * There are two parts to a library which are disjunct in their locations
  313. * 1) The manifest file (stored in /JPATH_MANIFESTS/libraries)
  314. * 2) The actual files (stored in /JPATH_PLATFORM/libraryname)
  315. * Thus installation of a library is the process of dumping files
  316. * in two different places. As such it is impossible to perform
  317. * any operation beyond mere registration of a library under the presumption
  318. * that the files exist in the appropriate location so that come uninstall
  319. * time they can be adequately removed.
  320. */
  321. $manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
  322. $this->parent->manifest = $this->parent->isManifest($manifestPath);
  323. $this->parent->setPath('manifest', $manifestPath);
  324. $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
  325. $this->parent->extension->manifest_cache = json_encode($manifest_details);
  326. $this->parent->extension->state = 0;
  327. $this->parent->extension->name = $manifest_details['name'];
  328. $this->parent->extension->enabled = 1;
  329. $this->parent->extension->params = $this->parent->getParams();
  330. if ($this->parent->extension->store())
  331. {
  332. return true;
  333. }
  334. else
  335. {
  336. JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_LIB_DISCOVER_STORE_DETAILS'));
  337. return false;
  338. }
  339. }
  340. /**
  341. * Refreshes the extension table cache
  342. *
  343. * @return boolean Result of operation, true if updated, false on failure
  344. *
  345. * @since 11.1
  346. */
  347. public function refreshManifestCache()
  348. {
  349. // Need to find to find where the XML file is since we don't store this normally
  350. $manifestPath = JPATH_MANIFESTS . '/libraries/' . $this->parent->extension->element . '.xml';
  351. $this->parent->manifest = $this->parent->isManifest($manifestPath);
  352. $this->parent->setPath('manifest', $manifestPath);
  353. $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
  354. $this->parent->extension->manifest_cache = json_encode($manifest_details);
  355. $this->parent->extension->name = $manifest_details['name'];
  356. try
  357. {
  358. return $this->parent->extension->store();
  359. }
  360. catch (JException $e)
  361. {
  362. JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_LIB_REFRESH_MANIFEST_CACHE'));
  363. return false;
  364. }
  365. }
  366. }