PageRenderTime 59ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/libraries/joomla/installer/adapters/plugin.php

https://bitbucket.org/pasamio/jhttprequest
PHP | 761 lines | 487 code | 65 blank | 209 comment | 93 complexity | 20b525512613e2258f415ba487df177f MD5 | raw file
Possible License(s): BSD-3-Clause, GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * @copyright Copyright (C) 2005 - 2011 Open Source Matters, Inc. All rights reserved.
  4. * @license GNU General Public License version 2 or later; see LICENSE
  5. * @package Joomla.Platform
  6. * @subpackage Installer
  7. */
  8. defined('JPATH_PLATFORM') or die;
  9. jimport('joomla.base.adapterinstance');
  10. /**
  11. * Plugin installer
  12. *
  13. * @package Joomla.Platform
  14. * @subpackage Installer
  15. * @since 11.1
  16. */
  17. class JInstallerPlugin extends JAdapterInstance
  18. {
  19. /** @var string install function routing */
  20. var $route = 'install';
  21. protected $manifest = null;
  22. protected $manifest_script = null;
  23. protected $name = null;
  24. protected $scriptElement = null;
  25. protected $oldFiles = null;
  26. /**
  27. * Custom loadLanguage method
  28. *
  29. * @access public
  30. * @param string $path the path where to find language files
  31. * @since 11.1
  32. */
  33. public function loadLanguage($path=null)
  34. {
  35. $source = $this->parent->getPath('source');
  36. if (!$source) {
  37. $this->parent->setPath('source', JPATH_PLUGINS . '/'.$this->parent->extension->folder.'/'.$this->parent->extension->element);
  38. }
  39. $this->manifest = $this->parent->getManifest();
  40. $element = $this->manifest->files;
  41. if ($element)
  42. {
  43. $group = strtolower((string)$this->manifest->attributes()->group);
  44. $name = '';
  45. if (count($element->children()))
  46. {
  47. foreach ($element->children() as $file)
  48. {
  49. if ((string)$file->attributes()->plugin)
  50. {
  51. $name = strtolower((string)$file->attributes()->plugin);
  52. break;
  53. }
  54. }
  55. }
  56. if ($name)
  57. {
  58. $extension = "plg_${group}_${name}";
  59. $lang = JFactory::getLanguage();
  60. $source = $path ? $path : JPATH_PLUGINS . "/$group/$name";
  61. $folder = (string)$element->attributes()->folder;
  62. if ($folder && file_exists("$path/$folder"))
  63. {
  64. $source = "$path/$folder";
  65. }
  66. $lang->load($extension . '.sys', $source, null, false, false)
  67. || $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, null, false, false)
  68. || $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
  69. || $lang->load($extension . '.sys', JPATH_ADMINISTRATOR, $lang->getDefault(), false, false);
  70. }
  71. }
  72. }
  73. /**
  74. * Custom install method
  75. *
  76. * @access public
  77. * @return boolean True on success
  78. * @since 11.1
  79. */
  80. public function install()
  81. {
  82. // Get a database connector object
  83. $db = $this->parent->getDbo();
  84. // Get the extension manifest object
  85. $this->manifest = $this->parent->getManifest();
  86. $xml = $this->manifest;
  87. /**
  88. * ---------------------------------------------------------------------------------------------
  89. * Manifest Document Setup Section
  90. * ---------------------------------------------------------------------------------------------
  91. */
  92. // Set the extensions name
  93. $name = (string)$xml->name;
  94. $name = JFilterInput::getInstance()->clean($name, 'string');
  95. $this->set('name', $name);
  96. // Get the component description
  97. $description = (string)$xml->description;
  98. if ($description) {
  99. $this->parent->set('message', JText::_($description));
  100. }
  101. else {
  102. $this->parent->set('message', '');
  103. }
  104. /*
  105. * Backward Compatability
  106. * @todo Deprecate in future version
  107. */
  108. $type = (string)$xml->attributes()->type;
  109. // Set the installation path
  110. if (count($xml->files->children()))
  111. {
  112. foreach ($xml->files->children() as $file)
  113. {
  114. if ((string)$file->attributes()->$type)
  115. {
  116. $element = (string)$file->attributes()->$type;
  117. break;
  118. }
  119. }
  120. }
  121. $group = (string)$xml->attributes()->group;
  122. if (!empty ($element) && !empty($group)) {
  123. $this->parent->setPath('extension_root', JPATH_PLUGINS.DS.$group.DS.$element);
  124. }
  125. else
  126. {
  127. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_NO_FILE', JText::_('JLIB_INSTALLER_'.$this->route)));
  128. return false;
  129. }
  130. /*
  131. * Check if we should enable overwrite settings
  132. */
  133. // Check to see if a plugin by the same name is already installed
  134. $query = 'SELECT `extension_id`' .
  135. ' FROM `#__extensions`' .
  136. ' WHERE folder = '.$db->Quote($group) .
  137. ' AND element = '.$db->Quote($element);
  138. $db->setQuery($query);
  139. try {
  140. $db->Query();
  141. }
  142. catch(JException $e)
  143. {
  144. // Install failed, roll back changes
  145. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK', JText::_('JLIB_INSTALLER_'.$this->route), $db->stderr(true)));
  146. return false;
  147. }
  148. $id = $db->loadResult();
  149. // if its on the fs...
  150. if (file_exists($this->parent->getPath('extension_root')) && (!$this->parent->getOverwrite() || $this->parent->getUpgrade()))
  151. {
  152. $updateElement = $xml->update;
  153. // upgrade manually set
  154. // update function available
  155. // update tag detected
  156. if ($this->parent->getUpgrade() || ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'update')) || is_a($updateElement, 'JXMLElement'))
  157. {
  158. // force these one
  159. $this->parent->setOverwrite(true);
  160. $this->parent->setUpgrade(true);
  161. if ($id) { // if there is a matching extension mark this as an update; semantics really
  162. $this->route = 'update';
  163. }
  164. }
  165. else if (!$this->parent->getOverwrite())
  166. {
  167. // overwrite is set
  168. // we didn't have overwrite set, find an udpate function or find an update tag so lets call it safe
  169. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_DIRECTORY', JText::_('JLIB_INSTALLER_'.$this->route), $this->parent->getPath('extension_root')));
  170. return false;
  171. }
  172. }
  173. /**
  174. * ---------------------------------------------------------------------------------------------
  175. * Installer Trigger Loading
  176. * ---------------------------------------------------------------------------------------------
  177. */
  178. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  179. if ((string)$xml->scriptfile)
  180. {
  181. $manifestScript = (string)$xml->scriptfile;
  182. $manifestScriptFile = $this->parent->getPath('source').DS.$manifestScript;
  183. if (is_file($manifestScriptFile))
  184. {
  185. // load the file
  186. include_once $manifestScriptFile;
  187. }
  188. // Set the class name
  189. $classname = 'plg'.$group.$element.'InstallerScript';
  190. if (class_exists($classname))
  191. {
  192. // create a new instance
  193. $this->parent->manifestClass = new $classname($this);
  194. // and set this so we can copy it later
  195. $this->set('manifest_script', $manifestScript);
  196. // Note: if we don't find the class, don't bother to copy the file
  197. }
  198. }
  199. // run preflight if possible (since we know we're not an update)
  200. ob_start();
  201. ob_implicit_flush(false);
  202. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight'))
  203. {
  204. if($this->parent->manifestClass->preflight($this->route, $this) === false)
  205. {
  206. // Install failed, rollback changes
  207. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
  208. return false;
  209. }
  210. }
  211. $msg = ob_get_contents(); // create msg object; first use here
  212. ob_end_clean();
  213. /**
  214. * ---------------------------------------------------------------------------------------------
  215. * Filesystem Processing Section
  216. * ---------------------------------------------------------------------------------------------
  217. */
  218. // If the plugin directory does not exist, lets create it
  219. $created = false;
  220. if (!file_exists($this->parent->getPath('extension_root')))
  221. {
  222. if (!$created = JFolder::create($this->parent->getPath('extension_root')))
  223. {
  224. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_CREATE_DIRECTORY', JText::_('JLIB_INSTALLER_'.$this->route), $this->parent->getPath('extension_root')));
  225. return false;
  226. }
  227. }
  228. // if we're updating at this point when there is always going to be an extension_root find the old xml files
  229. if($this->route == 'update')
  230. {
  231. // Hunt for the original XML file
  232. $old_manifest = null;
  233. $tmpInstaller = new JInstaller(); // create a new installer because findManifest sets stuff; side effects!
  234. // look in the extension root
  235. $tmpInstaller->setPath('source', $this->parent->getPath('extension_root'));
  236. if ($tmpInstaller->findManifest())
  237. {
  238. $old_manifest = $tmpInstaller->getManifest();
  239. $this->oldFiles = $old_manifest->files;
  240. }
  241. }
  242. /*
  243. * If we created the plugin directory and will want to remove it if we
  244. * have to roll back the installation, lets add it to the installation
  245. * step stack
  246. */
  247. if ($created) {
  248. $this->parent->pushStep(array ('type' => 'folder', 'path' => $this->parent->getPath('extension_root')));
  249. }
  250. // Copy all necessary files
  251. if ($this->parent->parseFiles($xml->files, -1, $this->oldFiles) === false)
  252. {
  253. // Install failed, roll back changes
  254. $this->parent->abort();
  255. return false;
  256. }
  257. // Parse optional tags -- media and language files for plugins go in admin app
  258. $this->parent->parseMedia($xml->media, 1);
  259. $this->parent->parseLanguages($xml->languages, 1);
  260. // If there is a manifest script, lets copy it.
  261. if ($this->get('manifest_script'))
  262. {
  263. $path['src'] = $this->parent->getPath('source').DS.$this->get('manifest_script');
  264. $path['dest'] = $this->parent->getPath('extension_root').DS.$this->get('manifest_script');
  265. if (!file_exists($path['dest']))
  266. {
  267. if (!$this->parent->copyFiles(array ($path)))
  268. {
  269. // Install failed, rollback changes
  270. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_MANIFEST', JText::_('JLIB_INSTALLER_'.$this->route)));
  271. return false;
  272. }
  273. }
  274. }
  275. /**
  276. * ---------------------------------------------------------------------------------------------
  277. * Database Processing Section
  278. * ---------------------------------------------------------------------------------------------
  279. */
  280. $row = JTable::getInstance('extension');
  281. // Was there a plugin already installed with the same name?
  282. if ($id)
  283. {
  284. if (!$this->parent->getOverwrite())
  285. {
  286. // Install failed, roll back changes
  287. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ALLREADY_EXISTS', JText::_('JLIB_INSTALLER_'.$this->route), $this->get('name')));
  288. return false;
  289. }
  290. $row->load($id);
  291. $row->name = $this->get('name');
  292. $row->manifest_cache = $this->parent->generateManifestCache();
  293. $row->store(); // update the manifest cache and name
  294. }
  295. else
  296. {
  297. // Store in the extensions table (1.6)
  298. $row->name = $this->get('name');
  299. $row->type = 'plugin';
  300. $row->ordering = 0;
  301. $row->element = $element;
  302. $row->folder = $group;
  303. $row->enabled = 0;
  304. $row->protected = 0;
  305. $row->access = 1;
  306. $row->client_id = 0;
  307. $row->params = $this->parent->getParams();
  308. $row->custom_data = ''; // custom data
  309. $row->system_data = ''; // system data
  310. $row->manifest_cache = $this->parent->generateManifestCache();
  311. // Editor plugins are published by default
  312. if ($group == 'editors') {
  313. $row->enabled = 1;
  314. }
  315. if (!$row->store())
  316. {
  317. // Install failed, roll back changes
  318. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_ROLLBACK', JText::_('JLIB_INSTALLER_'.$this->route), $db->stderr(true)));
  319. return false;
  320. }
  321. // Since we have created a plugin item, we add it to the installation step stack
  322. // so that if we have to rollback the changes we can undo it.
  323. $this->parent->pushStep(array ('type' => 'extension', 'id' => $row->extension_id));
  324. $id = $row->extension_id;
  325. }
  326. /*
  327. * Let's run the queries for the module
  328. * If Joomla 1.5 compatible, with discreet sql files - execute appropriate
  329. * file for utf-8 support or non-utf-8 support
  330. */
  331. // try for Joomla 1.5 type queries
  332. // second argument is the utf compatible version attribute
  333. if(strtolower($this->route) == 'install') {
  334. $utfresult = $this->parent->parseSQLFiles($this->manifest->install->sql);
  335. if ($utfresult === false)
  336. {
  337. // Install failed, rollback changes
  338. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_'.$this->route), $db->stderr(true)));
  339. return false;
  340. }
  341. // Set the schema version to be the latest update version
  342. if($this->manifest->update) {
  343. $this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
  344. }
  345. } else if(strtolower($this->route) == 'update') {
  346. if($this->manifest->update)
  347. {
  348. $result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
  349. if ($result === false)
  350. {
  351. // Install failed, rollback changes
  352. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_UPDATE_SQL_ERROR', $db->stderr(true)));
  353. return false;
  354. }
  355. }
  356. }
  357. // Start Joomla! 1.6
  358. ob_start();
  359. ob_implicit_flush(false);
  360. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,$this->route))
  361. {
  362. if($this->parent->manifestClass->{$this->route}($this) === false)
  363. {
  364. // Install failed, rollback changes
  365. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
  366. return false;
  367. }
  368. }
  369. $msg .= ob_get_contents(); // append messages
  370. ob_end_clean();
  371. /**
  372. * ---------------------------------------------------------------------------------------------
  373. * Finalization and Cleanup Section
  374. * ---------------------------------------------------------------------------------------------
  375. */
  376. // Lastly, we will copy the manifest file to its appropriate place.
  377. if (!$this->parent->copyManifest(-1))
  378. {
  379. // Install failed, rollback changes
  380. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_INSTALL_COPY_SETUP', JText::_('JLIB_INSTALLER_'.$this->route)));
  381. return false;
  382. }
  383. // And now we run the postflight
  384. ob_start();
  385. ob_implicit_flush(false);
  386. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'postflight'))
  387. {
  388. $this->parent->manifestClass->postflight($this->route, $this);
  389. }
  390. $msg .= ob_get_contents(); // append messages
  391. ob_end_clean();
  392. if ($msg != '') {
  393. $this->parent->set('extension_message', $msg);
  394. }
  395. return $id;
  396. }
  397. /**
  398. * Custom update method
  399. *
  400. * @access public
  401. * @return boolean True on success
  402. * @since 11.1
  403. */
  404. function update()
  405. {
  406. // set the overwrite setting
  407. $this->parent->setOverwrite(true);
  408. $this->parent->setUpgrade(true);
  409. // set the route for the install
  410. $this->route = 'update';
  411. // go to install which handles updates properly
  412. return $this->install();
  413. }
  414. /**
  415. * Custom uninstall method
  416. *
  417. * @access public
  418. * @param int $cid The id of the plugin to uninstall
  419. * @param int $clientId The id of the client (unused)
  420. * @return boolean True on success
  421. * @since 11.1
  422. */
  423. public function uninstall($id)
  424. {
  425. // Initialise variables.
  426. $row = null;
  427. $retval = true;
  428. $db = $this->parent->getDbo();
  429. // First order of business will be to load the module object table from the database.
  430. // This should give us the necessary information to proceed.
  431. $row = JTable::getInstance('extension');
  432. if (!$row->load((int) $id))
  433. {
  434. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_ERRORUNKOWNEXTENSION'));
  435. return false;
  436. }
  437. // Is the plugin we are trying to uninstall a core one?
  438. // Because that is not a good idea...
  439. if ($row->protected)
  440. {
  441. JError::raiseWarning(100, JText::sprintf('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_WARNCOREPLUGIN', $row->name));
  442. return false;
  443. }
  444. // Get the plugin folder so we can properly build the plugin path
  445. if (trim($row->folder) == '')
  446. {
  447. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_FOLDER_FIELD_EMPTY'));
  448. return false;
  449. }
  450. // Set the plugin root path
  451. if (is_dir(JPATH_PLUGINS.DS.$row->folder.DS.$row->element)) {
  452. // Use 1.6 plugins
  453. $this->parent->setPath('extension_root', JPATH_PLUGINS.DS.$row->folder.DS.$row->element);
  454. }
  455. else {
  456. // Use Legacy 1.5 plugins
  457. $this->parent->setPath('extension_root', JPATH_PLUGINS.DS.$row->folder);
  458. }
  459. // Because plugins don't have their own folders we cannot use the standard method of finding an installation manifest
  460. // Since 1.6 they do, however until we move to 1.7 and remove 1.6 legacy we still need to use this method
  461. // when we get there it'll be something like "$this->parent->findManifest();$manifest = $this->parent->getManifest();"
  462. $manifestFile = $this->parent->getPath('extension_root').DS.$row->element.'.xml';
  463. if ( ! file_exists($manifestFile))
  464. {
  465. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_INVALID_NOTFOUND_MANIFEST'));
  466. return false;
  467. }
  468. $xml = JFactory::getXML($manifestFile);
  469. $this->manifest = $xml;
  470. // If we cannot load the xml file return null
  471. if (!$xml)
  472. {
  473. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_LOAD_MANIFEST'));
  474. return false;
  475. }
  476. /*
  477. * Check for a valid XML root tag.
  478. * @todo: Remove backwards compatability in a future version
  479. * Should be 'extension', but for backward compatability we will accept 'install'.
  480. */
  481. if ($xml->getName() != 'install' && $xml->getName() != 'extension')
  482. {
  483. JError::raiseWarning(100, JText::_('JLIB_INSTALLER_ERROR_PLG_UNINSTALL_INVALID_MANIFEST'));
  484. return false;
  485. }
  486. // Attempt to load the language file; might have uninstall strings
  487. $this->parent->setPath('source', JPATH_PLUGINS .'/'.$row->folder.'/'.$row->element);
  488. $this->loadLanguage(JPATH_PLUGINS .'/'.$row->folder.'/'.$row->element);
  489. /**
  490. * ---------------------------------------------------------------------------------------------
  491. * Installer Trigger Loading
  492. * ---------------------------------------------------------------------------------------------
  493. */
  494. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  495. $manifestScript = (string)$xml->scriptfile;
  496. if ($manifestScript)
  497. {
  498. $manifestScriptFile = $this->parent->getPath('source').DS.$manifestScript;
  499. if (is_file($manifestScriptFile)) {
  500. // load the file
  501. include_once $manifestScriptFile;
  502. }
  503. // Set the class name
  504. $classname = 'plg'.$row->folder.$row->element.'InstallerScript';
  505. if (class_exists($classname))
  506. {
  507. // create a new instance
  508. $this->parent->manifestClass = new $classname($this);
  509. // and set this so we can copy it later
  510. $this->set('manifest_script', $manifestScript);
  511. // Note: if we don't find the class, don't bother to copy the file
  512. }
  513. }
  514. // run preflight if possible (since we know we're not an update)
  515. ob_start();
  516. ob_implicit_flush(false);
  517. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'preflight'))
  518. {
  519. if($this->parent->manifestClass->preflight($this->route, $this) === false)
  520. {
  521. // Install failed, rollback changes
  522. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PLG_INSTALL_CUSTOM_INSTALL_FAILURE'));
  523. return false;
  524. }
  525. }
  526. $msg = ob_get_contents(); // create msg object; first use here
  527. ob_end_clean();
  528. /*
  529. * Let's run the queries for the module
  530. * If Joomla 1.5 compatible, with discreet sql files - execute appropriate
  531. * file for utf-8 support or non-utf-8 support
  532. */
  533. // try for Joomla 1.5 type queries
  534. // second argument is the utf compatible version attribute
  535. $utfresult = $this->parent->parseSQLFiles($xml->{strtolower($this->route)}->sql);
  536. if ($utfresult === false)
  537. {
  538. // Install failed, rollback changes
  539. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_PLG_UNINSTALL_SQL_ERROR', $db->stderr(true)));
  540. return false;
  541. }
  542. // Start Joomla! 1.6
  543. ob_start();
  544. ob_implicit_flush(false);
  545. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass,'uninstall'))
  546. {
  547. $this->parent->manifestClass->uninstall($this);
  548. }
  549. $msg = ob_get_contents(); // append messages
  550. ob_end_clean();
  551. // Remove the plugin files
  552. $this->parent->removeFiles($xml->images, -1);
  553. $this->parent->removeFiles($xml->files, -1);
  554. JFile::delete($manifestFile);
  555. // Remove all media and languages as well
  556. $this->parent->removeFiles($xml->media);
  557. $this->parent->removeFiles($xml->languages, 1);
  558. // Remove the schema version
  559. $query = $db->getQuery(true);
  560. $query->delete()->from('#__schemas')->where('extension_id = '. $row->extension_id);
  561. $db->setQuery($query);
  562. $db->Query();
  563. // Now we will no longer need the plugin object, so lets delete it
  564. $row->delete($row->extension_id);
  565. unset ($row);
  566. // If the folder is empty, let's delete it
  567. $files = JFolder::files($this->parent->getPath('extension_root'));
  568. JFolder::delete($this->parent->getPath('extension_root'));
  569. if ($msg) {
  570. $this->parent->set('extension_message',$msg);
  571. }
  572. return $retval;
  573. }
  574. /**
  575. * Custom discover method
  576. *
  577. * @access public
  578. * @return array(JExtension) list of extensions available
  579. * @since 1.6
  580. */
  581. function discover()
  582. {
  583. $results = Array();
  584. $folder_list = JFolder::folders(JPATH_SITE.DS.'plugins');
  585. foreach ($folder_list as $folder)
  586. {
  587. $file_list = JFolder::files(JPATH_SITE.DS.'plugins'.DS.$folder,'\.xml$');
  588. foreach ($file_list as $file)
  589. {
  590. $manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE.'/plugins/'.$folder.'/'.$file);
  591. $file = JFile::stripExt($file);
  592. if ($file == 'example') continue; // ignore example plugins
  593. $extension = JTable::getInstance('extension');
  594. $extension->set('type', 'plugin');
  595. $extension->set('client_id', 0);
  596. $extension->set('element', $file);
  597. $extension->set('folder', $folder);
  598. $extension->set('name', $file);
  599. $extension->set('state', -1);
  600. $extension->set('manifest_cache', json_encode($manifest_details));
  601. $results[] = $extension;
  602. }
  603. $folder_list = JFolder::folders(JPATH_SITE.DS.'plugins'.DS.$folder);
  604. foreach ($folder_list as $plugin_folder)
  605. {
  606. $file_list = JFolder::files(JPATH_SITE.DS.'plugins'.DS.$folder.DS.$plugin_folder,'\.xml$');
  607. foreach ($file_list as $file)
  608. {
  609. $manifest_details = JApplicationHelper::parseXMLInstallFile(JPATH_SITE.'/plugins/'.$folder.'/'.$plugin_folder.'/'.$file);
  610. $file = JFile::stripExt($file);
  611. if ($file == 'example') continue; // ignore example plugins
  612. $extension = JTable::getInstance('extension');
  613. $extension->set('type', 'plugin');
  614. $extension->set('client_id', 0);
  615. $extension->set('element', $file);
  616. $extension->set('folder', $folder);
  617. $extension->set('name', $file);
  618. $extension->set('state', -1);
  619. $extension->set('manifest_cache', json_encode($manifest_details));
  620. $results[] = $extension;
  621. }
  622. }
  623. }
  624. return $results;
  625. }
  626. /**
  627. * Custom discover_install method
  628. *
  629. * @access public
  630. * @param int $id The id of the extension to install (from #__discoveredextensions)
  631. * @return void
  632. * @since 1.6
  633. */
  634. function discover_install()
  635. {
  636. // Plugins use the extensions table as their primary store
  637. // Similar to modules and templates, rather easy
  638. // If its not in the extensions table we just add it
  639. $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
  640. if (is_dir($client->path . DS . 'plugins'. DS . $this->parent->extension->folder . DS . $this->parent->extension->element)) {
  641. $manifestPath = $client->path . DS . 'plugins'. DS . $this->parent->extension->folder . DS . $this->parent->extension->element . DS . $this->parent->extension->element . '.xml';
  642. }
  643. else {
  644. $manifestPath = $client->path . DS . 'plugins'. DS . $this->parent->extension->folder . DS . $this->parent->extension->element . '.xml';
  645. }
  646. $this->parent->manifest = $this->parent->isManifest($manifestPath);
  647. $description = (string)$this->parent->manifest->description;
  648. if ($description) {
  649. $this->parent->set('message', JText::_($description));
  650. }
  651. else {
  652. $this->parent->set('message', '');
  653. }
  654. $this->parent->setPath('manifest', $manifestPath);
  655. $manifest_details = JApplicationHelper::parseXMLInstallFile($manifestPath);
  656. $this->parent->extension->manifest_cache = json_encode($manifest_details);
  657. $this->parent->extension->state = 0;
  658. $this->parent->extension->name = $manifest_details['name'];
  659. $this->parent->extension->enabled = 1;
  660. $this->parent->extension->params = $this->parent->getParams();
  661. if ($this->parent->extension->store()) {
  662. return $this->parent->extension->get('extension_id');
  663. }
  664. else
  665. {
  666. JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_PLG_DISCOVER_STORE_DETAILS'));
  667. return false;
  668. }
  669. }
  670. /**
  671. * Refreshes the extension table cache
  672. * @return boolean result of operation, true if updated, false on failure
  673. * @since 11.1
  674. */
  675. public function refreshManifestCache()
  676. {
  677. // Plugins use the extensions table as their primary store
  678. // Similar to modules and templates, rather easy
  679. // If its not in the extensions table we just add it
  680. $client = JApplicationHelper::getClientInfo($this->parent->extension->client_id);
  681. $manifestPath = $client->path . '/plugins/'. $this->parent->extension->folder . '/' . $this->parent->extension->element . '/' . $this->parent->extension->element . '.xml';
  682. $this->parent->manifest = $this->parent->isManifest($manifestPath);
  683. $this->parent->setPath('manifest', $manifestPath);
  684. $manifest_details = JApplicationHelper::parseXMLInstallFile($this->parent->getPath('manifest'));
  685. $this->parent->extension->manifest_cache = json_encode($manifest_details);
  686. $this->parent->extension->name = $manifest_details['name'];
  687. if ($this->parent->extension->store()) {
  688. return true;
  689. }
  690. else
  691. {
  692. JError::raiseWarning(101, JText::_('JLIB_INSTALLER_ERROR_PLG_REFRESH_MANIFEST_CACHE'));
  693. return false;
  694. }
  695. }
  696. }