<?php

/*
 * @component UserPoints
 * @copyright Copyright (C) 2015-2022 Bernard Gilly - Adrien Roussel - Martin Brampton
 * @license : GNU/GPL
 * @Website : https://remository.com
 */

defined('_JEXEC') or die('Restricted access');

use Joomla\CMS\Factory;
use Joomla\CMS\Version;
use Joomla\CMS\Installer\Installer;
use Joomla\CMS\Installer\InstallerScript;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Plugin\PluginHelper;
use BlackSheepResearch\Component\UserPoints\Site;
use BlackSheepResearch\Component\UserPoints\Site\Problems\OptionChange;

$mycomponent = 'userpoints';

class com_userpointsInstallerScript extends InstallerScript {

    protected $extension = 'com_userpoints';
    protected $deleteFolders = [
        '/plugins/altauserpoints',
        '/plugins/system/altauserpoints',
        '/plugins/content/sysplgaup_content',
        '/plugins/content/sysplgaup_reader2author',
        '/plugins/content/sysplgaup_raffle',
        '/plugins/quickicon/altauserpointsicon',
        '/plugins/user/sysplgaup_newregistered',
        '/components/com_altauserpoints',
        '/administrator/components/com_altauserpoints'
    ];
    private $error = 0;
    private $install = '';
    private $elements = [];
    private $installer = null;
    private $db = null;
    private $app = null;
    private $fieldnames = [];

    public function __construct() {
        $this->installer = new Installer();
        // The following preferred for Joomla 4
        // $this->db = Factory::getContainer()->get('DatabaseDriver');
        $this->db = Factory::getDbo();
        $this->app = Factory::getApplication();
    }

