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

/administrator/components/com_jce/install.php

https://github.com/srgg6701/auction-ruseasons
PHP | 1247 lines | 836 code | 251 blank | 160 comment | 167 complexity | 712b34a2d307d2d180febd310771df7b MD5 | raw file
Possible License(s): GPL-2.0, LGPL-3.0, LGPL-2.1, BSD-3-Clause, JSON
  1. <?php
  2. /**
  3. * @package JCE
  4. * @copyright Copyright (c) 2009-2012 Ryan Demmer. All rights reserved.
  5. * @license GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  6. * JCE is free software. This version may have been modified pursuant
  7. * to the GNU General Public License, and as distributed it includes or
  8. * is derivative of works licensed under the GNU General Public License or
  9. * other free or open source software licenses.
  10. */
  11. defined('_JEXEC') or die('RESTRICTED');
  12. abstract class WFInstall {
  13. private static function cleanupInstall() {
  14. $path = JPATH_ADMINISTRATOR . '/components/com_jce';
  15. if (!is_file($path . '/jce.php')) {
  16. self::removePackages();
  17. $db = JFactory::getDBO();
  18. // cleanup menus
  19. if (defined('JPATH_PLATFORM')) {
  20. $query = $db->getQuery(true);
  21. $query->select('id')->from('#__menu')->where(array('alias = ' . $db->Quote('jce'), 'menutype = ' . $db->Quote('main')));
  22. $db->setQuery($query);
  23. $id = $db->loadResult();
  24. $query->clear();
  25. if ($id) {
  26. $table = JTable::getInstance('menu');
  27. // delete main item
  28. $table->delete((int) $id);
  29. // delete children
  30. $query->select('id')->from('#__menu')->where('parent_id = ' . $db->Quote($id));
  31. $db->setQuery($query);
  32. $ids = $db->loadColumn();
  33. $query->clear();
  34. if (!empty($ids)) {
  35. // Iterate the items to delete each one.
  36. foreach ($ids as $menuid) {
  37. $table->delete((int) $menuid);
  38. }
  39. }
  40. // Rebuild the whole tree
  41. $table->rebuild();
  42. }
  43. } else {
  44. $db->setQuery('DELETE FROM #__components WHERE `option` = ' . $db->Quote('com_jce'));
  45. $db->query();
  46. }
  47. }
  48. if (is_file($path . '/install.script.php')) {
  49. jimport('joomla.filesystem.folder');
  50. jimport('joomla.filesystem.file');
  51. JFile::delete($path . '/install.script.php');
  52. JFolder::delete($path);
  53. }
  54. }
  55. public static function install($installer) {
  56. error_reporting(E_ERROR | E_WARNING);
  57. // load languages
  58. $language = JFactory::getLanguage();
  59. $language->load('com_jce', JPATH_ADMINISTRATOR, null, true);
  60. $language->load('com_jce.sys', JPATH_ADMINISTRATOR, null, true);
  61. $requirements = array();
  62. // check PHP version
  63. if (version_compare(PHP_VERSION, '5.2.4', '<')) {
  64. $requirements[] = array(
  65. 'name' => 'PHP Version',
  66. 'info' => 'JCE Requires PHP version 5.2.4 or later. Your version is : ' . PHP_VERSION
  67. );
  68. }
  69. // check JSON is installed
  70. if (function_exists('json_encode') === false || function_exists('json_decode') === false) {
  71. $requirements[] = array(
  72. 'name' => 'JSON',
  73. 'info' => 'JCE requires the <a href="http://php.net/manual/en/book.json.php" target="_blank">PHP JSON</a> extension which is not available on this server.'
  74. );
  75. }
  76. // check SimpleXML
  77. if (function_exists('simplexml_load_string') === false || function_exists('simplexml_load_file') === false || class_exists('SimpleXMLElement') === false) {
  78. $requirements[] = array(
  79. 'name' => 'SimpleXML',
  80. 'info' => 'JCE requires the <a href="http://php.net/manual/en/book.simplexml.php" target="_blank">PHP SimpleXML</a> library which is not available on this server.'
  81. );
  82. }
  83. if (!empty($requirements)) {
  84. $message = '<div id="jce"><style type="text/css" scoped="scoped">' . file_get_contents(dirname(__FILE__) . '/media/css/install.css') . '</style>';
  85. $message .= '<h2>' . JText::_('WF_ADMIN_TITLE') . ' - Install Failed</h2>';
  86. $message .= '<h3>JCE could not be installed as this site does not meet <a href="http://www.joomlacontenteditor.net/support/documentation/56-editor/106-requirements" target="_blank">technical requirements</a> (see below)</h3>';
  87. $message .= '<ul class="install">';
  88. foreach ($requirements as $requirement) {
  89. $message .= '<li class="error">' . $requirement['name'] . ' : ' . $requirement['info'] . '<li>';
  90. }
  91. $message .= '</ul>';
  92. $message .= '</div>';
  93. $installer->set('message', $message);
  94. $installer->abort();
  95. self::cleanupInstall();
  96. return false;
  97. }
  98. // get manifest
  99. $manifest = $installer->getManifest();
  100. $new_version = (string) $manifest->version;
  101. // Joomla! 1.5
  102. if (!defined('JPATH_PLATFORM') && !$new_version) {
  103. $new_version = (string) $manifest->document->getElementByPath('version')->data();
  104. }
  105. // get version from xml file
  106. if (!$manifest) {
  107. $manifest = JApplicationHelper::parseXMLInstallFile($installer->getPath('manifest'));
  108. if (is_array($manifest)) {
  109. $new_version = $manifest['version'];
  110. }
  111. }
  112. $state = false;
  113. // the current version
  114. $current_version = $new_version;
  115. if (defined('JPATH_PLATFORM')) {
  116. $xml_file = $installer->getPath('extension_administrator') . '/jce.xml';
  117. // check for an xml file
  118. if (is_file($xml_file)) {
  119. if ($xml = JApplicationHelper::parseXMLInstallFile($xml_file)) {
  120. $current_version = $xml['version'];
  121. }
  122. }
  123. } else {
  124. if (basename($installer->getPath('manifest')) == 'legacy.xml') {
  125. $xml_file = JPATH_PLUGINS . '/editors/jce.xml';
  126. // check for an xml file
  127. if ($xml = JApplicationHelper::parseXMLInstallFile($xml_file)) {
  128. $current_version = $xml['version'];
  129. } else {
  130. // check for old tables
  131. if (self::checkTable('#__jce_groups')) {
  132. $current_version = '1.5.0';
  133. }
  134. // check for old tables
  135. if (self::checkTable('#__jce_profiles')) {
  136. $current_version = '2.0.0beta1';
  137. }
  138. }
  139. }
  140. }
  141. // perform upgrade
  142. if (version_compare($current_version, $new_version, '<')) {
  143. $state = self::upgrade($current_version);
  144. } else {
  145. // install plugins first
  146. $state = self::installProfiles();
  147. }
  148. if (self::checkTableColumn('#__wf_profiles', 'device') === false) {
  149. $db = JFactory::getDBO();
  150. $query = 'ALTER TABLE #__wf_profiles CHANGE `description` `description` TEXT';
  151. $db->setQuery($query);
  152. $db->query();
  153. // Change types field to TEXT
  154. $query = 'ALTER TABLE #__wf_profiles CHANGE `types` `types` TEXT';
  155. $db->setQuery($query);
  156. $db->query();
  157. // Add device field
  158. $query = 'ALTER TABLE #__wf_profiles ADD `device` VARCHAR(255) AFTER `area`';
  159. if (strtolower($db->name) == 'sqlsrv' || strtolower($db->name) == 'sqlazure') {
  160. $query = 'ALTER TABLE #__wf_profiles ADD `device` NVARCHAR(250)';
  161. }
  162. $db->setQuery($query);
  163. $db->query();
  164. }
  165. if ($state) {
  166. // legacy (JCE 1.5) cleanup
  167. if (!defined('JPATH_PLATFORM')) {
  168. self::legacyCleanup();
  169. }
  170. $message = '<div id="jce"><style type="text/css" scoped="scoped">' . file_get_contents(dirname(__FILE__) . '/media/css/install.css') . '</style>';
  171. $message .= '<h2>' . JText::_('WF_ADMIN_TITLE') . ' ' . $new_version . '</h2>';
  172. $message .= '<ul class="install">';
  173. $message .= '<li class="success">' . JText::_('WF_ADMIN_DESC') . '<li>';
  174. // install packages (editor plugin, quickicon etc)
  175. $packages = dirname(__FILE__) . '/packages';
  176. // install additional packages
  177. if (is_dir($packages)) {
  178. $message .= self::installPackages($packages);
  179. }
  180. $message .= '</ul>';
  181. $message .= '</div>';
  182. $installer->set('message', $message);
  183. // post-install
  184. self::addIndexfiles(array(dirname(__FILE__), JPATH_SITE . '/components/com_jce', JPATH_PLUGINS . '/jce'));
  185. } else {
  186. $installer->abort();
  187. return false;
  188. }
  189. }
  190. public static function uninstall() {
  191. $db = JFactory::getDBO();
  192. // remove Profiles table if its empty
  193. if ((int) self::checkTableContents('#__wf_profiles') == 0) {
  194. if (method_exists($db, 'dropTable')) {
  195. $db->dropTable('#__wf_profiles', true);
  196. } else {
  197. $query = 'DROP TABLE IF EXISTS #__wf_profiles';
  198. $db->setQuery($query);
  199. }
  200. $db->query();
  201. }
  202. // remove packages
  203. self::removePackages();
  204. }
  205. private static function paramsToObject($data) {
  206. $registry = new JRegistry();
  207. $registry->loadIni($data);
  208. return $registry->toObject();
  209. }
  210. private static function loadXMLFile($file) {
  211. $xml = null;
  212. // Disable libxml errors and allow to fetch error information as needed
  213. libxml_use_internal_errors(true);
  214. if (is_file($file)) {
  215. // Try to load the xml file
  216. $xml = simplexml_load_file($file);
  217. }
  218. return $xml;
  219. }
  220. // Upgrade from JCE 1.5.x
  221. private static function upgradeLegacy() {
  222. $app = JFactory::getApplication();
  223. $db = JFactory::getDBO();
  224. $admin = JPATH_ADMINISTRATOR . '/components/com_jce';
  225. $site = JPATH_SITE . '/components/com_jce';
  226. //require_once($admin . '/helpers/parameter.php');
  227. // check for groups table / data
  228. if (self::checkTable('#__jce_groups') && self::checkTableContents('#__jce_groups')) {
  229. jimport('joomla.plugin.helper');
  230. // get plugin
  231. $plugin = JPluginHelper::getPlugin('editors', 'jce');
  232. // get JCE component
  233. $table = JTable::getInstance('component');
  234. $table->loadByOption('com_jce');
  235. // process params to JSON string
  236. $params = self::paramsToObject($table->params);
  237. // set params
  238. $table->params = json_encode(array('editor' => $params));
  239. // store
  240. $table->store();
  241. // get all groups data
  242. $query = 'SELECT * FROM #__jce_groups';
  243. $db->setQuery($query);
  244. $groups = $db->loadObjectList();
  245. // get all plugin data
  246. $query = 'SELECT id, name, icon FROM #__jce_plugins';
  247. $db->setQuery($query);
  248. $plugins = $db->loadAssocList('id');
  249. $map = array(
  250. 'advlink' => 'link',
  251. 'advcode' => 'source',
  252. 'tablecontrols' => 'table',
  253. 'cut,copy,paste' => 'clipboard',
  254. 'paste' => 'clipboard',
  255. 'search,replace' => 'searchreplace',
  256. 'cite,abbr,acronym,del,ins,attribs' => 'xhtmlxtras',
  257. 'styleprops' => 'style',
  258. 'readmore,pagebreak' => 'article',
  259. 'ltr,rtl' => 'directionality',
  260. 'insertlayer,moveforward,movebackward,absolute' => 'layer'
  261. );
  262. if (self::createProfilesTable()) {
  263. foreach ($groups as $group) {
  264. $row = JTable::getInstance('profiles', 'WFTable');
  265. $rows = array();
  266. // transfer row ids to names
  267. foreach (explode(';', $group->rows) as $item) {
  268. $icons = array();
  269. foreach (explode(',', $item) as $id) {
  270. // spacer
  271. if ($id == '00') {
  272. $icon = 'spacer';
  273. } else {
  274. if (isset($plugins[$id])) {
  275. $icon = $plugins[$id]['icon'];
  276. // map old icon names to new
  277. if (array_key_exists($icon, $map)) {
  278. $icon = $map[$icon];
  279. }
  280. }
  281. }
  282. $icons[] = $icon;
  283. }
  284. $rows[] = implode(',', $icons);
  285. }
  286. // re-assign rows
  287. $row->rows = implode(';', $rows);
  288. $names = array('anchor');
  289. // add lists
  290. if (preg_match('#(numlist|bullist)#', $row->rows)) {
  291. $names[] = 'lists';
  292. }
  293. // transfer plugin ids to names
  294. foreach (explode(',', $group->plugins) as $id) {
  295. if (isset($plugins[$id])) {
  296. $name = $plugins[$id]['name'];
  297. // map old icon names to new
  298. if (array_key_exists($name, $map)) {
  299. $name = $map[$name];
  300. }
  301. $names[] = $name;
  302. }
  303. }
  304. // re-assign plugins
  305. $row->plugins = implode(',', $names);
  306. // convert params to JSON
  307. $params = self::paramsToObject($group->params);
  308. $data = new StdClass();
  309. // Add lists plugin
  310. $buttons = array();
  311. if (strpos($row->rows, 'numlist') !== false) {
  312. $buttons[] = 'numlist';
  313. // replace "numlist" with "lists"
  314. $row->rows = str_replace('numlist', 'lists', $row->rows);
  315. }
  316. if (strpos($row->rows, 'bullist') !== false) {
  317. $buttons[] = 'bullist';
  318. // replace "bullist" with "lists"
  319. if (strpos($row->rows, 'lists') === false) {
  320. $row->rows = str_replace('bullist', 'lists', $row->rows);
  321. }
  322. }
  323. // remove bullist and numlist
  324. $row->rows = str_replace(array('bullist', 'numlist'), '', $row->rows);
  325. // add lists buttons parameter
  326. if (!empty($buttons)) {
  327. $params->lists_buttons = $buttons;
  328. }
  329. // convert parameters
  330. foreach ($params as $key => $value) {
  331. $parts = explode('_', $key);
  332. $node = array_shift($parts);
  333. // special consideration for imgmanager_ext!!
  334. if (strpos($key, 'imgmanager_ext_') !== false) {
  335. $node = $node . '_' . array_shift($parts);
  336. }
  337. // convert some nodes
  338. if (isset($map[$node])) {
  339. $node = $map[$node];
  340. }
  341. $key = implode('_', $parts);
  342. if ($value !== '') {
  343. if (!isset($data->$node) || !is_object($data->$node)) {
  344. $data->$node = new StdClass();
  345. }
  346. // convert Link parameters
  347. if ($node == 'link' && $key != 'target') {
  348. $sub = $key;
  349. $key = 'links';
  350. if (!isset($data->$node->$key)) {
  351. $data->$node->$key = new StdClass();
  352. }
  353. if (preg_match('#^(content|contacts|static|weblinks|menu)$#', $sub)) {
  354. if (!isset($data->$node->$key->joomlalinks)) {
  355. $data->$node->$key->joomlalinks = new StdClass();
  356. $data->$node->$key->joomlalinks->enable = 1;
  357. }
  358. $data->$node->$key->joomlalinks->$sub = $value;
  359. } else {
  360. $data->$node->$key->$sub = new StdClass();
  361. $data->$node->$key->$sub->enable = 1;
  362. }
  363. } else {
  364. $data->$node->$key = $value;
  365. }
  366. }
  367. }
  368. // re-assign params
  369. $row->params = json_encode($data);
  370. // re-assign other values
  371. $row->name = $group->name;
  372. $row->description = $group->description;
  373. $row->users = $group->users;
  374. $row->types = $group->types;
  375. $row->components = $group->components;
  376. $row->published = $group->published;
  377. $row->ordering = $group->ordering;
  378. // add area data
  379. if ($row->name == 'Default') {
  380. $row->area = 0;
  381. }
  382. if ($row->name == 'Front End') {
  383. $row->area = 1;
  384. }
  385. if (self::checkTable('#__wf_profiles')) {
  386. $name = $row->name;
  387. // check for existing profile
  388. $query = 'SELECT id FROM #__wf_profiles' . ' WHERE name = ' . $db->Quote($name);
  389. $db->setQuery($query);
  390. // create name copy if exists
  391. while ($db->loadResult()) {
  392. $name = JText::sprintf('WF_PROFILES_COPY_OF', $name);
  393. $query = 'SELECT id FROM #__wf_profiles' . ' WHERE name = ' . $db->Quote($name);
  394. $db->setQuery($query);
  395. }
  396. // set name
  397. $row->name = $name;
  398. }
  399. if (!$row->store()) {
  400. $app->enqueueMessage('Conversion of group data failed : ' . $row->name, 'error');
  401. } else {
  402. $app->enqueueMessage('Conversion of group data successful : ' . $row->name);
  403. }
  404. unset($row);
  405. }
  406. // If profiles table empty due to error, install profiles data
  407. if (!self::checkTableContents('#__wf_profiles')) {
  408. self::installProfiles();
  409. } else {
  410. // add Blogger profile
  411. self::installProfile('Blogger');
  412. // add Mobile profile
  413. self::installProfile('Mobile');
  414. }
  415. } else {
  416. return false;
  417. }
  418. // Install profiles
  419. } else {
  420. self::installProfiles();
  421. }
  422. // Remove Plugins menu item
  423. $query = 'DELETE FROM #__components' . ' WHERE admin_menu_link = ' . $db->Quote('option=com_jce&type=plugins');
  424. $db->setQuery($query);
  425. $db->query();
  426. // Update Component Name
  427. $query = 'UPDATE #__components' . ' SET name = ' . $db->Quote('COM_JCE') . ' WHERE ' . $db->Quote('option') . '=' . $db->Quote('com_jce') . ' AND parent = 0';
  428. $db->setQuery($query);
  429. $db->query();
  430. // Fix links for other views and edit names
  431. $menus = array('install' => 'installer', 'group' => 'profiles', 'groups' => 'profiles', 'config' => 'config');
  432. $row = JTable::getInstance('component');
  433. foreach ($menus as $k => $v) {
  434. $query = 'SELECT id FROM #__components' . ' WHERE admin_menu_link = ' . $db->Quote('option=com_jce&type=' . $k);
  435. $db->setQuery($query);
  436. $id = $db->loadObject();
  437. if ($id) {
  438. $row->load($id);
  439. $row->name = $v;
  440. $row->admin_menu_link = 'option=com_jce&view=' . $v;
  441. if (!$row->store()) {
  442. $mainframe->enqueueMessage('Unable to update Component Links for view : ' . strtoupper($v), 'error');
  443. }
  444. }
  445. }
  446. // remove old admin language files
  447. $folders = JFolder::folders(JPATH_ADMINISTRATOR . '/language', '.', false, true, array('.svn', 'CVS', 'en-GB'));
  448. foreach ($folders as $folder) {
  449. $name = basename($folder);
  450. $files = array($name . '.com_jce.ini', $name . '.com_jce.menu.ini', $name . '.com_jce.xml');
  451. foreach ($files as $file) {
  452. if (is_file($folder . '/' . $file)) {
  453. @JFile::delete($folder . '/' . $file);
  454. }
  455. }
  456. }
  457. // remove old site language files
  458. $folders = JFolder::folders(JPATH_SITE . '/language', '.', false, true, array('.svn', 'CVS', 'en-GB'));
  459. foreach ($folders as $folder) {
  460. $files = JFolder::files($folder, '^' . basename($folder) . '\.com_jce([_a-z0-9]+)?\.(ini|xml)$', false, true);
  461. @JFile::delete($files);
  462. }
  463. // remove legacy admin folders
  464. $folders = array('cpanel', 'config', 'css', 'groups', 'plugins', 'img', 'installer', 'js');
  465. foreach ($folders as $folder) {
  466. if (is_dir($admin . '/' . $folder)) {
  467. @JFolder::delete($admin . '/' . $folder);
  468. }
  469. }
  470. // remove legacy admin files
  471. $files = array('editor.php', 'helper.php', 'updater.php');
  472. foreach ($files as $file) {
  473. if (is_file($admin . '/' . $file)) {
  474. @JFile::delete($admin . '/' . $file);
  475. }
  476. }
  477. // remove legacy admin folders
  478. $folders = array('controller', 'css', 'js');
  479. foreach ($folders as $folder) {
  480. if (is_dir($site . '/' . $folder)) {
  481. @JFolder::delete($site . '/' . $folder);
  482. }
  483. }
  484. // remove legacy admin files
  485. $files = array('popup.php');
  486. foreach ($files as $file) {
  487. if (is_file($site . '/' . $file)) {
  488. @JFile::delete($site . '/' . $file);
  489. }
  490. }
  491. if (!defined('JPATH_PLATFORM')) {
  492. // remove old plugin folder
  493. $path = JPATH_PLUGINS . '/editors';
  494. if (is_dir($path . '/jce')) {
  495. @JFolder::delete($path . '/jce');
  496. }
  497. }
  498. return true;
  499. }
  500. private static function installProfile($name) {
  501. $db = JFactory::getDBO();
  502. $query = $db->getQuery(true);
  503. if (is_object($query)) {
  504. $query->select('COUNT(id)')->from('#__wf_profiles')->where('name = ' . $db->Quote($name));
  505. } else {
  506. $query = 'SELECT COUNT(id) FROM #__wf_profiles WHERE name = ' . $db->Quote($name);
  507. }
  508. $db->setQuery($query);
  509. $id = $db->loadResult();
  510. if (!$id) {
  511. // Blogger
  512. $file = JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.xml';
  513. $xml = self::loadXMLFile($file);
  514. if ($xml) {
  515. foreach ($xml->profiles->children() as $profile) {
  516. if ((string) $profile->attributes()->name == $name) {
  517. $row = JTable::getInstance('profiles', 'WFTable');
  518. require_once(JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.php');
  519. $groups = WFModelProfiles::getUserGroups((int) $profile->children('area'));
  520. foreach ($profile->children() as $item) {
  521. switch ((string) $item->getName()) {
  522. case 'types':
  523. $row->types = implode(',', $groups);
  524. break;
  525. case 'area':
  526. $row->area = (int) $item;
  527. break;
  528. case 'rows':
  529. $row->rows = (string) $item;
  530. break;
  531. case 'plugins':
  532. $row->plugins = (string) $item;
  533. break;
  534. default:
  535. $key = $item->getName();
  536. $row->$key = (string) $item;
  537. break;
  538. }
  539. }
  540. $row->store();
  541. }
  542. }
  543. }
  544. }
  545. }
  546. /**
  547. * Upgrade database tables and remove legacy folders
  548. * @return Boolean
  549. */
  550. private static function upgrade($version) {
  551. $app = JFactory::getApplication();
  552. $db = JFactory::getDBO();
  553. jimport('joomla.filesystem.folder');
  554. jimport('joomla.filesystem.file');
  555. $admin = JPATH_ADMINISTRATOR . '/components/com_jce';
  556. $site = JPATH_SITE . '/components/com_jce';
  557. // add tables path
  558. JTable::addIncludePath($admin . '/tables');
  559. // upgrade from 1.5.x to 2.0.0 (only in Joomla! 1.5)
  560. if (version_compare($version, '2.0.0', '<') && !defined('JPATH_PLATFORM')) {
  561. return self::upgradeLegacy();
  562. }// end JCE 1.5 upgrade
  563. // Remove folders
  564. $folders = array(
  565. // Remove JQuery folders from admin
  566. $admin . '/media/css/jquery',
  567. $admin . '/media/js/jquery',
  568. // remove plugin package folder
  569. $admin . '/plugin',
  570. // remove legend view
  571. $admin . '/views/legend',
  572. // remove controller from site
  573. $site . '/controller',
  574. // Remove plugin language files (incorporated into main language file)
  575. $site . '/editor/tiny_mce/plugins/article/langs',
  576. $site . '/editor/tiny_mce/plugins/imgmanager/langs',
  577. $site . '/editor/tiny_mce/plugins/link/langs',
  578. $site . '/editor/tiny_mce/plugins/searchreplace/langs',
  579. $site . '/editor/tiny_mce/plugins/style/langs',
  580. $site . '/editor/tiny_mce/plugins/table/langs',
  581. $site . '/editor/tiny_mce/plugins/xhtmlxtras/langs',
  582. // remove paste folder
  583. $site . '/editor/tiny_mce/plugins/paste',
  584. // remove jquery
  585. $site . '/editor/libraries/js/jquery',
  586. // remove browser extension
  587. $site . '/editor/extensions/browser'
  588. );
  589. foreach ($folders as $folder) {
  590. if (JFolder::exists($folder)) {
  591. @JFolder::delete($folder);
  592. }
  593. }
  594. // Remove files
  595. $files = array(
  596. // remove javascript files from admin (moved to site)
  597. $admin . '/media/js/colorpicker.js',
  598. $admin . '/media/js/help.js',
  599. $admin . '/media/js/html5.js',
  600. $admin . '/media/js/select.js',
  601. $admin . '/media/js/tips.js',
  602. // remove legend.js
  603. $admin . '/media/js/legend.js',
  604. // remove css files from admin (moved to site)
  605. $admin . '/media/css/help.css',
  606. $admin . '/media/css/select.css',
  607. $admin . '/media/css/tips.css',
  608. // remove legend model
  609. $admin . '/models/legend.php',
  610. // remove extension adapter
  611. $admin . '/adapters/extension.php',
  612. // remove error class from site (moved to admin)
  613. $site . '/editor/libraries/classes/error.php',
  614. // remove popup file
  615. $site . '/popup.php',
  616. // remove anchor from theme (moved to plugins)
  617. $site . '/editor/tiny_mce/themes/advanced/css/anchor.css',
  618. $site . '/editor/tiny_mce/themes/advanced/css/js/anchor.js',
  619. $site . '/editor/tiny_mce/themes/advanced/css/tmpl/anchor.php',
  620. // remove redundant file
  621. $site . '/editor/tiny_mce/themes/advanced/css/skins/default/img/items.gif',
  622. // remove search files from file browser (renamed to filter)
  623. $site . '/editor/extensions/browser/css/search.css',
  624. $site . '/editor/extensions/browser/js/search.js',
  625. $site . '/editor/extensions/browser/search.php',
  626. // remove dilg language file from theme (incorporated into main dlg file)
  627. $site . '/editor/tiny_mce/themes/advanced/langs/en_dlg.js',
  628. // remove old jquery UI
  629. $site . '/editor/libraries/jquery/js/jquery-ui-1.9.0.custom.min.js'
  630. );
  631. foreach ($files as $file) {
  632. if (JFile::exists($file)) {
  633. @JFile::delete($file);
  634. }
  635. }
  636. // 2.1 - Add visualblocks plugin
  637. if (version_compare($version, '2.1', '<')) {
  638. $profiles = self::getProfiles();
  639. $profile = JTable::getInstance('Profiles', 'WFTable');
  640. if (!empty($profiles)) {
  641. foreach ($profiles as $item) {
  642. $profile->load($item->id);
  643. if (strpos($profile->rows, 'visualblocks') === false) {
  644. $profile->rows = str_replace('visualchars', 'visualchars,visualblocks', $profile->rows);
  645. }
  646. if (strpos($profile->plugins, 'visualblocks') === false) {
  647. $profile->plugins = str_replace('visualchars', 'visualchars,visualblocks', $profile->plugins);
  648. }
  649. $profile->store();
  650. }
  651. }
  652. }
  653. // 2.1.1 - Add anchor plugin
  654. if (version_compare($version, '2.1.1', '<')) {
  655. $profiles = self::getProfiles();
  656. $profile = JTable::getInstance('Profiles', 'WFTable');
  657. if (!empty($profiles)) {
  658. foreach ($profiles as $item) {
  659. $profile->load($item->id);
  660. // add anchor to end of plugins list
  661. if (strpos($profile->rows, 'anchor') !== false) {
  662. $profile->plugins .= ',anchor';
  663. }
  664. $profile->store();
  665. }
  666. }
  667. }
  668. // 2.2.1 - Add "Blogger" profile
  669. if (version_compare($version, '2.2.1', '<')) {
  670. self::installProfile('Blogger');
  671. }
  672. // 2.2.1 to 2.2.5 - Remove K2Links partial install
  673. if (version_compare($version, '2.2.1', '>') && version_compare($version, '2.2.5', '<')) {
  674. $path = $site . '/editor/extensions/links';
  675. if (is_file($path . '/k2links.php') && is_file($path . '/k2links.xml') && !is_dir($path . '/k2links')) {
  676. @JFile::delete($path . '/k2links.php');
  677. @JFile::delete($path . '/k2links.xml');
  678. }
  679. }
  680. // replace some profile row items
  681. if (version_compare($version, '2.2.8', '<')) {
  682. $profiles = self::getProfiles();
  683. $profile = JTable::getInstance('Profiles', 'WFTable');
  684. if (!empty($profiles)) {
  685. foreach ($profiles as $item) {
  686. $profile->load($item->id);
  687. $profile->rows = str_replace('paste', 'clipboard', $profile->rows);
  688. $profile->plugins = str_replace('paste', 'clipboard', $profile->plugins);
  689. $data = json_decode($profile->params, true);
  690. // swap paste data to 'clipboard'
  691. if ($data && array_key_exists('paste', $data)) {
  692. $params = array();
  693. // add 'paste_' prefix
  694. foreach ($data['paste'] as $k => $v) {
  695. $params['paste_' . $k] = $v;
  696. }
  697. // remove paste parameters
  698. unset($data['paste']);
  699. // assign new params to clipboard
  700. $data['clipboard'] = $params;
  701. }
  702. $profile->params = json_encode($data);
  703. $profile->store();
  704. }
  705. }
  706. }
  707. if (version_compare($version, '2.3.0beta', '<')) {
  708. // add Mobile profile
  709. self::installProfile('Mobile');
  710. }
  711. if (version_compare($version, '2.2.9', '<') || version_compare($version, '2.3.0beta3', '<')) {
  712. $profiles = self::getProfiles();
  713. $profile = JTable::getInstance('Profiles', 'WFTable');
  714. if (!empty($profiles)) {
  715. foreach ($profiles as $item) {
  716. $profile->load($item->id);
  717. $buttons = array('buttons' => array());
  718. if (strpos($profile->rows, 'numlist') !== false) {
  719. $buttons['buttons'][] = 'numlist';
  720. $profile->rows = str_replace('numlist', 'lists', $profile->rows);
  721. }
  722. if (strpos($profile->rows, 'bullist') !== false) {
  723. $buttons['buttons'][] = 'bullist';
  724. if (strpos($profile->rows, 'lists') === false) {
  725. $profile->rows = str_replace('bullist', 'lists', $profile->rows);
  726. }
  727. }
  728. // remove bullist and numlist
  729. $profile->rows = str_replace(array('bullist', 'numlist'), '', $profile->rows);
  730. // replace multiple commas with a single one
  731. $profile->rows = preg_replace('#,+#', ',', $profile->rows);
  732. // fix rows
  733. $profile->rows = str_replace(',;', ';', $profile->rows);
  734. if (!empty($buttons['buttons'])) {
  735. $profile->plugins .= ',lists';
  736. $data = json_decode($profile->params, true);
  737. $data['lists'] = $buttons;
  738. $profile->params = json_encode($data);
  739. $profile->store();
  740. }
  741. }
  742. }
  743. }
  744. return true;
  745. }
  746. private static function getProfiles() {
  747. $db = JFactory::getDBO();
  748. if (is_object($query)) {
  749. $query->select('id')->from('#__wf_profiles');
  750. } else {
  751. $query = 'SELECT id FROM #__wf_profiles';
  752. }
  753. $db->setQuery($query);
  754. return $db->loadObjectList();
  755. }
  756. private static function createProfilesTable() {
  757. include_once (dirname(__FILE__) . '/includes/base.php');
  758. include_once (dirname(__FILE__) . '/models/profiles.php');
  759. $profiles = new WFModelProfiles();
  760. if (method_exists($profiles, 'createProfilesTable')) {
  761. return $profiles->createProfilesTable();
  762. }
  763. return false;
  764. }
  765. private static function installProfiles() {
  766. include_once (dirname(__FILE__) . '/includes/base.php');
  767. include_once (dirname(__FILE__) . '/models/profiles.php');
  768. $profiles = new WFModelProfiles();
  769. if (method_exists($profiles, 'installProfiles')) {
  770. return $profiles->installProfiles();
  771. }
  772. return false;
  773. }
  774. /**
  775. * Install additional packages
  776. * @return Array or false
  777. * @param object $path[optional] Path to package folder
  778. */
  779. private static function installPackages($source) {
  780. jimport('joomla.installer.installer');
  781. $mainframe = JFactory::getApplication();
  782. $db = JFactory::getDBO();
  783. $result = '';
  784. JTable::addIncludePath(JPATH_LIBRARIES . '/joomla/database/table');
  785. $packages = array(
  786. 'editors' => array('jce'),
  787. 'quickicon' => array('jcefilebrowser'),
  788. 'modules' => array('mod_jcefilebrowser')
  789. );
  790. foreach ($packages as $folder => $element) {
  791. // Joomla! 2.5
  792. if (defined('JPATH_PLATFORM')) {
  793. if ($folder == 'modules') {
  794. continue;
  795. }
  796. // Joomla! 1.5
  797. } else {
  798. if ($folder == 'quickicon') {
  799. continue;
  800. }
  801. }
  802. $installer = new JInstaller();
  803. $installer->setOverwrite(true);
  804. if ($installer->install($source . '/' . $folder)) {
  805. if (method_exists($installer, 'loadLanguage')) {
  806. $installer->loadLanguage();
  807. }
  808. if ($installer->message) {
  809. $result .= '<li class="success">' . JText::_($installer->message, $installer->message) . '</li>';
  810. }
  811. // enable quickicon
  812. if ($folder == 'quickicon') {
  813. $plugin = JTable::getInstance('extension');
  814. foreach ($element as $item) {
  815. $id = $plugin->find(array('type' => 'plugin', 'folder' => $folder, 'element' => $item));
  816. $plugin->load($id);
  817. $plugin->publish();
  818. }
  819. }
  820. // enable module
  821. if ($folder == 'modules') {
  822. $module = JTable::getInstance('module');
  823. foreach ($element as $item) {
  824. $id = self::getModule($item);
  825. $module->load($id);
  826. $module->position = 'icon';
  827. $module->ordering = 100;
  828. $module->published = 1;
  829. $module->store();
  830. }
  831. }
  832. if ($folder == 'editors') {
  833. $manifest = $installer->getPath('manifest');
  834. if (basename($manifest) == 'legacy.xml') {
  835. // rename legacy.xml to jce.xml
  836. JFile::move($installer->getPath('extension_root') . '/' . basename($manifest), $installer->getPath('extension_root') . '/jce.xml');
  837. }
  838. }
  839. // add index files
  840. self::addIndexfiles(array($installer->getPath('extension_root')));
  841. } else {
  842. $result .= '<li class="error">' . JText::_($installer->message, $installer->message) . '</li>';
  843. }
  844. }
  845. return $result;
  846. }
  847. private static function getModule($name) {
  848. // Joomla! 2.5
  849. if (defined('JPATH_PLATFORM')) {
  850. $module = JTable::getInstance('extension');
  851. return $module->find(array('type' => 'module', 'element' => $name));
  852. // Joomla! 1.5
  853. } else {
  854. $db = JFactory::getDBO();
  855. $query = 'SELECT id FROM #__modules' . ' WHERE module = ' . $db->Quote($name);
  856. $db->setQuery($query);
  857. return $db->loadResult();
  858. }
  859. }
  860. private static function getPlugin($folder, $element) {
  861. // Joomla! 2.5
  862. if (defined('JPATH_PLATFORM')) {
  863. $plugin = JTable::getInstance('extension');
  864. return $plugin->find(array('type' => 'plugin', 'folder' => $folder, 'element' => $element));
  865. // Joomla! 1.5
  866. } else {
  867. $plugin = JTable::getInstance('plugin');
  868. $db = JFactory::getDBO();
  869. $query = 'SELECT id FROM #__plugins' . ' WHERE folder = ' . $db->Quote($folder) . ' AND element = ' . $db->Quote($element);
  870. $db->setQuery($query);
  871. return $db->loadResult();
  872. }
  873. }
  874. /**
  875. * Uninstall the editor
  876. * @return boolean
  877. */
  878. private static function removePackages() {
  879. $app = JFactory::getApplication();
  880. $db = JFactory::getDBO();
  881. jimport('joomla.module.helper');
  882. jimport('joomla.installer.installer');
  883. $plugins = array(
  884. 'editors' => array('jce'),
  885. 'quickicon' => array('jcefilebrowser')
  886. );
  887. $modules = array('mod_jcefilebrowser');
  888. // items to remove
  889. $items = array(
  890. 'plugin' => array(),
  891. 'module' => array()
  892. );
  893. foreach ($plugins as $folder => $elements) {
  894. foreach ($elements as $element) {
  895. $item = self::getPlugin($folder, $element);
  896. if ($item) {
  897. $items['plugin'][] = $item;
  898. }
  899. }
  900. }
  901. foreach ($modules as $module) {
  902. $item = self::getModule($module);
  903. if ($item) {
  904. $items['module'][] = $item;
  905. }
  906. }
  907. foreach ($items as $type => $extensions) {
  908. if ($extensions) {
  909. foreach ($extensions as $id) {
  910. $installer = new JInstaller();
  911. $installer->uninstall($type, $id);
  912. $app->enqueueMessage($installer->message);
  913. }
  914. }
  915. }
  916. }
  917. private static function addIndexfiles($paths) {
  918. jimport('joomla.filesystem.folder');
  919. jimport('joomla.filesystem.file');
  920. // get the base file
  921. $file = JPATH_ADMINISTRATOR . '/components' . 'com_jce/index.html';
  922. if (is_file($file)) {
  923. foreach ((array) $paths as $path) {
  924. if (is_dir($path)) {
  925. // admin component
  926. $folders = JFolder::folders($path, '.', true, true);
  927. foreach ($folders as $folder) {
  928. JFile::copy($file, $folder . '/' . basename($file));
  929. }
  930. }
  931. }
  932. }
  933. }
  934. private static function legacyCleanup() {
  935. $db = JFactory::getDBO();
  936. $query = 'DROP TABLE IF EXISTS #__jce_groups';
  937. $db->setQuery($query);
  938. $db->query();
  939. $query = 'DROP TABLE IF EXISTS #__jce_plugins';
  940. $db->setQuery($query);
  941. $db->query();
  942. $query = 'DROP TABLE IF EXISTS #__jce_extensions';
  943. $db->setQuery($query);
  944. $db->query();
  945. }
  946. private static function checkTable($table) {
  947. $db = JFactory::getDBO();
  948. $tables = $db->getTableList();
  949. if (!empty($tables)) {
  950. // swap array values with keys, convert to lowercase and return array keys as values
  951. $tables = array_keys(array_change_key_case(array_flip($tables)));
  952. $app = JFactory::getApplication();
  953. $match = str_replace('#__', strtolower($app->getCfg('dbprefix', '')), $table);
  954. return in_array($match, $tables);
  955. }
  956. // try with query
  957. $query = $db->getQuery(true);
  958. if (is_object($query)) {
  959. $query->select('COUNT(id)')->from($table);
  960. } else {
  961. $query = 'SELECT COUNT(id) FROM ' . $table;
  962. }
  963. $db->setQuery($query);
  964. return $db->query();
  965. }
  966. /**
  967. * Check table contents
  968. * @return integer
  969. * @param string $table Table name
  970. */
  971. private static function checkTableContents($table) {
  972. $db = JFactory::getDBO();
  973. $query = $db->getQuery(true);
  974. if (is_object($query)) {
  975. $query->select('COUNT(id)')->from($table);
  976. } else {
  977. $query = 'SELECT COUNT(id) FROM ' . $table;
  978. }
  979. $db->setQuery($query);
  980. return $db->loadResult();
  981. }
  982. private static function checkTableColumn($table, $column) {
  983. $db = JFactory::getDBO();
  984. // use built in function
  985. if (method_exists($db, 'getTableColumns')) {
  986. $fields = $db->getTableColumns($table);
  987. } else {
  988. $db->setQuery('DESCRIBE ' . $table);
  989. $fields = $db->loadResultArray();
  990. // we need to check keys not values
  991. $fields = array_flip($fields);
  992. }
  993. return array_key_exists($column, $fields);
  994. }
  995. }
  996. ?>