<?php

/*
 * Copyright (C) 2018 KAINOTOMO PH LTD <info@kainotomo.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace Joomla\Component\SpStgSrv\Administrator\Model;

defined('_JEXEC') or die;

use Joomla\CMS\MVC\Model\BaseDatabaseModel;
use Joomla\CMS\Component\ComponentHelper;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\Component\SpStgSrv\Administrator\Helper\SpStgSrvHelper;
use Joomla\Component\SpStgSrv\Administrator\Helper\InstallerHelper;
use Joomla\CMS\Log\Log;
use Joomla\CMS\Client\ClientHelper;
use Joomla\Filesystem\File;
use Joomla\Filesystem\Stream;

/**
 * Description of InstallerModel
 *
 * @author KAINOTOMO PH LTD <info@kainotomo.com>
 */
class InstallerModel extends BaseDatabaseModel {

        public $package_name;   //package name for log
        public $version;        //package version for log
        public $execute_result = ''; //result when executing php and sql

        public function getItem($data, $decrypt = TRUE) {
                $item = $data;

                //Authorize
                $params = ComponentHelper::getParams('com_spstgsrv');
                $password = $params->get('password');
                if ($password == SpStgSrvHelper::decrypt($item['sec'], $password, $decrypt)) {
                        $item['result'] = '1';
                } else {
                        $item['message'] = Text::_('COM_SPSTGSRV_FAILED_DECRYPTION');
                        $item['result'] = '0';
                }
                unset($item['sec']);

                //Initialize
                $date = Factory::getDate();
                $item['created'] = $date->toSql();
                $item['ip'] = $this->getIP();

                return $item;
        }

        function install($data, $is_win = false) {
                if ($is_win) {
                        if (!($package = $this->getPackage($data['package_name'], $is_win))) {
                                $message = Text::_('COM_INSTALLER_INSTALL_ERROR');
                                return $message;
                        }
                } else {
                        if (!($package = $this->getPackage($data['package_path'] . $data['package_name'], $is_win))) {
                                $message = Text::sprintf('COM_SPSTGSRV_INSTALL_INVALID_URL', $data['package_path'] . $data['package_name']);
                                return $message;
                        }
                }

                // Get an installer instance
                $installer = new InstallerHelper();

                // Install the package
                if (!$installer->install($package['dir'])) {
                        // There was an error installing the package
                        //$message = Text::sprintf('COM_INSTALLER_INSTALL_ERROR', Text::_('COM_INSTALLER_TYPE_TYPE_' . strtoupper($package['type'])));
                        $message = $installer->get('inst_msg');
                        return $message;
                }
                $this->package_name = (string) $installer->manifest->name;
                $this->version = (string) $installer->manifest->version;

                // Cleanup the install files
                if (!is_file($package['packagefile'])) {
                        $config = Factory::getConfig();
                        $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile'];
                }

                \Joomla\CMS\Installer\InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']);

                return 'success';
        }

        public function update($data) {

                $uid = $data['extension_id'];

                //jce updates
                if (strpos($uid, 'jce_') === 0) {
                        return Text::_('COM_SPSTGSRV_FAILED_TO_UPDATE');
                        //return $this->update_jce($uid); //paniko need to update jce
                }

                $update = new \JUpdate();
                $instance = new \Joomla\CMS\Table\Update($this->getDbo());
                $instance->load(Array('extension_id' => $uid));
                $this->package_name = $instance->name; //for log
                $this->version = (string) $instance->version;
                $update_id = $instance->update_id;
                $downloadurl_pro = $this->nonumber($instance->detailsurl);
                if (is_string($downloadurl_pro)) {
                        $update->downloadurl->_data = $downloadurl_pro;
                } else {
                        if (!$update->loadFromXML($instance->detailsurl)) {
                                $message = Text::_('COM_SPSTGSRV_FAILED_TO_READ_XML');
                                return $message;
                        }
                }
                $update->set('extra_query', $instance->extra_query);

                // install sets state and enqueues messages
                $result = $this->installUpdate($update, $uid);

                if ($result === 'success') {
                        $instance->delete($update_id);
                        //$this->purge();
                }

                if ($result === 'success') {
                        return 'success';
                } else {
                        return Text::_('COM_SPSTGSRV_FAILED_TO_UPDATE') . ' ' . $result;
                }
        }