    public function postflight($type, $parent) {
        $this->dropColumn('#__alpha_userpoints', 'points');
        $view1 = "CREATE OR REPLACE VIEW `#__alpha_userpoints_combined` AS SELECT a.*, IFNULL(d.sumpoints, 0.0) AS points,
            IFNULL(m.medalcount,0) AS nummedals, u.name, u.username, u.email, u.block, registerDate, lastvisitDate
            FROM #__alpha_userpoints AS a LEFT JOIN #__users AS u ON u.id = a.userid
            LEFT JOIN (SELECT referreid, SUM(points) AS sumpoints FROM #__alpha_userpoints_details
            WHERE approved != 0 AND (expire_date > NOW() OR expire_date = '1000-01-01 00:00:00') AND `enabled` != 0 AND `status` != 0
            GROUP BY referreid) AS d ON a.referreid = d.referreid
            LEFT JOIN (SELECT medal, COUNT(medal) AS medalcount FROM #__alpha_userpoints_medals GROUP BY medal) AS m ON a.id = m.medal";
        $this->db->setQuery($view1);
        $this->db->execute();
        $this->addColumn('#__alpha_userpoints_details', 'rule_id', "varchar(50) NOT NULL DEFAULT ''", 'referreid');
        $this->addColumn('#__alpha_userpoints_details_archive', 'rule_id', "varchar(50) NOT NULL DEFAULT ''", 'referreid');
        $this->addColumn('#__alpha_userpoints_rules', 'allow_referral', 'tinyint(1) NOT NULL DEFAULT 1', 'fixedpoints');
        $view2 = "CREATE OR REPLACE VIEW `#__alpha_userpoints_details_combined` AS "
                . " SELECT d.*, r.rule_name, r.plugin_function, r.content_items, u.name, u.username, u.email, u.block, registerDate, lastvisitDate, a.userid, a.referraluser, a.published "
                . " FROM `#__alpha_userpoints_details` AS d INNER JOIN `#__alpha_userpoints_rules` as r ON d.rule_id = r.plugin_function "
                . " INNER JOIN `#__alpha_userpoints` AS a ON a.referreid = d.referreid "
                . " INNER JOIN `#__users` AS u ON u.id =  a.userid";
        $this->db->setQuery($view2);
        $this->db->execute();
        $dedupe = "DELETE t1 FROM `#__alpha_userpoints_rules` AS t1 INNER JOIN `#__alpha_userpoints_rules` t2 WHERE t1.id < t2.id AND t1.plugin_function = t2.plugin_function";
        $this->db->setQuery($dedupe);
        $this->db->execute();
        $prefix = Factory::getConfig()['dbprefix'];
        $indexrules1 = "SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS WHERE table_name='{$prefix}alpha_userpoints_rules' AND INDEX_NAME = 'unique_alpha_rule_id';";
        $this->db->setQuery($indexrules1);
        if (!$this->db->loadResult()) {
            $indexrules2 = "CREATE UNIQUE INDEX unique_alpha_rule_id ON `#__alpha_userpoints_rules` (plugin_function)";
            $this->db->setQuery($indexrules2);
            $this->db->execute();
        }
        $linksql = "UPDATE `#__alpha_userpoints_details` AS d INNER JOIN `#__alpha_userpoints_rules` AS r ON r.id = d.rule SET d.rule_id = r.plugin_function";
        $this->db->setQuery($linksql);
        $this->db->execute();
        $linksqla = "UPDATE `#__alpha_userpoints_details_archive` AS d INNER JOIN `#__alpha_userpoints_rules` AS r ON r.id = d.rule SET d.rule_id = r.plugin_function";
        $this->db->setQuery($linksqla);
        $this->db->execute();
        $this->addColumn('#__alpha_userpoints_levelrank', 'rule_id', "varchar(50) NOT NULL DEFAULT ''", 'rank');
        $this->db->setQuery("UPDATE #__alpha_userpoints_levelrank AS l INNER JOIN #__alpha_userpoints_rules AS r "
                . " ON l.ruleid = r.id SET l.rule_id = r.plugin_function, l.ruleid = 0 WHERE l.ruleid != 0");
        $this->db->execute();

        if ('install' != $type AND 'update' != $type) {
            return;
        }
        // $componentXML = Installer::parseXMLInstallFile(Path::clean(JPATH_ADMINISTRATOR . '/components/com_userpoints/manifest.xml'));
        // $componentXML['version']
        $newinstall = $this->handleParams();

        $version = simplexml_load_file(JPATH_ADMINISTRATOR . '/components/com_userpoints/' . 'userpoints.xml')->version;
        $logolink = Uri::base() . 'components/com_userpoints/assets/images/up_logo.png';
        echo <<<INSTALL_HEADER

    <div class="well">
        <img src="$logolink" alt="Logo" align="left" />
        <h1> UserPoints Installation $version </h1>
        $newinstall

INSTALL_HEADER;

        $this->examplePlugin();
        $this->guestUser();
        $this->insertRules();
        $this->insertLevelRanks();
        $this->installDefaultModules($parent);
        $this->upgradeFields();
        if (!$this->installAllPlugins()) {
            echo Text::_('COM_AUP_PLUGINS_NOT_INSTALLED');
        }
        $this->tidyOldExtensions();
        $this->makeCompatibility();
        echo <<<INSTALL_REPORT

        <p>&nbsp;</p>
        <p>&nbsp;</p>
        <p>{$this->install}</p>
        <p>&nbsp;</p>
        <p><a href="index.php?option=com_userpoints" class="btn btn-primary" style="color:#FFF;">Go to UserPoints</a></p>
        <p>{$this->up_CopySite($version,'left')}</p>
        <p></p>
    </div>

INSTALL_REPORT;
    }

    private function handleParams() {
        if (!$this->paramsPresent()) {
            $instruction = Text::_('COM_AUP_ALERT_CONFIGURATION');
            $baselink = URI::root(true) . '/administrator/index.php';
            $synclink = URI::root() . 'administrator/index.php?option=com_userpoints&task=usersync';
            $configlink = $baselink . '?option=com_config&view=component&component=com_userpoints&path=&return='
                    . base64_encode($synclink);
            $clicknow = Text::_('COM_AUP_CLICK_TO_CONFIGURE');
            return <<<NEW_INSTALL

        <h4>$instruction</h4>
        <p><a href="$configlink" class="btn btn-primary" style="color:#FFF;">$clicknow </a></p>

NEW_INSTALL;
        } else {
            return '';
        }
    }

    private function paramsPresent() {
        $this->db->setQuery("SELECT `element`,`params` FROM #__extensions WHERE `element` LIKE '%userpoints' AND `type`='component'");
        $results = $this->db->loadObjectList();
        foreach ((array) $results as $result) {
            $elements[$result->element] = $result->params;
        }
        if (isset($elements)) {
            if (isset($elements['com_userpoints']) AND '{}' != $elements['com_userpoints']) {
                return true;
            }
            if (isset($elements['com_betauserpoints']) AND '{}' != $elements['com_betauserpoints']) {
                $this->setPointsParams($elements['com_betauserpoints']);
                return true;
            }
            if (isset($elements['com_altauserpoints']) AND '{}' != $elements['com_altauserpoints']) {
                $this->setPointsParams($elements['com_altauserpoints']);
                return true;
            }
        }
        return false;
    }

    private function setPointsParams($params) {
        $this->db->setQuery("UPDATE #__extensions SET `params` = '$params' WHERE element = 'com_userpoints'");
        $this->db->execute();
    }

    private function tidyOldExtensions() {
        $query = "SELECT `extension_id`, `type` FROM `#__extensions` "
                . "WHERE (`name` LIKE '%betauserpoints%' OR `name` LIKE '%altauserpoints%') ";
        $this->db->setQuery($query);
        $idups = $this->db->loadObjectList();
        foreach ((array) $idups as $idup) {
            $this->installer->uninstall($idup->type, $idup->extension_id);
        }
        $this->removeFiles();
    }

    private function makeCompatibility() {
        foreach (['altauserpoints', 'alphauserpoints'] as $compatapp) {
            $compatdir = JPATH_SITE . '/components/com_' . $compatapp;
            @mkdir($compatdir, 0777 & ~umask(), true);
            copy(JPATH_SITE . '/components/com_userpoints/assets/compatibility/helper.php', $compatdir . '/helper.php');
        }
    }

    /**
     * method to install the component
     *
     * @return void
     */
    public function install($parent) {
        // $parent is the class calling this method
    }

    /**
     * method to uninstall the component
     *
     * @return void
     */
    public function uninstall($parent) {
        // $parent is the class calling this method
        $query = "SELECT `extension_id`, `type` FROM `#__extensions` WHERE (`name` LIKE '%userpoints%' OR `name` = 'system-up_namespace')"
                . " AND `type` != 'component'";
        $this->db->setQuery($query);
        $idups = $this->db->loadObjectList();
        foreach ((array) $idups as $idup) {
            $this->installer->uninstall($idup->type, $idup->extension_id);
        }
    }

    /**
     * method to update the component
     *
     * @return void
     */
    public function update($parent) {
        // $parent is the class calling this method

        $this->install($parent);
    }

    /**
     * method to run before an install/update/uninstall method
     *
     * @return void
     */
    public function preflight($type, $parent) {
        // $parent is the class calling this method
        // $type is the type of change (install, update or discover_install)
        if ('uninstall' == $type) {
            return;
        }
        $sql = "UPDATE `#__modules` SET title = REPLACE(`title`,'AltaUser','User'), "
                . "`module` = REPLACE(`module`,'altauser','user') "
                . "WHERE `module` LIKE '%altauser%'";
        $this->db->setQuery($sql);
        $this->db->execute();
        $sql = "DELETE FROM `#__extensions` WHERE element LIKE '%alta%' AND type = 'module'";
        $this->db->setQuery($sql);
        $this->db->execute();
        $sql = "DELETE FROM #__extensions WHERE element IN ('altauserpointsicon', 'altauserpoints', 'sysplgup_newregistered', "
                . "'sysplgup_raffle', 'sysplgup_reader2author', 'sysplgup_content', 'plg_editors-xtd_raffle', 'notification_rank_medal')";
        $this->db->setQuery($sql);
        $this->db->execute();
        $search = '/' . preg_quote($this->db->getPrefix(), '/') . '/';
        $tables = preg_replace($search, '#__', $this->db->setQuery('SHOW TABLES')->loadColumn(), 1);
        $this->fixDateDefaults($tables);
        PluginHelper::importPlugin('extension');
        $this->app->triggerEvent('onRegisterComponent', [
            'com_userpoints',
            OptionChange::class,
            'handleOptionsChange',
            true
        ]);
        $this->app->triggerEvent('onRegisterComponentNamespace', [
            'com_userpoints',
            Site::class,
            JPATH_SITE . '/components/com_userpoints/src'
        ]);
    }

    private function addColumn($tablename, $column, $columnspec, $after = '') {
        if (!in_array($column, $this->GetFieldNames($tablename))) {
            $sql = "ALTER TABLE `$tablename` ADD `$column` $columnspec";
            if ($after) {
                $sql .= " AFTER `$after`";
            }
            $this->db->setQuery($sql);
            $this->db->execute();
        }
    }

    private function dropColumn($tablename, $column) {
        if (in_array($column, $this->GetFieldNames($tablename))) {
            echo "ALTER TABLE `$tablename` DROP COLUMN `$column`";
            $this->db->setQuery("ALTER TABLE `$tablename` DROP COLUMN `$column`");
            $this->db->execute();
        }
    }

    private function GetFieldNames($tablename) {
        if (!isset($this->fieldnames[$tablename])) {
            $this->db->setQuery("SHOW COLUMNS FROM `$tablename`");
            $fields = $this->db->loadObjectList();
            foreach ($fields as $field) {
                $names[] = $field->Field;
            }
            $this->fieldnames[$tablename] = isset($names) ? $names : [];
        }
        return $this->fieldnames[$tablename];
    }

    private function fixDateDefaults($tables) {
        $dates = [
            '`#__alpha_userpoints`' => ['`leveldate`'],
            '`#__alpha_userpoints_medals`' => ['`medaldate`']
        ];
        $datetimes = [
            '`#__alpha_userpoints`' => ['`last_update`'],
            '`#__alpha_userpoints_details`' => ['`insert_date`', '`expire_date`'],
            '`#__alpha_userpoints_details_archive`' => ['`insert_date`', '`expire_date`'],
            '`#__alpha_userpoints_rules`' => ['`rule_expire`'],
            '`#__alpha_userpoints_coupons`' => ['`expires`'],
            '`#__alpha_userpoints_qrcodetrack`' => ['`trackdate`'],
            '`#__alpha_userpoints_raffle`' => ['`raffledate`'],
            '`#__alpha_userpoints_raffle_inscriptions`' => ['`inscription`']
        ];
        $this->processOneDateSet($dates, 'date', '1000-01-01', $tables);
        $this->processOneDateSet($datetimes, 'datetime', '1000-01-01 00:00:00', $tables);
    }

    private function processOneDateSet($set, $type, $default, $tables) {
        foreach ($set as $table => $fields) {
            if (in_array($table, $tables)) {
                foreach ($fields as $field) {
                    $alters[] = "MODIFY $field $type NOT NULL DEFAULT '$default'";
                    $sql = "UPDATE $table SET $field = '$default' WHERE $field LIKE '0000-00-00%'";
                    $this->db->setQuery($sql);
                    $this->db->execute();
                }
                $sql = "ALTER TABLE $table" . implode(', ', $alters);
                $this->db->setQuery($sql);
                $this->db->execute();
                unset($alters);
            }
        }
    }

    private function examplePlugin() {
        // copy example of Joomla plugin for UserPoints
        $pathPluginsAUP = JPATH_SITE . '/plugins/userpoints';
        if (!is_dir($pathPluginsAUP)) {
            Folder::create($pathPluginsAUP);
        }
        $src = JPATH_ADMINISTRATOR . '/components/com_userpoints/install/plugins/example';
        $dest = $pathPluginsAUP . '/example';
        Folder::copy($src, $dest, '', true);
    }

    private function installAllPlugins() {
        $this->installPlugin('extension-up_options', 'up_options', 'system <b>Options</b> Plugin ');
        $this->installPlugin('content-up_content', 'up_content', 'system <b>Content</b> Plugin ');
        $this->installPlugin('content-up_raffle', 'up_raffle', 'Raffle <b>Content</b> Plugin ');
        $this->installPlugin('content-up_reader2author', 'up_reader2author', 'Reader to Author <b>Content</b> Plugin ');
        $this->installPlugin('editors-xtd-raffle', 'raffle', 'Raffle Editor Button <b>Editor</b> Plugin ');
        $this->installPlugin('notification_rank_medal', 'notification_rank_medal', '<b>Notification on update rank and medal</b> Plugin ');
        $this->installPlugin('user-up_newregistered', 'up_newregistered', 'Registering <b>User</b> Plugin ');
        $this->installPlugin('userpoints', 'userpoints', '<b>System</b> Plugin ');
        $this->installPlugin('userpointsicon', 'userpointsicon', 'Quick Icon <b>Button</b> Plugin');
        $this->installPlugin('up_login', 'up_login', 'On login <b>User</b> Plugin');
        if (Version::MAJOR_VERSION < 4) {
            $this->installPlugin('up_namespace', 'up_namespace', 'Set namespace in Joomla for UserPoints');
        }

        if (count($this->elements)) {
            $elementlist = implode("','", $this->elements);
            $this->db->setQuery("UPDATE #__extensions SET enabled = 1 WHERE `element` IN ('$elementlist') AND `type` = 'plugin'");
            $this->db->execute();
        }
        return (0 == $this->error);
    }

    private function guestUser() {
        // This GUEST user is used by AUP system, don't remove!
        $query = "INSERT INTO #__alpha_userpoints (`userid`, `referreid`,
		`last_update`, `referraluser`, `referrees`, `blocked`, `levelrank`)
		VALUES (0, 'GUEST', '1000-01-01 00:00:00', '', 0, 0, 0)
                ON DUPLICATE KEY UPDATE `userid` = 0;";
        $this->db->setQuery($query);
        $this->db->execute();
    }

