PageRenderTime 80ms CodeModel.GetById 43ms RepoModel.GetById 0ms app.codeStats 1ms

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

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