        /**
         * Applies FTP credentials to Joomla! itself, when required
         *
         * @return  void
         *
         * @since	2.5.4
         */
        protected function _applyCredentials() {
                if (!ClientHelper::hasCredentials('ftp')) {
                        $user = Factory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_user', 'ftp_user', null, 'raw');
                        $pass = Factory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_pass', 'ftp_pass', null, 'raw');

                        if ($user != '' && $pass != '') {
                                // Add credentials to the session
                                if (!ClientHelper::setCredentials('ftp', $user, $pass)) {
                                        Factory::getApplication()->enqueueMessage(Text::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED'), 'warning');
                                }
                        }
                }
        }

        /**
         * Applies FTP credentials to Joomla! itself, when required
         *
         * @return  void
         *
         * @since   2.5.4
         */
        protected function _applyCredentialsNew() {
                Factory::getApplication()->getUserStateFromRequest('com_joomlaupdate.method', 'method', 'direct', 'cmd');

                if (!ClientHelper::hasCredentials('ftp')) {
                        $user = Factory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_user', 'ftp_user', null, 'raw');
                        $pass = Factory::getApplication()->getUserStateFromRequest('com_joomlaupdate.ftp_pass', 'ftp_pass', null, 'raw');

                        if ($user != '' && $pass != '') {
                                // Add credentials to the session
                                if (!ClientHelper::setCredentials('ftp', $user, $pass)) {
                                        Factory::getApplication()->enqueueMessage(Text::_('JLIB_CLIENT_ERROR_HELPER_SETCREDENTIALSFROMREQUEST_FAILED'), 'warning');
                                }
                        }
                }
        }

        /**
         * Performs the download of the update package
         *
         * @return  void
         *
         * @since   2.5.4
         */
        public function downloadJoomla() {
                $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}';
                $options['text_file'] = 'joomla_update.php';

                $this->_applyCredentials();

                $model = new \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel();
                $file = $model->download();

                return $file;
        }

        public function downloadJoomlaNew() {
                $options['format'] = '{DATE}\t{TIME}\t{LEVEL}\t{CODE}\t{MESSAGE}';
                $options['text_file'] = 'joomla_update.php';
                
                Log::addLogger($options, Log::INFO, array('Update', 'databasequery', 'jerror'));
                $user = Factory::getUser();
                Log::add(Text::sprintf('COM_JOOMLAUPDATE_UPDATE_LOG_START', $user->id, $user->name, JVERSION), Log::INFO, 'Update');

                $this->_applyCredentialsNew();

                /** @var JoomlaupdateModelDefault $model */
                $model = new \Joomla\Component\Joomlaupdate\Administrator\Model\UpdateModel();
                $file = $model->download();

                return $file;
        }