    private function insertRules() {
        $sqlr = "UPDATE `#__alpha_userpoints_rules` SET `plugin_function` = REPLACE(`plugin_function`,'sysplgbup', 'sysplgup')";
        $this->db->setQuery($sqlr);
        $this->db->execute();
        $query = "UPDATE `#__alpha_userpoints_rules` SET `plugin_function` = REPLACE(`plugin_function`, 'sysplgaup', 'sysplgup')";
        $this->db->setQuery($query);
        $this->db->execute();
        // Insert default rules on fresh install
        $queryr = "INSERT INTO `#__alpha_userpoints_rules` (`rule_name`, `rule_description`, `rule_plugin`, `plugin_function`, `access`, `component`, `calltask`, `taskid`, `points`, `points2`, `percentage`, `rule_expire`, `sections`, `categories`, `content_items`, `exclude_items`, `published`, `system`, `duplicate`, `blockcopy`, `autoapproved`, `fixedpoints`, `category`, `displaymsg`, `msg`, `method`, `notification`, `emailsubject`, `emailbody`, `emailformat`, `bcc2admin`, `type_expire_date`, `chain`, `linkup`, `displayactivity`) VALUES
                ('AUP_COMBINED_ACTIVITIES', 'AUP_COMBINE_ACTIVITIES_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_archive', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 1, 1, 0, 1, 1, 0, 'sy', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_CHANGE_LEVEL_3', 'AUP_CHANGE_LEVEL_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_changelevel3', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '1', '', 0, 1, 0, 1, 1, 1, 'us', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_CHANGE_LEVEL_2', 'AUP_CHANGE_LEVEL_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_changelevel2', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '1', '', 0, 1, 0, 1, 1, 1, 'us', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_CHANGE_LEVEL_1', 'AUP_CHANGE_LEVEL_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_changelevel1', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '1', '', 0, 1, 0, 1, 1, 1, 'us', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_PROFILE_VIEW', 'AUP_PROFILE_VIEW_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_profile_view', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 'co', 1, '', 1, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_CUSTOM', 'AUP_CUSTOM_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_custom', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 0, 1, 0, 'ot', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_RAFFLE', 'AUP_RAFFLE_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_raffle', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 0, 'ot', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_COUPON_POINTS_CODES', 'AUP_COUPON_POINTS_CODES_DESCRIPTION', 'AUP_SYSTEM', 'sysplgup_couponpointscodes', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 0, 'cd', 1, '', 1, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_WINNERNOTIFICATION', 'AUP_WINNERNOTIFICATIONDESCRIPTION', 'AUP_SYSTEM', 'sysplgup_winnernotification', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 0, 'sy', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_BONUSPOINTS', 'AUP_BONUSPOINTSDESCRIPTION', 'AUP_SYSTEM', 'sysplgup_bonuspoints', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 1, 0, 1, 1, 'ot', 0, '', 4, 0, '', '', 0, 0, 0, 1, 0, 1),
                ('AUP_REFERRALPOINTS', 'AUP_REFERRALPOINTSDESCRIPTION', 'AUP_SYSTEM', 'sysplgup_referralpoints', 1, '', '', '', 0.00, 0.00, 1, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 'co', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_READTOAUTHOR', 'AUP_READTOAUTHORDESCRIPTION', 'AUP_SYSTEM', 'sysplgup_reader2author', 0, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 'ar', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_INVITESUCCES', 'AUP_INVITE_A_USERSUCCESS', 'AUP_SYSTEM', 'sysplgup_invitewithsuccess', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 're', 0, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_INVITE', 'AUP_INVITE_A_USER', 'AUP_SYSTEM', 'sysplgup_invite', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 're', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_LOGIN', 'AUP_LOGIN_DESCRIPTION', 'AUP_SYSTEM', 'up_login', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 'us', 0, '', 2, 0, '', '', 0, 0, 0, 0, 0, 1),
                ('COM_AUP_PURCHASE_POINTS', 'COM_AUP_PURCHASE_POINTS', '', 'sysplgup_buypoints', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 1, 0, 1, 1, 1, 'us', 1, '', 0, 1, '', '', 0, 0, 0, 0, 0, 1),
                ('AUP_NEWUSER', 'AUP_NEWUSERDESCRIPTION', 'AUP_SYSTEM', 'sysplgup_newregistered', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 1, 1, 0, 1, 1, 1, 'us', 0, '', 1, 0, '', '', 0, 0, 0, 0, 0, 1)
                ON DUPLICATE KEY UPDATE rule_name = rule_name;

            ";

        /* Removed Kunena rules - not currently supported by Kunena
         *
          ('AUP_KU_NEW_TOPIC', 'AUP_KU_NEW_TOPIC_DESCRIPTION', 'AUP_KUNENA_FORUM', 'plgup_kunena_topic_create', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 0, 0, 0, 1, 1, 'fo', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
          ('AUP_KU_REPLY_TOPIC', 'AUP_KU_REPLY_DESCRIPTION', 'AUP_KUNENA_FORUM', 'plgup_kunena_topic_reply', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 0, 0, 0, 1, 1, 'fo', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
          ('AUP_KU_THANKYOU', 'AUP_KU_THANKYOU_DESCRIPTION', 'AUP_KUNENA_FORUM', 'plgup_kunena_message_thankyou', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 0, 0, 0, 1, 1, 'fo', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1),
          ('AUP_KU_DELETE_POST', 'AUP_KU_DELETE_POST_DESCRIPTION', 'AUP_KUNENA_FORUM', 'plgup_kunena_message_delete', 1, '', '', '', 0.00, 0.00, 0, '1000-01-01 00:00:00', '', '', '', '', 0, 0, 0, 0, 1, 1, 'fo', 1, '', 4, 0, '', '', 0, 0, 0, 0, 0, 1);
         */

        $this->db->setQuery($queryr);
        if ($this->db->execute()) {
            // default
            $this->install .= '<img src="components/com_userpoints/assets/images/icon-16-allow.png"
							alt="" align="absmiddle" /> 16 default rules installed<br/>';
            // Kunena
            // $this->install .= '<img src="components/com_userpoints/assets/images/icon-16-allow.png"
            //					alt="" align="absmiddle" /> 4 default rules for Kunena installed<br/>';
        }
    }

    private function insertLevelRanks() {
        $this->db->setQuery("SELECT COUNT(*) FROM #__alpha_userpoints_levelrank");
        if (!$this->db->loadResult()) {
            // insert sample ranks and medals on fresh install
            $query = "INSERT INTO `#__alpha_userpoints_levelrank` (`rank`, `description`,
						`levelpoints`, `typerank`, `icon`, `image`, `gid`, `category`, `emailbody`) VALUES
								('Gold member', 'Gold member', 10000, 0, 'icon_gold.png', 'gold.png', 0, 0, ''),
								('Silver member', 'Silver member', 6000, 0, 'icon_silver.png', 'silver.png', 0, 0, ''),
								('Bronze member', 'Bronze member', 3000, 0, 'icon_bronze.png', 'bronze.png', 0, 0, ''),
								('Honor Medal ', 'Honor Medal for best activities on this site', 1000, 1, 'award_small_gold.png', 'award_big_gold.png', 0, 0, '');";
            $this->db->setQuery($query);
            $this->db->execute();

            $this->install .= '<img src="components/com_userpoints/assets/images/icon-16-allow.png"
						alt="" align="absmiddle" /> Sample ranks/medals installed<br/>';
        }
    }

