<?php

/**
 * @package       JCE
 * @copyright     Copyright (c) 2009-2017 Ryan Demmer. All rights reserved.
 * @license       GNU/GPL 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * JCE is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 */
defined('_JEXEC') or die('RESTRICTED');

// try to set time limit
@set_time_limit(0);

abstract class WFInstall
{
    public static function install($installer)
    {
        error_reporting(E_ERROR | E_WARNING);

        $app = JFactory::getApplication();

        // load languages
        $language = JFactory::getLanguage();
        $language->load('com_jce', JPATH_ADMINISTRATOR, null, true);
        $language->load('com_jce.sys', JPATH_ADMINISTRATOR, null, true);

        // get manifest
        $manifest = $installer->getManifest();
        $new_version = (string) $manifest->version;

        $state = false;

        // the current version
        $current_version = $installer->get('current_version');

        // install profiles etc.
        $state = self::installProfiles();

        // perform upgrade
        if (version_compare($current_version, $new_version, '<')) {
            $state = self::upgrade($current_version);
        }

        if ($state) {
            $message = '<div class="ui-jce">';
            $message .= '   <h2>' . JText::_('COM_JCE') . ' ' . $new_version . '</h2>';
            $message .= '   <div>' . JText::_('COM_JCE_XML_DESCRIPTION') . '</div>';
            $message .= '</div>';

            $installer->set('message', $message);

            // post-install
            self::addIndexfiles(array(
                __DIR__,
                JPATH_SITE . '/components/com_jce',
                JPATH_PLUGINS . '/content/jce',
                JPATH_PLUGINS . '/editors/jce',
                JPATH_PLUGINS . '/extension/jce',
                JPATH_PLUGINS . '/installer/jce',
                JPATH_PLUGINS . '/quickicon/jce',
                JPATH_PLUGINS . '/system/jce',
            ));
        } else {
            $installer->abort();
            return false;
        }

        return $state;
    }

    private static function loadXMLFile($file)
    {
        $xml = null;

        // Disable libxml errors and allow to fetch error information as needed
        libxml_use_internal_errors(true);

        if (is_file($file)) {
            // Try to load the xml file
            $xml = simplexml_load_file($file);
        }

        return $xml;
    }

    private static function installProfile($name)
    {
        $db = JFactory::getDBO();

        $query = $db->getQuery(true);

        if (is_object($query)) {
            $query->select('COUNT(id)')->from('#__wf_profiles')->where('name = ' . $db->Quote($name));
        } else {
            $query = 'SELECT COUNT(id) FROM #__wf_profiles WHERE name = ' . $db->Quote($name);
        }

        $db->setQuery($query);
        $id = $db->loadResult();

        if (!$id) {
            // Blogger
            $file = JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.xml';

            $xml = self::loadXMLFile($file);

            if ($xml) {
                foreach ($xml->profiles->children() as $profile) {
                    if ((string) $profile->attributes()->name == $name) {
                        $row = JTable::getInstance('profiles', 'WFTable');

                        require_once JPATH_ADMINISTRATOR . '/components/com_jce/models/profiles.php';
                        $groups = WFModelProfiles::getUserGroups((int) $profile->children('area'));

                        foreach ($profile->children() as $item) {
                            switch ((string) $item->getName()) {
                                case 'types':
                                    $row->types = implode(',', $groups);
                                    break;
                                case 'area':
                                    $row->area = (int) $item;
                                    break;
                                case 'rows':
                                    $row->rows = (string) $item;
                                    break;
                                case 'plugins':
                                    $row->plugins = (string) $item;
                                    break;
                                default:
                                    $key = $item->getName();
                                    $row->$key = (string) $item;

                                    break;
                            }
                        }
                        $row->store();
                    }
                }
            }
        }
    }