        /**
         * Handles the actual update installation.
         *
         * @param	JUpdate	An update definition
         * @return	boolean	Result of install
         */
        private function installUpdate($update, $uid) {

                if ($uid != '700') {
                        if (isset($update->get('downloadurl')->_data)) {
                                $url = $update->downloadurl->_data;
                                if ($extra_query = $update->get('extra_query')) {
                                        $url .= (strpos($url, '?') === false) ? '?' : '&amp;';
                                        $url .= $extra_query;
                                }
                        } else {
                                return Text::_('COM_INSTALLER_INVALID_EXTENSION_UPDATE');
                        }
                        
                        $p_file = \Joomla\CMS\Installer\InstallerHelper::downloadPackage($url);
                } else {
                        $p_file = $this->downloadJoomla();
                }

                // Was the package downloaded?
                if (!$p_file) {
                        return Text::sprintf('COM_INSTALLER_PACKAGE_DOWNLOAD_FAILED', $url);
                }

                $config = Factory::getConfig();
                $tmp_dest = $config->get('tmp_path');

                // Unpack the downloaded package file
                $package = \Joomla\CMS\Installer\InstallerHelper::unpack($tmp_dest . '/' . $p_file);

                // Get an installer instance
                // Get an installer instance        
                $installer = new InstallerHelper();
                $update->set('type', $package['type']);

                // Install the package
                if (!$installer->update($package['dir'])) {
                        // There was an error updating the package
                        //$msg = Text::sprintf('COM_INSTALLER_MSG_UPDATE_ERROR', Text::_('COM_INSTALLER_TYPE_TYPE_'.strtoupper($package['type'])));
                        $msg = $installer->get('inst_msg');
                        return $msg;
                } else {
                        // Package updated successfully
                        //$msg = Text::sprintf('COM_INSTALLER_MSG_UPDATE_SUCCESS', Text::_('COM_INSTALLER_TYPE_TYPE_'.strtoupper($package['type'])));
                        $result = 'success';
                }

                // Quick change
                $this->type = $package['type'];

                // Cleanup the install files
                if (!is_file($package['packagefile'])) {
                        $config = Factory::getConfig();
                        $package['packagefile'] = $config->get('tmp_path') . '/' . $package['packagefile'];
                }

                \Joomla\CMS\Installer\InstallerHelper::cleanupInstall($package['packagefile'], $package['extractdir']);

                return $result;
        }

        protected function getPackage($url, $is_win = false) {
                if ($is_win) {
                        $p_file = $url;
                } else {
                        // Download the package at the URL given
                        $p_file = \Joomla\CMS\Installer\InstallerHelper::downloadPackage($url);

                        // Was the package downloaded?
                        if (!$p_file) {
                                return false;
                        }
                }

                $config = Factory::getConfig();
                $tmp_dest = $config->get('tmp_path');

                // Unpack the downloaded package file
                $package = \Joomla\CMS\Installer\InstallerHelper::unpack($tmp_dest . '/' . $p_file);
                return $package;
        }

        function authorizeSEC($sec) {

                //check IP
                $params = ComponentHelper::getParams('com_spstgsrv');

                //check encryption
                $password = $params->get('password');
                if (SpStgSrvHelper::decrypt($password, $password)) {
                        return false;
                }

                return true;
        }

        function getIP() {
                if (!empty($_SERVER["HTTP_CLIENT_IP"])) {
                        //check for ip from share internet
                        $ip = $_SERVER["HTTP_CLIENT_IP"];
                } elseif (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
                        // Check for the Proxy User
                        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
                } else {
                        $ip = $_SERVER["REMOTE_ADDR"];
                }

                if ($ip == "::1")
                        $ip = "127.0.0.1";

                return $ip;
        }

        function save($item) {
                $table = $this->getTable('Log');
                $item['created'] = \Joomla\CMS\Date\Date::getInstance('now')->toSql();
                $table->bind($item);
                $table->store();
        }