    private function installDefaultModules($parent) {
        $status = new stdClass;
        $status->modules = array();
        $status->plugins = array();
        $src = $parent->getParent()->getPath('source');
        $manifest = $parent->getParent()->manifest;
        $modules = $manifest->xpath('modules/module');
        foreach ($modules as $module) {
            $name = (string) $module->attributes()->module;
            $client = (string) $module->attributes()->client;
            $modulePublished = (string) $module->attributes()->publish;
            $modulePosition = (string) $module->attributes()->position;
            if (is_null($client)) {
                $client = 'site';
            }
            $path = $src . '/modules/' . $name;
            $this->installer->setOverwrite(true);
            $result = $this->installer->install($path);

            if ($client == 'administrator') {
                //auto publish the admin modules
                $sql = $this->db->getQuery(true)
                        ->update($this->db->qn('#__modules'))
                        ->set($this->db->qn('position') . ' = ' . $this->db->q($modulePosition))
                        ->where($this->db->qn('module') . ' = ' . $this->db->q($name));
                if ($modulePublished) {
                    $sql->set($this->db->qn('published') . ' = ' . $this->db->q('1'));
                }
                $this->db->setQuery($sql);
                $this->db->execute();

                // Link to all pages
                $query = $this->db->getQuery(true);
                $query->select('id')->from($this->db->qn('#__modules'))
                        ->where($this->db->qn('module') . ' = ' . $this->db->q($name));
                $this->db->setQuery($query);
                $moduleid = $this->db->loadResult();

                $query = $this->db->getQuery(true);
                $query->select('*')->from($this->db->qn('#__modules_menu'))
                        ->where($this->db->qn('moduleid') . ' = ' . $this->db->q($moduleid));
                $this->db->setQuery($query);
                $assignments = $this->db->loadObjectList();
                $isAssigned = !empty($assignments);
                if (!$isAssigned) {
                    $o = (object) array(
                                'moduleid' => $moduleid,
                                'menuid' => 0
                    );
                    $this->db->insertObject('#__modules_menu', $o);
                }
            }

            $status->modules[] = array('name' => $name, 'client' => $client, 'result' => $result);
        }

        if (count($status->modules)) {
            foreach ($status->modules as $module) {
                $this->install .= ($module['result']) ? '<img
						src="components/com_userpoints/assets/images/icon-16-allow.png"
						alt="" align="absmiddle" /> Module ' . $module['name'] . ' installed<br/>' : '<img
						src="components/com_userpoints/assets/images/publish_x.png" alt=""
						align="absmiddle" /> Module ' . $module['name'] . ' not installed !!!<br/>';
            }
        }
    }

