PageRenderTime 52ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/administrator/components/com_jce/install.php

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