        public function getPackages($filter = null) {
                $search = $filter['search'];
                $enabled = $filter['enabled'];
                $type = $filter['type'];
                $client = $filter['client'];
                $group = $filter['group'];
                $hideprotected = $filter['hideprotected'];
                $limit = (int) $filter['sp_limit'];
                $start = (int) $filter['start'];

                $db = Factory::getDBO();
                $query = $db->getQuery(true);
                $query->select('*');
                $query->from('#__extensions');
                $query->where('state=0');
                if ($hideprotected) {
                        $query->where('protected!=1');
                }
                if ($enabled != '') {
                        $query->where('enabled=' . intval($enabled));
                }
                if ($type) {
                        $query->where('type=' . $this->_db->Quote($type));
                }
                if ($client != '') {
                        $query->where('client_id=' . intval($client));
                }
                if ($group != '' && in_array($type, array('plugin', 'library', ''))) {

                        $query->where('folder=' . $this->_db->Quote($group == '*' ? '' : $group));
                }

                // Filter by search in title.
                if (!empty($search)) {
                        if (stripos($search, 'id:') === 0) {
                                $query->where('extension_id = ' . (int) substr($search, 3));
                        } else {
                                $search = $db->Quote('%' . $db->escape($search, true) . '%');
                                $query->where('(name LIKE ' . $search . ' OR element LIKE ' . $search . ')');
                        }
                }

                $db->setQuery($query, $start, $limit);
                try {
                        $db->execute();
                } catch (\RuntimeException $exc) {
                        return $exc->getMessage();
                }

                $items = $db->loadAssocList('extension_id');
                if (empty($items)) {
                        return Text::_('COM_SPSTGSRV_READ_EMPTY');
                }

                //Get name and updates
                $lang = Factory::getLanguage();
                foreach ($items as $key => $item) {
                        if (!$lang->load($item['element'], JPATH_ADMINISTRATOR)) {
                                if (!$lang->load($item['element'], JPATH_SITE)) {
                                        $lang->load('plg_' . $item['folder'] . '_' . $item['element'], JPATH_ADMINISTRATOR);
                                }
                        }
                        $items[$key]['name'] = Text::_($item['name']);
                        $manifest_cache = json_decode($items[$key]['manifest_cache']);
                        $manifest_cache->name = Text::_($manifest_cache->name);
                        $manifest_cache->description = Text::_($manifest_cache->description);
                        $manifest_cache->description = '';
                        $items[$key]['manifest_cache'] = json_encode($manifest_cache);
                        $items[$key]['params'] = '';
                }

                return $items;
        }

        public function count($filter = null) {
                $search = $filter['search'];
                $enabled = $filter['enabled'];
                $type = $filter['type'];
                $client = $filter['client'];
                $group = $filter['group'];
                $hideprotected = $filter['hideprotected'];

                $db = Factory::getDBO();
                $query = $db->getQuery(true);
                $query->select('COUNT(*)');
                $query->from('#__extensions');
                $query->where('state=0');
                if ($hideprotected) {
                        $query->where('protected!=1');
                }
                if ($enabled != '') {
                        $query->where('enabled=' . intval($enabled));
                }
                if ($type) {
                        $query->where('type=' . $this->_db->Quote($type));
                }
                if ($client != '') {
                        $query->where('client_id=' . intval($client));
                }
                if ($group != '' && in_array($type, array('plugin', 'library', ''))) {

                        $query->where('folder=' . $this->_db->Quote($group == '*' ? '' : $group));
                }

                // Filter by search in title.
                if (!empty($search)) {
                        if (stripos($search, 'id:') === 0) {
                                $query->where('extension_id = ' . (int) substr($search, 3));
                        } else {
                                $search = $db->Quote('%' . $db->escape($search, true) . '%');
                                $query->where('(name LIKE ' . $search . ' OR element LIKE ' . $search . ')');
                        }
                }

                $db->setQuery($query);
                if (!$db->query()) {
                        $items['result'] = '0';
                        $items['message'] = $db->getErrorMsg();
                        return $items;
                }

                $count = $db->loadResult();

                if (empty($count)) {
                        $items['message'] = Text::_('COM_SPSTGSRV_READ_EMPTY');
                        $items['result'] = '0';
                        return $items;
                }

                $items['count'] = $count;
                $items['message'] = 'success';
                $items['result'] = '1';
                return $items;
        }

        function publish($data) {
                // Get a database connector
                $db = Factory::getDBO();

                // Get a table object for the extension type
                $table = JTable::getInstance('Extension');
                JTable::addIncludePath(JPATH_ADMINISTRATOR . '/components/com_templates/tables');
                // Enable the extension in the table and store it in the database
                $table->load($data['package_id']);
                if ($table->type == 'template') {
                        $style = JTable::getInstance('Style', 'TemplatesTable');
                        if ($style->load(array('template' => $table->element, 'client_id' => $table->client_id, 'home' => 1))) {
                                $message = Text::_('COM_SPSTGSRV_ERROR_DISABLE_DEFAULT_TEMPLATE_NOT_PERMITTED');
                                return $message;
                        }
                }

                //Return if different element
                if ($table->element != $data['package_element']) {
                        return Text::_('COM_SPSTGSRV_ELEMENT_DIFFERENT');
                }

                $table->enabled = $data['enabled'];
                if (!$table->store()) {
                        $message = $table->getError();
                        $result = $message;
                }

                return 'success';
        }