    private function upgradeFields() {
        // Upgrade field in database on update version
        // -------------------------------------------
        // version 1.9.9
        //test199 = "SELECT `notification` FROM #__alpha_userpoints_levelrank";
        $this->db->setQuery("SHOW COLUMNS FROM #__alpha_userpoints_levelrank LIKE 'notification'");
        //if ( !$this->db->execute() ) {
        if (!$this->db->loadResult()) {
            $queries = array(
                "ALTER TABLE #__alpha_userpoints_levelrank ADD `notification` tinyint(1) NOT NULL DEFAULT '0', ADD `emailsubject` varchar(255) NOT NULL DEFAULT '', ADD `emailbody` text NOT NULL DEFAULT '', ADD `emailformat` tinyint(1) NOT NULL DEFAULT '0', ADD `bcc2admin` tinyint(1) NOT NULL DEFAULT '0';",
                "ALTER TABLE #__alpha_userpoints_raffle_inscriptions ADD `ticket` varchar(30) NOT NULL DEFAULT '', ADD `referredraw` int(11) NOT NULL DEFAULT '0', ADD `inscription` datetime NOT NULL DEFAULT '1000-01-01 00:00:00';",
                "ALTER TABLE #__alpha_userpoints_rules ADD `chain` tinyint(1) NOT NULL DEFAULT '0', ADD `linkup` int(11) NOT NULL DEFAULT '0';",
                "UPDATE #__alpha_userpoints_rules SET `duplicate`='1', `blockcopy`='0', `chain`='1' WHERE `plugin_function`='sysplgup_bonuspoints';"
            );
            foreach ($queries as $query) {
                $this->db->setQuery($query);
                $this->db->execute();
            }
        }

        // version 2.0.2
        //test202 = "SELECT `displayactivity` FROM #__alpha_userpoints_rules";
        $this->db->setQuery("SHOW COLUMNS FROM #__alpha_userpoints_rules LIKE 'displayactivity'");
        //if ( !$this->db->execute() ) {
        if (!$this->db->loadResult()) {
            $q = "ALTER TABLE #__alpha_userpoints_rules ADD `displayactivity` tinyint(1) NOT NULL DEFAULT '1';";
            $this->db->setQuery($q);
            $this->db->execute();
        }

        // version 2.0.4
        //test204 = "SELECT `enabled` FROM #__alpha_userpoints_details";
        $this->db->setQuery("SHOW COLUMNS FROM #__alpha_userpoints_details LIKE 'enabled'");
        if (!$this->db->loadResult()) {
            $q = "ALTER TABLE #__alpha_userpoints_details ADD `enabled` tinyint(1) NOT NULL DEFAULT '1';";
            $this->db->setQuery($q);
            $this->db->execute();
        }
    }