    /**
     * Upgrade database tables and remove legacy folders
     * @return Boolean
     */
    private static function upgrade($version)
    {
        $app = JFactory::getApplication();
        $db = JFactory::getDBO();

        jimport('joomla.filesystem.folder');
        jimport('joomla.filesystem.file');

        $admin = JPATH_ADMINISTRATOR . '/components/com_jce';
        $site = JPATH_SITE . '/components/com_jce';

        // add tables path
        JTable::addIncludePath($admin . '/tables');

        $files = array(
            $admin . '/adapters/language.php',
            $admin . '/classes/lessc.inc.php',
            $admin . '/controller/installer.php',
            $admin . '/install.script.php',
            $admin . '/media/css/global.css',
            $admin . '/media/css/install.css',
            $admin . '/media/css/installer.css',
            $admin . '/media/css/profiles.css',
            $admin . '/media/css/upload.css',
            $admin . '/media/img/cpanel.png',
            $admin . '/media/img/error.png',
            $admin . '/media/img/glyphicons-halflings-white.png',
            $admin . '/media/img/glyphicons-halflings.png',
            $admin . '/media/img/list_label_bg.gif',
            $admin . '/media/img/menu/jce-config.png',
            $admin . '/media/img/menu/jce-cpanel.png',
            $admin . '/media/img/menu/jce-install.png',
            $admin . '/media/img/menu/jce-profiles.png',
            $admin . '/media/img/spacer.gif',
            $admin . '/media/img/tick.png',
            $admin . '/media/js/browser.js',
            $admin . '/media/js/core.js',
            $admin . '/media/js/installer.js',
            $admin . '/media/js/profile.js',
            $admin . '/media/js/uploads.js',
            $admin . '/models/installer.php',
            $admin . '/models/installer.xml',
            $admin . '/models/plugins.xml',
            $admin . '/models/commands.xml',

            $site . '/editor/elements/mediaplayer.php',
            $site . '/editor/libraries/extensions/imgageeditor/picmonkey.php',
            $site . '/editor/libraries/extensions/imgageeditor/picmonkey.xml',
            $site . '/editor/libraries/extensions/imgageeditor/index.html',
            $site . '/editor/libraries/css/colorpicker.css',
            $site . '/editor/libraries/css/editor.css',
            $site . '/editor/libraries/css/files.css',
            $site . '/editor/libraries/css/help.css',
            $site . '/editor/libraries/css/manager.css',
            $site . '/editor/libraries/css/plugin.css',
            $site . '/editor/libraries/css/popup.css',
            $site . '/editor/libraries/img/broken.png',
            $site . '/editor/libraries/img/cloud_upload.png',
            $site . '/editor/libraries/img/drag.png',
            $site . '/editor/libraries/img/icons-24.png',
            $site . '/editor/libraries/img/icons.png',

            $site . '/editor/libraries/jquery/css/jquery-ui.css',
            $site . '/editor/libraries/js/editor.js',
            $site . '/editor/libraries/js/help.js',
            $site . '/editor/libraries/js/link.full.js',
            $site . '/editor/libraries/js/manager.full.js',
            $site . '/editor/libraries/js/plugin.full.js',
            $site . '/editor/libraries/mediaplayer/license.txt',
            $site . '/editor/tiny_mce/plugins/inlinepopups/css/dialog.css',
            $site . '/editor/tiny_mce/plugins/media/img/iframe.png',
            $site . '/editor/tiny_mce/themes/advanced/img/icons.gif',
        );

        $folders = array(
            $admin . '/adapters',
            $admin . '/views/installer',
            $site . '/editor/extensions/mediaplayer',
            $site . '/editor/libraries/jquery/css/images',
            $site . '/editor/libraries/plupload',
            $site . '/editor/libraries/views/browser',
            $site . '/editor/tiny_mce/themes/advanced/skins/classic',
            $site . '/editor/tiny_mce/themes/advanced/skins/highcontrast',
            $site . '/editor/libraries/extensions/imgageeditor',
            $site . '/editor/libraries/extensions/imgageeditor/picmonkey',
        );

        foreach ($folders as $folder) {
            if (JFolder::exists($folder)) {
                if (!JFolder::delete($folder)) {
                    $app->enqueueMessage('Unable to delete folder: ' . $folder, 'error');
                }
            }
        }

        foreach ($files as $file) {
            if (JFile::exists($file)) {
                if (!JFile::delete($file)) {
                    $app->enqueueMessage('Unable to delete file: ' . $file, 'error');
                }
            }
        }

        // pro cleanup
        if (is_dir($site . '/libraries/pro')) {
            // remove old language files
            $languages = JFolder::files(JPATH_SITE . '/language/en-GB/', '^en-GB\.com_jce_[caption|iframe|filemanager|imgmanager_ext|mediamanager|templatemanager|microdata|emotions|fullpage].*', false, true);

            if (!empty($languages)) {
                JFile::delete($languages);
            }
        }

        // clean up links extension folder
        $files = JFolder::files($site . '/editor/extensions/links', '.', false, true);

        foreach ($files as $file) {
            $name = pathinfo($file, PATHINFO_FILENAME);
            // leave this...
            if ($name === "joomlalinks") {
                continue;
            }
            // delete others
            JFile::delete($file);

            $path = dirname($file);

            if (is_dir($path . '/' . $name)) {
                JFolder::delete($path . '/' . $name);
            }
        }
        return true;
    }

    private static function getProfiles()
    {
        $db = JFactory::getDBO();

        $query = $db->getQuery(true);

        if (is_object($query)) {
            $query->select('id')->from('#__wf_profiles');
        } else {
            $query = 'SELECT id FROM #__wf_profiles';
        }

        $db->setQuery($query);
        return $db->loadObjectList();
    }

    private static function createProfilesTable()
    {
        include_once dirname(__FILE__) . '/includes/base.php';
        include_once dirname(__FILE__) . '/models/profiles.php';

        $profiles = new WFModelProfiles();

        if (method_exists($profiles, 'createProfilesTable')) {
            return $profiles->createProfilesTable();
        }

        return false;
    }

    private static function installProfiles()
    {
        include_once dirname(__FILE__) . '/includes/base.php';
        include_once dirname(__FILE__) . '/models/profiles.php';

        $profiles = new WFModelProfiles();

        if (method_exists($profiles, 'installProfiles')) {
            return $profiles->installProfiles();
        }

        return false;
    }

    private static function addIndexfiles($paths)
    {
        jimport('joomla.filesystem.folder');
        jimport('joomla.filesystem.file');

        // get the base file
        $file = JPATH_ADMINISTRATOR . '/components/com_jce/index.html';

        if (is_file($file)) {

            foreach ((array) $paths as $path) {
                if (is_dir($path)) {
                    // admin component
                    $folders = JFolder::folders($path, '.', true, true);

                    foreach ($folders as $folder) {
                        JFile::copy($file, $folder . '/' . basename($file));
                    }
                }
            }
        }
    }

    private static function checkTableColumn($table, $column)
    {
        $db = JFactory::getDBO();

        // use built in function
        if (method_exists($db, 'getTableColumns')) {
            $fields = $db->getTableColumns($table);
        } else {
            $db->setQuery('DESCRIBE ' . $table);
            if (method_exists($db, 'loadColumn')) {
                $fields = $db->loadColumn();
            } else {
                $fields = $db->loadResultArray();
            }

            // we need to check keys not values
            $fields = array_flip($fields);
        }

        return array_key_exists($column, $fields);
    }
}