        function remove($data) {
                // Initialise variables.
                $failed = array();

                // Get an installer object for the extension type
                require_once JPATH_COMPONENT . '/helpers/installer.php';
                $installer = SpStgSrvHelperInstaller::getInstance();
                $row = JTable::getInstance('extension');

                // Uninstall the chosen extensions
                $id = trim($data['package_id']);
                $row->load($id);

                //Return if different element
                if ($row->element != $data['package_element']) {
                        return Text::_('COM_SPSTGSRV_ELEMENT_DIFFERENT');
                }

                if ($row->type) {
                        $result = $installer->uninstall($row->type, $id);

                        // Build an array of extensions that failed to uninstall
                        if ($result === false) {
                                $failed[] = $id;
                        }
                } else {
                        $failed[] = $id;
                }

                if (count($failed)) {

                        // There was an error in uninstalling the package
                        $message = Text::_('COM_SPSTGMNG_UNINSTALL_ERROR');
                        return $message;
                }

                return 'success';
        }

        function sync($data) {
                $id = $data['package_id'];

                // Get an installer object for the extension type
                require_once JPATH_COMPONENT . '/helpers/installer.php';
                $installer = SpStgSrvHelperInstaller::getInstance();
                $row = JTable::getInstance('extension');
                $result = 0;

                // Refresh manifest cache
                $result |= $installer->refreshManifestCache($id);

                $row->load($id);
                $filter['search'] = $row->get('element');
                $filter['enabled'] = '';
                $filter['type'] = '';
                $filter['client'] = '';
                $filter['group'] = '';
                $filter['hideprotected'] = '';
                return $this->getPackages($filter);
        }

        public function find() {
                $result = Array();
                //Purge cache
                if (!$this->purge()) {
                        $result['result'] = 0;
                        $result['message'] = Text::_('COM_SPSTGSRV_FAILED_TO_PURGE_UPDATES');
                        return $result;
                }
                if (!$this->enableSites())
                        return Text::_('COM_SPSTGSRV_FAILED_TO_ENABLE_UPDATES');

                //Find        
                $cache_timeout = 21600;
                $updater = JUpdater::getInstance();
                //if(!$updater->findUpdates(0, $cache_timeout)) return Text::_('COM_SPSTGSRV_FAILED_TO_FIND_UPDATES');
                $updater->findUpdates(0, $cache_timeout);
                $updates = $this->getUpdates();
                if (!$updates)
                        Text::_('COM_SPSTGSRV_FAILED_TO_FIND_UPDATES');
                $updates['result'] = 1;
                return $updates;
        }

        public function purge() {
                $db = Factory::getDBO();
                // Note: TRUNCATE is a DDL operation
                // This may or may not mean depending on your database
                $db->setQuery('TRUNCATE TABLE #__updates');
                if ($db->Query()) {
                        // Reset the last update check timestamp
                        $query = $db->getQuery(true);
                        $query->update('#__update_sites');
                        $query->set('last_check_timestamp = 0');
                        $db->setQuery($query);
                        $db->query();

                        return true;
                } else {
                        return false;
                }
        }

        public function enableSites() {
                $db = Factory::getDBO();
                $db->setQuery('UPDATE #__update_sites SET enabled = 1 WHERE enabled = 0');
                if ($db->Query()) {
                        return true;
                } else {
                        return false;
                }
        }