    private function installPlugin($filename, $element, $description) {
        $this->installer->setOverwrite(true);
        if ($this->installer->install(JPATH_ADMINISTRATOR . '/components/com_userpoints/install/plugins/' . $filename)) {
            // Add to list to be published
            $this->elements[] = $element;
            $this->install .= <<<INSTALL_LIST

        <img src="components/com_userpoints/assets/images/icon-16-allow.png" alt="Installed Icon" align="absmiddle" />
            Installing UserPoints $description<br/>

INSTALL_LIST;
        } else {
            $this->install .= <<<INSTALL_LIST_FAIL

        <img src="components/com_userpoints/assets/images/icon-16-allow.png" alt="Installed Icon" align="absmiddle" />
            Failed to install UserPoints $description<br/>

INSTALL_LIST_FAIL;
            $this->error++;
        }
    }

    private function up_CopySite($version, $align = 'center') {
        // Get Copyright for Backend
        $copyStart = 2016;
        $copyNow = date('Y');
        $copySite = ($copyStart == $copyNow) ? $copyStart : "$copyStart - $copyNow";
        $copyright = "&copy; $copySite - Bernard Gilly - Adrien Roussel - Martin Brampton";

        echo <<<FOOTER
    <br />
    <div align="$align">
            <p><strong>UserPoints <a href="https://remository.com" target="_blank">Version $version </a> </strong> $copyright</p>
            <p>
                <a href="https://remository.com" target="_blank">https://remository.com</a>
                | <a href="https://remository.com/support/support-tickets" target="_blank" >Support Tickets</a>
                | <a href="https://docs.black-sheep-research.com/userpoints:developer" target="_blank">API Documentation</a>
            </p>
            <p>
                UserPoints is Free Software released under the <a href="http://www.gnu.org/licenses/gpl-2.0.html" target="_blank">GNU/GPL License</a>
            </p>
    </div>

FOOTER;
    }
}
