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

/libraries/cms/installer/adapter/file.php

https://bitbucket.org/pastor399/newcastleunifc
PHP | 815 lines | 479 code | 145 blank | 191 comment | 68 complexity | 71733b1600c2515fb67f0be8888faabd MD5 | raw file
  1. <?php
  2. /**
  3. * @package Joomla.Libraries
  4. * @subpackage Installer
  5. *
  6. * @copyright Copyright (C) 2005 - 2013 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. jimport('joomla.filesystem.folder');
  12. /**
  13. * File installer
  14. *
  15. * @package Joomla.Libraries
  16. * @subpackage Installer
  17. * @since 3.1
  18. */
  19. class JInstallerAdapterFile extends JAdapterInstance
  20. {
  21. protected $route = 'install';
  22. /**
  23. * Custom loadLanguage method
  24. *
  25. * @param string $path The path on which to find language files.
  26. *
  27. * @return void
  28. *
  29. * @since 3.1
  30. */
  31. public function loadLanguage($path)
  32. {
  33. $this->manifest = $this->parent->getManifest();
  34. $extension = 'files_' . str_replace('files_', '', strtolower(JFilterInput::getInstance()->clean((string) $this->manifest->name, 'cmd')));
  35. $lang = JFactory::getLanguage();
  36. $source = $path;
  37. $lang->load($extension . '.sys', $source, null, false, false)
  38. || $lang->load($extension . '.sys', JPATH_SITE, null, false, false)
  39. || $lang->load($extension . '.sys', $source, $lang->getDefault(), false, false)
  40. || $lang->load($extension . '.sys', JPATH_SITE, $lang->getDefault(), false, false);
  41. }
  42. /**
  43. * Custom install method
  44. *
  45. * @return boolean True on success
  46. *
  47. * @since 3.1
  48. */
  49. public function install()
  50. {
  51. // Get the extension manifest object
  52. $this->manifest = $this->parent->getManifest();
  53. /*
  54. * ---------------------------------------------------------------------------------------------
  55. * Manifest Document Setup Section
  56. * ---------------------------------------------------------------------------------------------
  57. */
  58. // Set the extension's name
  59. $name = JFilterInput::getInstance()->clean((string) $this->manifest->name, 'string');
  60. $this->set('name', $name);
  61. // Set element
  62. $manifestPath = JPath::clean($this->parent->getPath('manifest'));
  63. $element = preg_replace('/\.xml/', '', basename($manifestPath));
  64. $this->set('element', $element);
  65. // Get the component description
  66. $description = (string) $this->manifest->description;
  67. if ($description)
  68. {
  69. $this->parent->set('message', JText::_($description));
  70. }
  71. else
  72. {
  73. $this->parent->set('message', '');
  74. }
  75. // Check if the extension by the same name is already installed
  76. if ($this->extensionExistsInSystem($element))
  77. {
  78. // Package with same name already exists
  79. if (!$this->parent->isOverwrite())
  80. {
  81. // We're not overwriting so abort
  82. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_SAME_NAME'));
  83. return false;
  84. }
  85. else
  86. {
  87. // Swap to the update route
  88. $this->route = 'update';
  89. }
  90. }
  91. // Set the file root path
  92. if ($name == 'files_joomla')
  93. {
  94. // If we are updating the Joomla core, set the root path to the root of Joomla
  95. $this->parent->setPath('extension_root', JPATH_ROOT);
  96. }
  97. else
  98. {
  99. $this->parent->setPath('extension_root', JPATH_MANIFESTS . '/files/' . $this->get('element'));
  100. }
  101. /**
  102. * ---------------------------------------------------------------------------------------------
  103. * Installer Trigger Loading
  104. * ---------------------------------------------------------------------------------------------
  105. */
  106. // If there is an manifest class file, lets load it; we'll copy it later (don't have dest yet)
  107. $this->scriptElement = $this->manifest->scriptfile;
  108. $manifestScript = (string) $this->manifest->scriptfile;
  109. if ($manifestScript)
  110. {
  111. $manifestScriptFile = $this->parent->getPath('source') . '/' . $manifestScript;
  112. if (is_file($manifestScriptFile))
  113. {
  114. // Load the file
  115. include_once $manifestScriptFile;
  116. }
  117. // Set the class name
  118. $classname = $element . 'InstallerScript';
  119. if (class_exists($classname))
  120. {
  121. // Create a new instance
  122. $this->parent->manifestClass = new $classname($this);
  123. // And set this so we can copy it later
  124. $this->set('manifest_script', $manifestScript);
  125. }
  126. }
  127. // Run preflight if possible (since we know we're not an update)
  128. ob_start();
  129. ob_implicit_flush(false);
  130. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'preflight'))
  131. {
  132. if ($this->parent->manifestClass->preflight($this->route, $this) === false)
  133. {
  134. // Install failed, rollback changes
  135. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
  136. return false;
  137. }
  138. }
  139. // Create msg object; first use here
  140. $msg = ob_get_contents();
  141. ob_end_clean();
  142. // Populate File and Folder List to copy
  143. $this->populateFilesAndFolderList();
  144. /*
  145. * ---------------------------------------------------------------------------------------------
  146. * Filesystem Processing Section
  147. * ---------------------------------------------------------------------------------------------
  148. */
  149. // Now that we have folder list, lets start creating them
  150. foreach ($this->folderList as $folder)
  151. {
  152. if (!JFolder::exists($folder))
  153. {
  154. if (!$created = JFolder::create($folder))
  155. {
  156. JLog::add(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $folder), JLog::WARNING, 'jerror');
  157. // If installation fails, rollback
  158. $this->parent->abort();
  159. return false;
  160. }
  161. // Since we created a directory and will want to remove it if we have to roll back.
  162. // The installation due to some errors, let's add it to the installation step stack.
  163. if ($created)
  164. {
  165. $this->parent->pushStep(array('type' => 'folder', 'path' => $folder));
  166. }
  167. }
  168. }
  169. // Now that we have file list, let's start copying them
  170. $this->parent->copyFiles($this->fileList);
  171. // Parse optional tags
  172. $this->parent->parseLanguages($this->manifest->languages);
  173. /**
  174. * ---------------------------------------------------------------------------------------------
  175. * Finalization and Cleanup Section
  176. * ---------------------------------------------------------------------------------------------
  177. */
  178. // Get a database connector object
  179. $db = $this->parent->getDbo();
  180. /*
  181. * Check to see if a file extension by the same name is already installed
  182. * If it is, then update the table because if the files aren't there
  183. * we can assume that it was (badly) uninstalled
  184. * If it isn't, add an entry to extensions
  185. */
  186. $query = $db->getQuery(true)
  187. ->select($db->quoteName('extension_id'))
  188. ->from($db->quoteName('#__extensions'))
  189. ->where($db->quoteName('type') . ' = ' . $db->quote('file'))
  190. ->where($db->quoteName('element') . ' = ' . $db->quote($element));
  191. $db->setQuery($query);
  192. try
  193. {
  194. $db->execute();
  195. }
  196. catch (RuntimeException $e)
  197. {
  198. // Install failed, roll back changes
  199. $this->parent->abort(
  200. JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
  201. );
  202. return false;
  203. }
  204. $id = $db->loadResult();
  205. $row = JTable::getInstance('extension');
  206. if ($id)
  207. {
  208. // Load the entry and update the manifest_cache
  209. $row->load($id);
  210. // Update name
  211. $row->set('name', $this->get('name'));
  212. // Update manifest
  213. $row->manifest_cache = $this->parent->generateManifestCache();
  214. if (!$row->store())
  215. {
  216. // Install failed, roll back changes
  217. $this->parent->abort(
  218. JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
  219. );
  220. return false;
  221. }
  222. }
  223. else
  224. {
  225. // Add an entry to the extension table with a whole heap of defaults
  226. $row->set('name', $this->get('name'));
  227. $row->set('type', 'file');
  228. $row->set('element', $this->get('element'));
  229. // There is no folder for files so leave it blank
  230. $row->set('folder', '');
  231. $row->set('enabled', 1);
  232. $row->set('protected', 0);
  233. $row->set('access', 0);
  234. $row->set('client_id', 0);
  235. $row->set('params', '');
  236. $row->set('system_data', '');
  237. $row->set('manifest_cache', $this->parent->generateManifestCache());
  238. if (!$row->store())
  239. {
  240. // Install failed, roll back changes
  241. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_ROLLBACK', $db->stderr(true)));
  242. return false;
  243. }
  244. // Since we have created a module item, we add it to the installation step stack
  245. // so that if we have to rollback the changes we can undo it.
  246. $this->parent->pushStep(array('type' => 'extension', 'extension_id' => $row->extension_id));
  247. }
  248. // Let's run the queries for the file
  249. if (strtolower($this->route) == 'install')
  250. {
  251. $result = $this->parent->parseSQLFiles($this->manifest->install->sql);
  252. if ($result === false)
  253. {
  254. // Install failed, rollback changes
  255. $this->parent->abort(
  256. JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_SQL_ERROR', JText::_('JLIB_INSTALLER_' . $this->route), $db->stderr(true))
  257. );
  258. return false;
  259. }
  260. // Set the schema version to be the latest update version
  261. if ($this->manifest->update)
  262. {
  263. $this->parent->setSchemaVersion($this->manifest->update->schemas, $row->extension_id);
  264. }
  265. }
  266. elseif (strtolower($this->route) == 'update')
  267. {
  268. if ($this->manifest->update)
  269. {
  270. $result = $this->parent->parseSchemaUpdates($this->manifest->update->schemas, $row->extension_id);
  271. if ($result === false)
  272. {
  273. // Install failed, rollback changes
  274. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_UPDATE_SQL_ERROR', $db->stderr(true)));
  275. return false;
  276. }
  277. }
  278. }
  279. // Try to run the script file's custom method based on the route
  280. ob_start();
  281. ob_implicit_flush(false);
  282. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, $this->route))
  283. {
  284. if ($this->parent->manifestClass->{$this->route}($this) === false)
  285. {
  286. // Install failed, rollback changes
  287. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_CUSTOM_INSTALL_FAILURE'));
  288. return false;
  289. }
  290. }
  291. // Append messages
  292. $msg .= ob_get_contents();
  293. ob_end_clean();
  294. // Lastly, we will copy the manifest file to its appropriate place.
  295. $manifest = array();
  296. $manifest['src'] = $this->parent->getPath('manifest');
  297. $manifest['dest'] = JPATH_MANIFESTS . '/files/' . basename($this->parent->getPath('manifest'));
  298. if (!$this->parent->copyFiles(array($manifest), true))
  299. {
  300. // Install failed, rollback changes
  301. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_FILE_INSTALL_COPY_SETUP'));
  302. return false;
  303. }
  304. // If there is a manifest script, let's copy it.
  305. if ($this->get('manifest_script'))
  306. {
  307. // First, we have to create a folder for the script if one isn't present
  308. if (!file_exists($this->parent->getPath('extension_root')))
  309. {
  310. JFolder::create($this->parent->getPath('extension_root'));
  311. }
  312. $path['src'] = $this->parent->getPath('source') . '/' . $this->get('manifest_script');
  313. $path['dest'] = $this->parent->getPath('extension_root') . '/' . $this->get('manifest_script');
  314. if (!file_exists($path['dest']) || $this->parent->isOverwrite())
  315. {
  316. if (!$this->parent->copyFiles(array($path)))
  317. {
  318. // Install failed, rollback changes
  319. $this->parent->abort(JText::_('JLIB_INSTALLER_ABORT_PACKAGE_INSTALL_MANIFEST'));
  320. return false;
  321. }
  322. }
  323. }
  324. // Clobber any possible pending updates
  325. $update = JTable::getInstance('update');
  326. $uid = $update->find(
  327. array('element' => $this->get('element'), 'type' => 'file', 'client_id' => '', 'folder' => '')
  328. );
  329. if ($uid)
  330. {
  331. $update->delete($uid);
  332. }
  333. // And now we run the postflight
  334. ob_start();
  335. ob_implicit_flush(false);
  336. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'postflight'))
  337. {
  338. $this->parent->manifestClass->postflight($this->route, $this);
  339. }
  340. // Append messages
  341. $msg .= ob_get_contents();
  342. ob_end_clean();
  343. if ($msg != '')
  344. {
  345. $this->parent->set('extension_message', $msg);
  346. }
  347. return $row->get('extension_id');
  348. }
  349. /**
  350. * Custom update method
  351. *
  352. * @return boolean True on success
  353. *
  354. * @since 3.1
  355. */
  356. public function update()
  357. {
  358. // Set the overwrite setting
  359. $this->parent->setOverwrite(true);
  360. $this->parent->setUpgrade(true);
  361. $this->route = 'update';
  362. // ...and adds new files
  363. return $this->install();
  364. }
  365. /**
  366. * Custom uninstall method
  367. *
  368. * @param string $id The id of the file to uninstall
  369. *
  370. * @return boolean True on success
  371. *
  372. * @since 3.1
  373. */
  374. public function uninstall($id)
  375. {
  376. $row = JTable::getInstance('extension');
  377. if (!$row->load($id))
  378. {
  379. JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_ENTRY'), JLog::WARNING, 'jerror');
  380. return false;
  381. }
  382. if ($row->protected)
  383. {
  384. JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_WARNCOREFILE'), JLog::WARNING, 'jerror');
  385. return false;
  386. }
  387. $retval = true;
  388. $manifestFile = JPATH_MANIFESTS . '/files/' . $row->element . '.xml';
  389. // Because files may not have their own folders we cannot use the standard method of finding an installation manifest
  390. if (file_exists($manifestFile))
  391. {
  392. // Set the files root path
  393. $this->parent->setPath('extension_root', JPATH_MANIFESTS . '/files/' . $row->element);
  394. $xml = simplexml_load_file($manifestFile);
  395. // If we cannot load the XML file return null
  396. if (!$xml)
  397. {
  398. JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_LOAD_MANIFEST'), JLog::WARNING, 'jerror');
  399. return false;
  400. }
  401. // Check for a valid XML root tag.
  402. if ($xml->getName() != 'extension')
  403. {
  404. JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_MANIFEST'), JLog::WARNING, 'jerror');
  405. return false;
  406. }
  407. $this->manifest = $xml;
  408. // If there is an manifest class file, let's load it
  409. $this->scriptElement = $this->manifest->scriptfile;
  410. $manifestScript = (string) $this->manifest->scriptfile;
  411. if ($manifestScript)
  412. {
  413. $manifestScriptFile = $this->parent->getPath('extension_root') . '/' . $manifestScript;
  414. if (is_file($manifestScriptFile))
  415. {
  416. // Load the file
  417. include_once $manifestScriptFile;
  418. }
  419. // Set the class name
  420. $classname = $row->element . 'InstallerScript';
  421. if (class_exists($classname))
  422. {
  423. // Create a new instance
  424. $this->parent->manifestClass = new $classname($this);
  425. // And set this so we can copy it later
  426. $this->set('manifest_script', $manifestScript);
  427. }
  428. }
  429. ob_start();
  430. ob_implicit_flush(false);
  431. // Run uninstall if possible
  432. if ($this->parent->manifestClass && method_exists($this->parent->manifestClass, 'uninstall'))
  433. {
  434. $this->parent->manifestClass->uninstall($this);
  435. }
  436. $msg = ob_get_contents();
  437. ob_end_clean();
  438. if ($msg != '')
  439. {
  440. $this->parent->set('extension_message', $msg);
  441. }
  442. $db = JFactory::getDbo();
  443. // Let's run the uninstall queries for the extension
  444. $result = $this->parent->parseSQLFiles($this->manifest->uninstall->sql);
  445. if ($result === false)
  446. {
  447. // Install failed, rollback changes
  448. JLog::add(JText::sprintf('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_SQL_ERROR', $db->stderr(true)), JLog::WARNING, 'jerror');
  449. $retval = false;
  450. }
  451. // Remove the schema version
  452. $query = $db->getQuery(true)
  453. ->delete('#__schemas')
  454. ->where('extension_id = ' . $row->extension_id);
  455. $db->setQuery($query);
  456. $db->execute();
  457. // Loop through all elements and get list of files and folders
  458. foreach ($xml->fileset->files as $eFiles)
  459. {
  460. $folder = (string) $eFiles->attributes()->folder;
  461. $target = (string) $eFiles->attributes()->target;
  462. // Create folder path
  463. if (empty($target))
  464. {
  465. $targetFolder = JPATH_ROOT;
  466. }
  467. else
  468. {
  469. $targetFolder = JPATH_ROOT . '/' . $target;
  470. }
  471. $folderList = array();
  472. // Check if all children exists
  473. if (count($eFiles->children()) > 0)
  474. {
  475. // Loop through all filenames elements
  476. foreach ($eFiles->children() as $eFileName)
  477. {
  478. if ($eFileName->getName() == 'folder')
  479. {
  480. $folderList[] = $targetFolder . '/' . $eFileName;
  481. }
  482. else
  483. {
  484. $fileName = $targetFolder . '/' . $eFileName;
  485. JFile::delete($fileName);
  486. }
  487. }
  488. }
  489. // Delete any folders that don't have any content in them.
  490. foreach ($folderList as $folder)
  491. {
  492. $files = JFolder::files($folder);
  493. if (!count($files))
  494. {
  495. JFolder::delete($folder);
  496. }
  497. }
  498. }
  499. JFile::delete($manifestFile);
  500. // Lastly, remove the extension_root
  501. $folder = $this->parent->getPath('extension_root');
  502. if (JFolder::exists($folder))
  503. {
  504. JFolder::delete($folder);
  505. }
  506. }
  507. else
  508. {
  509. JLog::add(JText::_('JLIB_INSTALLER_ERROR_FILE_UNINSTALL_INVALID_NOTFOUND_MANIFEST'), JLog::WARNING, 'jerror');
  510. // Delete the row because its broken
  511. $row->delete();
  512. return false;
  513. }
  514. $this->parent->removeFiles($xml->languages);
  515. $row->delete();
  516. return $retval;
  517. }
  518. /**
  519. * Function used to check if extension is already installed
  520. *
  521. * @param string $extension The element name of the extension to install
  522. *
  523. * @return boolean True if extension exists
  524. *
  525. * @since 3.1
  526. */
  527. protected function extensionExistsInSystem($extension = null)
  528. {
  529. // Get a database connector object
  530. $db = $this->parent->getDBO();
  531. $query = $db->getQuery(true)
  532. ->select($db->quoteName('extension_id'))
  533. ->from($db->quoteName('#__extensions'))
  534. ->where($db->quoteName('type') . ' = ' . $db->quote('file'))
  535. ->where($db->quoteName('element') . ' = ' . $db->quote($extension));
  536. $db->setQuery($query);
  537. try
  538. {
  539. $db->execute();
  540. }
  541. catch (RuntimeException $e)
  542. {
  543. // Install failed, roll back changes
  544. $this->parent->abort(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_ROLLBACK', $db->stderr(true)));
  545. return false;
  546. }
  547. $id = $db->loadResult();
  548. if (empty($id))
  549. {
  550. return false;
  551. }
  552. return true;
  553. }
  554. /**
  555. * Function used to populate files and folder list
  556. *
  557. * @return boolean none
  558. *
  559. * @since 3.1
  560. */
  561. protected function populateFilesAndFolderList()
  562. {
  563. // Initialise variable
  564. $this->folderList = array();
  565. $this->fileList = array();
  566. // Set root folder names
  567. $packagePath = $this->parent->getPath('source');
  568. $jRootPath = JPath::clean(JPATH_ROOT);
  569. // Loop through all elements and get list of files and folders
  570. foreach ($this->manifest->fileset->files as $eFiles)
  571. {
  572. // Check if the element is files element
  573. $folder = (string) $eFiles->attributes()->folder;
  574. $target = (string) $eFiles->attributes()->target;
  575. // Split folder names into array to get folder names. This will help in creating folders
  576. $arrList = preg_split("#/|\\/#", $target);
  577. $folderName = $jRootPath;
  578. foreach ($arrList as $dir)
  579. {
  580. if (empty($dir))
  581. {
  582. continue;
  583. }
  584. $folderName .= '/' . $dir;
  585. // Check if folder exists, if not then add to the array for folder creation
  586. if (!JFolder::exists($folderName))
  587. {
  588. array_push($this->folderList, $folderName);
  589. }
  590. }
  591. // Create folder path
  592. $sourceFolder = empty($folder) ? $packagePath : $packagePath . '/' . $folder;
  593. $targetFolder = empty($target) ? $jRootPath : $jRootPath . '/' . $target;
  594. // Check if source folder exists
  595. if (!JFolder::exists($sourceFolder))
  596. {
  597. JLog::add(JText::sprintf('JLIB_INSTALLER_ABORT_FILE_INSTALL_FAIL_SOURCE_DIRECTORY', $sourceFolder), JLog::WARNING, 'jerror');
  598. // If installation fails, rollback
  599. $this->parent->abort();
  600. return false;
  601. }
  602. // Check if all children exists
  603. if (count($eFiles->children()))
  604. {
  605. // Loop through all filenames elements
  606. foreach ($eFiles->children() as $eFileName)
  607. {
  608. $path['src'] = $sourceFolder . '/' . $eFileName;
  609. $path['dest'] = $targetFolder . '/' . $eFileName;
  610. $path['type'] = 'file';
  611. if ($eFileName->getName() == 'folder')
  612. {
  613. $folderName = $targetFolder . '/' . $eFileName;
  614. array_push($this->folderList, $folderName);
  615. $path['type'] = 'folder';
  616. }
  617. array_push($this->fileList, $path);
  618. }
  619. }
  620. else
  621. {
  622. $files = JFolder::files($sourceFolder);
  623. foreach ($files as $file)
  624. {
  625. $path['src'] = $sourceFolder . '/' . $file;
  626. $path['dest'] = $targetFolder . '/' . $file;
  627. array_push($this->fileList, $path);
  628. }
  629. }
  630. }
  631. }
  632. /**
  633. * Refreshes the extension table cache
  634. *
  635. * @return boolean result of operation, true if updated, false on failure
  636. *
  637. * @since 3.1
  638. */
  639. public function refreshManifestCache()
  640. {
  641. // Need to find to find where the XML file is since we don't store this normally
  642. $manifestPath = JPATH_MANIFESTS . '/files/' . $this->parent->extension->element . '.xml';
  643. $this->parent->manifest = $this->parent->isManifest($manifestPath);
  644. $this->parent->setPath('manifest', $manifestPath);
  645. $manifest_details = JInstaller::parseXMLInstallFile($this->parent->getPath('manifest'));
  646. $this->parent->extension->manifest_cache = json_encode($manifest_details);
  647. $this->parent->extension->name = $manifest_details['name'];
  648. try
  649. {
  650. return $this->parent->extension->store();
  651. }
  652. catch (RuntimeException $e)
  653. {
  654. JLog::add(JText::_('JLIB_INSTALLER_ERROR_PACK_REFRESH_MANIFEST_CACHE'), JLog::WARNING, 'jerror');
  655. return false;
  656. }
  657. }
  658. }
  659. /**
  660. * Deprecated class placeholder. You should use JInstallerAdapterFile instead.
  661. *
  662. * @package Joomla.Libraries
  663. * @subpackage Installer
  664. * @since 3.1
  665. * @deprecated 4.0
  666. * @codeCoverageIgnore
  667. */
  668. class JInstallerFile extends JInstallerAdapterFile
  669. {
  670. }