        protected function getUpdates($pk = null) {
                $db = $this->getDbo();
                $query = $db->getQuery(true);
                $query->select('*')->from('#__updates');
                if (is_null($pk)) {
                        $query->where('extension_id != 0');
                } else {
                        $query->where('extension_id = ' . $pk);
                }

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

        public function backup() {

                $this->backup_db();
                $this->backup_files();

                $items['message'] = 'success';
                $items['result'] = '1';
                return $items;
        }

        public function backup_files() {

                set_time_limit(0);

                $config = Factory::getConfig();
                $backup_dir = JPATH_COMPONENT_ADMINISTRATOR . '/backups/';

                //backup files
                $backup_file = $backup_dir . 'site.tgz';
                $command = 'tar --create \
                    --file=' . $backup_file . ' \
                    --gzip \
                    --exclude-tag=sp_exclude_tag \
                    ./
            ';

                exec($command);
                if (filesize($backup_file) < 1000) {
                        $items['message'] = 'Files backup failed.';
                        $items['result'] = '0';
                        return $items;
                }

                set_time_limit(30);

                $items['message'] = 'success';
                $items['result'] = '1';
                return $items;
        }

        public function backup_db() {

                set_time_limit(0);

                $config = Factory::getConfig();
                $backup_dir = JPATH_COMPONENT_ADMINISTRATOR . '/backups/';

                //backup db
                exec("mysqldump -u " . $config->get('user') . " -p" . $config->get('password') . " " . $config->get('db') . " | gzip > " . $backup_dir . $config->get('db') . '.sql.gz');
                if (filesize($backup_dir . $config->get('db') . '.sql.gz') < 1000) {
                        $items['message'] = 'Database backup failed.';
                        $items['result'] = '0';
                        return $items;
                }

                set_time_limit(30);

                $items['message'] = 'success';
                $items['result'] = '1';
                return $items;
        }

        public function backup_files_incremental($data) {

                set_time_limit(0);

                //backup files

                $backup_dir = JPATH_ROOT;
                $filenames = JFolder::files($backup_dir, '.', true, true);
                $dbo = Factory::getDbo();
                $query = $dbo->getQuery(TRUE);

                $query->clear();
                $query->select('filename, mdate')->from('#__spstgsrv_backups');
                $dbo->setQuery($query);
                $files_db = $dbo->loadAssocList();

                $files_rw = array();
                foreach ($filenames as $filename) {
                        if ($filename == $backup_dir . '/administrator/components/com_spstgsrv/backups/backup.zip')
                                continue;
                        $files_rw[] = array('filename' => $filename, 'mdate' => filemtime($filename));
                }

                $files = array();
                foreach ($files_rw as $values)
                        if (!in_array($values, $files_db))
                                $files[] = $values;

                $handle = opendir($backup_dir);
                if ($handle) {
                        $zip = new ZipArchive();
                        if ($zip->open(JPATH_COMPONENT_ADMINISTRATOR . '/backups/backup.zip', ZIPARCHIVE::CREATE) !== TRUE) {
                                exit("cannot open <$zip_file>\n");
                        }

                        foreach ($files as $file) {
                                $filename = $file['filename'];
                                $mdate = $file['mdate'];

                                if ($filename == $backup_dir . '/administrator/components/com_spstgsrv/backups/backup.zip')
                                        continue;
                                $query->clear();
                                $query->select('mdate')->from('#__spstgsrv_backups')->where('`filename` LIKE ' . $dbo->quote($dbo->escape($filename)));
                                $dbo->setQuery($query);
                                $result = $dbo->loadResult();

                                if (empty($result)) {
                                        //not found then create
                                        $dbo->setQuery(
                                                'INSERT INTO  `#__spstgsrv_backups` (' .
                                                '`id` ,' .
                                                '`filename` ,' .
                                                '`mdate`' .
                                                ')' .
                                                'VALUES (' .
                                                'NULL ,  ' . $dbo->quote($filename) . ', ' . $dbo->quote($dbo->escape($mdate)) .
                                                ')'
                                        );
                                        if (!$dbo->execute()) {
                                                $items['message'] = $dbo->getErrorMsg();
                                                $items['result'] = '0';
                                                return $items;
                                        }
                                        $zip->addFile($filename);
                                } else {
                                        if ($result != $mdate) {
                                                //different modified date
                                                $zip->addFile($filename);
                                                $dbo->setQuery(
                                                        'UPDATE  `#__spstgsrv_backups` ' .
                                                        ' SET `mdate` = ' . $dbo->quote($dbo->escape($mdate)) .
                                                        ' WHERE `filename` LIKE ' . $dbo->quote($dbo->escape($filename))
                                                );
                                                if (!$dbo->execute()) {
                                                        $items['message'] = $dbo->getErrorMsg();
                                                        $items['result'] = '0';
                                                        return $items;
                                                }
                                        }
                                }
                        }

                        closedir($handle);

                        if (!$zip->close()) {
                                CYENDFactory::print_r($zip);
                        }
                }

                //backup db

                set_time_limit(30);

                $items['message'] = 'success';
                $items['result'] = '1';
                return $items;
        }

        /**
         * Login to Joomla as administrator
         *
         * @return boolean true on success false on error
         * 
         * @since 2.1.1
         */
        private function login() {
                //$app = Factory::getApplication();
                $app = Factory::getApplication('administrator');

                $db = & Factory::getDBO();
                $query = 'SELECT `user_id`'
                        . ' FROM `#__user_usergroup_map`'
                        . ' WHERE group_id = 8';
                $db->setQuery($query);
                $user_id = $db->loadResult();

                $query = 'SELECT `username`'
                        . ' FROM `#__users`'
                        . ' WHERE id = ' . (int) $user_id;
                $db->setQuery($query);
                $username = $db->loadResult();

                JPluginHelper::importPlugin('user');

                $options = array();
                //$options['action'] = 'core.login.site';
                $options['action'] = 'core.login.admin';

                $response = new stdClass();
                $response->username = $username;
                $app->triggerEvent('onUserLogin', array((array) $response, $options));
        }

        /**
         * Check if nonumber extension and install it
         * 
         * @param string $detailsurl
         * @return boolean
         */
        private function nonumber($detailsurl) {

                //Check if nonumber
                if (strpos($detailsurl, 'nonumber.nl') === false) {
                        return false;
                }

                //Convert url parameters to array
                $ext_pos = strpos($detailsurl, '?') + 1;
                $vars_str = substr($detailsurl, $ext_pos);
                $vars_arr_1 = explode('&', $vars_str);
                $vars_arr = array();
                foreach ($vars_arr_1 as $value) {
                        $tmp_arr = explode('=', $value);
                        $vars_arr[$tmp_arr[0]] = $tmp_arr[1];
                }
                $id = $vars_arr['e'];

                //get download id
                $app = &Factory::getApplication();
                $params = ComponentHelper::getParams('com_nonumbermanager');
                $key_1 = $params->get('key');
                $key = strtolower(substr($key_1, 0, 8) . md5(substr($key_1, 8)));

                //get xml
                $url = 'http://download.nonumber.nl/extensions.php?k=' . $key . '&e=' . $id;
                $jhttp = JHttpFactory::getHttp();
                try {
                        $jhttp_response = $jhttp->get($url);
                } catch (Exception $exc) {
                        $app->enqueueMessage(Text::_($exc->getTraceAsString()), 'error');
                        return false;
                }

                $xml = $jhttp_response->body;
                $xml_array_1 = $array = json_decode(json_encode((array) simplexml_load_string($xml)), 1);
                $xml_array = $xml_array_1['extension'];

                foreach ($xml_array as $key => $value) {
                        if (($key == 'downloadurl_pro') && (!empty($value))) {
                                return $value;
                                /*
                                  include_once JPATH_ADMINISTRATOR . '\components\com_nonumbermanager\models\process.php';
                                  $process = new NoNumberManagerModelProcess();
                                  $result = $process->install($id, $value);
                                  if ($result === true) {
                                  return false;
                                  }
                                 * 
                                 */
                        }
                }

                return true;
        }

        private function update_jce($uid) {
                $result = true;

                //check if component is present
                $file_updates = JPATH_ADMINISTRATOR . '/components/com_jce/models/updates.php';
                if (!File::exists($file_updates)) {
                        return Text::_('COM_SPSTGSRV_FAILED_TO_UPDATE');
                }
                $file_model = JPATH_ADMINISTRATOR . '/components/com_jce/models/model.php';
                $file_helpers = JPATH_ADMINISTRATOR . '/components/com_jce/helpers/updates.php';
                $file_base = JPATH_ADMINISTRATOR . '/components/com_jce/includes/base.php';
                require_once $file_base;
                require_once ($file_updates);
                require_once ($file_model);
                require_once($file_helpers);

                $uid = substr($uid, 4);

                $model_updates = new WFModelUpdates();

                $updates_json = $model_updates->check();
                $updates_arr = json_decode($updates_json);

                foreach ($updates_arr as $value) {
                        if ($value->id == $uid) {

                                $this->package_name = $value->title . ' (' . $value->name . ')';
                                $this->version = $value->version;

                                $input = Factory::getApplication()->input;

                                $input->set('id', $value->id);
                                $download = json_decode($model_updates->download());

                                if (property_exists($download, 'error')) {
                                        $result = FALSE;
                                        break;
                                }

                                $input->set('file', $download->file);
                                //$input->set('hash', $value->hash);
                                Factory::getApplication()->input->set('hash', $download->hash, 'POST');
                                $input->set('installer', $download->installer);
                                $input->set('type', $download->type);

                                $install = json_decode($model_updates->install());
                                if (property_exists($install, 'error')) {
                                        if (!empty($install->error)) {
                                                $result = FALSE;
                                                break;
                                        }
                                }

                                //move folder
                                $source = JPATH_COMPONENT_SITE . '/editor';
                                $destination = JPATH_ROOT . '/components/com_jce/editor';
                                if (!JFolder::copy($source, $destination, '', true, true)) {
                                        $result = false;
                                        break;
                                }
                                JFolder::delete($source);

                                break;
                        }
                }

                if ($result) {
                        return 'success';
                } else {
                        return Text::_('COM_SPSTGSRV_FAILED_TO_UPDATE');
                }
        }

        public function execute_php($data, $is_win = false) {

                if ($is_win) {
                        $p_file = $data['package_name'];
                } else {
                        $url = $data['package_path'] . $data['package_name'];

                        $p_file = \Joomla\CMS\Installer\InstallerHelper::downloadPackage($url);

                        // Was the package downloaded?
                        if (!$p_file) {
                                $message = Text::plural('COM_SPSTGSRV_INSTALL_INVALID_URL', $data['package_path'] . $data['package_name']);
                                return $message;
                        }
                }

                //rename file
                $file_arr = explode('.', $p_file);
                unset($file_arr[count($file_arr) - 1]);
                $file = implode('.', $file_arr);
                $file .= '.php';
                $config = Factory::getConfig();
                $tmp_dir = $config->get('tmp_path') . DIRECTORY_SEPARATOR;
                File::move($tmp_dir . $p_file, $tmp_dir . $file);

                //run file        
                ob_start();
                include $tmp_dir . $file;
                $this->execute_result = ob_get_clean();
                File::delete($tmp_dir . $file);
                return 'success';
        }

        public function execute_sql($data, $is_win = false) {

                if ($is_win) {
                        $p_file = $data['package_name'];
                } else {
                        $this->package_name = $data['package_name'];

                        $url = $data['package_path'] . $data['package_name'];

                        $p_file = \Joomla\CMS\Installer\InstallerHelper::downloadPackage($url);

                        // Was the package downloaded?
                        if (!$p_file) {
                                $message = Text::plural('COM_SPSTGSRV_INSTALL_INVALID_URL', $data['package_path'] . $data['package_name']);
                                return $message;
                        }
                }

                //read file
                $stream = new Stream();
                $config = Factory::getConfig();
                $sql_file = $config->get('tmp_path') . DIRECTORY_SEPARATOR . $p_file;
                $stream->open($sql_file);
                $query = $stream->read();
                $stream->close();

                //execute query
                $db = Factory::getDbo();
                $db->setQuery($query);
                try {
                        $db->execute();
                } catch (Exception $exc) {
                        echo $exc->getMessage();
                        //echo $exc->getTraceAsString();
                        exit();
                }

                File::delete($sql_file);

                return 'success';
        }

}
