<?php
/**
* @package XenCentral Framework
* @author Skydevelop EU
* @copyright Drnoyan & Nalyan LDA, Portugal, EU
* @license http://www.dnf.pt/eula.html
* @link http://www.skydevelop.com
* @version 1.4.1
* @revision 125
*/


class XenCentral_Framework_ControllerAdmin_Framework extends XenForo_ControllerAdmin_Abstract
{
    public function actionTest()
    {
        $message = 'On that day onwards

sd my home

On Sat, Feb 20, 2016 at 11:18 PM, bheanloh <hello@istudy.my>
wrote:

> Gonna test this with admin.
>
> For all my emails.
> Sent from iStudy.my
>
> Regards,
> bheanloh
>
> ------------------
>
> **Reply to this email directly.
> **Do not delete this code to ensure mail delivery: [GQK27869554898 -
> iStudy.my]';

        echo XenCentral_ReplyViaEmail_EmailCron::trimMessageTest($message);
        exit;
    }

    public function actionPaymentList()
    {
        if (!XenForo_Visitor::getInstance()->hasAdminPermission('xcfw_can_manage_payments')) {
            return $this->responseNoPermission();
        }

        $order = 'dateline';
        $direction = 'DESC';

        $paymentModel = $this->_getPaymentApiModel();

        $page = $this->_input->filterSingle('page', XenForo_Input::UINT);
        $paymentsPerPage = 20;
        $showingAll = $this->_input->filterSingle('all', XenForo_Input::UINT);
        if ($showingAll) {
            $page = 1;
            $paymentsPerPage = 5000;
        }

        $fetchOptions = array(
                'perPage' => $paymentsPerPage,
                'page' => $page,

                'order' => $order,
                'direction' => $direction
        );

        $totalPayments = $paymentModel->countPayments();

        if (!$totalPayments) {
            return $this->responseError(new XenForo_Phrase('xcfw_no_payments_to_show'));
        }

        $conditions = array();

        $filter = $this->getInput()->filterSingle('_filter', XenForo_Input::ARRAY_SIMPLE);

        if ($filter && isset($filter['value'])) {
            $conditions['id_match'] = $filter['value'];
            $filterView = true;
        } else {
            $filterView = false;
        }

        $payments = $paymentModel->getPayments($conditions, $fetchOptions);

        $viewParams = array(
                'payments' => $payments,
                'totalPayments' => $totalPayments,
                'showingAll' => false,
                'showAll' => false,

                'linkParams' => array('order' => $order, 'direction' => $direction),
                'page' => $page,
                'paymentsPerPage' => $paymentsPerPage,

                'filterView' => $filterView,
                'filterMore' => false
        );

        return $this->responseView('XenCentral_Framework_ViewAdmin_Payment_List', 'xcfw_payment_list', $viewParams);
    }

    public function actionCopyTableData()
    {
        $table1 = 'xcodt_classifieds';
        $table2 = 'xcodt_classifieds_new';

        $db = XenForo_Application::getDb();
        $data1 = $db->fetchAll('
            SELECT * FROM ' . $table1 . '
        ');

        $fields1 = array_keys($db->describeTable($table1));
        $fields2 = array_keys($db->describeTable($table2));

        /*$columns1 = $columns2 =array();

        foreach($fields1 AS $column) {
            $columns1[]=$column['Field_name'];
        }*/

        foreach ($data1 AS $row) {
            $data2 = array();
            foreach ($row AS $key => $value) {
                if (in_array($key, $fields1) AND in_array($key, $fields2)) {
                    $data2[$key] = $value;
                }
            }
            $db->insert($table2, $data2);
        }
        exit;
    }

    public function actionCompareDbStructure()
    {
        $dbName1 = 'xenforo';
        $dbName2 = 'xenforo_ireview';

        $dbName1 = 'rcpowers_default_xf';
        $dbName2 = 'rcpowers_xenforo';

        /** @var $db1 Zend_Db_Adapter_Abstract */
        /** @var $db2 Zend_Db_Adapter_Abstract */
        list($db1, $db2) = $this->_getDbConnections($dbName1, $dbName2);
        list($tables1, $tables2) = $this->_getDbTables($db1, $db2);

        echo '<p>Tables not found in ' . $dbName2 . ' are: ' . implode(', ', array_diff($tables1, $tables2)) . '</p>';
        echo '<p>Tables not found in ' . $dbName1 . ' are: ' . implode(', ', array_diff($tables2, $tables1)) . '</p>';

        $dropIndexes = array();

        $indexDifferanceArray1 = array();
        $indexDifferanceArray2 = array();

        $recreateTables = array();

        // now compare existing tables
        foreach ($tables1 AS $table) {
            if (!isset($tables2[$table])) {
                continue;
            }

            $table1 = $db1->fetchAll('DESCRIBE ' . $table);
            $table2 = $db2->fetchAll('DESCRIBE ' . $table);

            $table1 = $this->_setKeyInArray('Field', $table1);
            $table2 = $this->_setKeyInArray('Field', $table2);

            $columnDiffernce1 = array_diff(array_keys($table1), array_keys($table2));
            $columnDiffernce2 = array_diff(array_keys($table2), array_keys($table1));

            $columnValueDifferences = array();

            foreach ($table1 AS $columnName => $column) {
                if (!isset($table2[$columnName])) {
                    continue;
                }

                foreach ($column AS $columnKey => $columnInfo) {
                    $columnInfo2 = $table2[$columnName][$columnKey];

                    if ($columnInfo2 != $columnInfo) {
                        $columnValueDifferences[$columnName] = array(
                                $columnKey,
                                $columnInfo,
                                $columnInfo2
                        );
                    }
                }
            }

            $showIndexes1 = $db1->fetchAll('Show indexes from ' . $table);
            $showIndexes2 = $db2->fetchAll('Show indexes from ' . $table);

            $primaryColumnName = false;
            $primaryKeyFound = 0;
            foreach ($showIndexes1 AS $key => $index) {
                if ($index['Key_name'] == 'PRIMARY') {
                    $primaryKeyFound++;
                    $primaryColumnName = $index['Column_name'];
                }

                unset($index['Seq_in_index']);
                unset($index['Cardinality']);
                $showIndexes1[$key] = $index;
            }
            foreach ($showIndexes2 AS $key => $index) {
                unset($index['Seq_in_index']);
                unset($index['Cardinality']);
                $showIndexes2[$key] = $index;

                if ($primaryKeyFound == 1 AND $index['Key_name'] != 'PRIMARY' AND $index['Column_name'] == $primaryColumnName) {
                    // this index can be dropped
                    $dropIndexes[] = array(
                            $table, $index['Key_name']
                    );
                }

            }
            $showIndexes1 = serialize($showIndexes1);
            $showIndexes2 = serialize($showIndexes2);

            if (!empty($columnDiffernce1)
                    OR !empty($columnDiffernce2)
                    OR !empty($columnValueDifferences)
                    OR $showIndexes1 != $showIndexes2
            ) {
                echo '<p>Difference in structure of table <b>' . $table . '</b></p>';
                if ($columnDiffernce1) {
                    echo '<p>Columns not found in ' . $dbName2 . ' are: ' . implode(', ', $columnDiffernce1) . '</p>';
                }
                if ($columnDiffernce2) {
                    echo '<p>Columns not found in ' . $dbName1 . ' are: ' . implode(', ', $columnDiffernce2) . '</p>';
                }

                if (!empty($columnValueDifferences)) {
                    foreach ($columnValueDifferences AS $columnName => $differance) {
                        echo '<p><b>' . $columnName . '=>' . $differance[0] . '</b> ' . $differance[1] . '<b>!=</b>' . $differance[2] . '</p>';
                    }
                }

                if ($showIndexes1 != $showIndexes2) {
                    $recreateTables [] = $table;
                    echo '<p><b>Difference in index definitaion found</b></p>';
                    $indexDifferanceArray1[] = unserialize($showIndexes1);
                    $indexDifferanceArray2[] = unserialize($showIndexes2);
                }
            }
        }
        if ($dropIndexes) {
            echo '<p>The follow SQL query will drop all additional unneeded indexes.</p>';
            echo '<pre>';
            foreach ($dropIndexes AS $index) {
                echo 'ALTER TABLE ' . $index[0] . ' DROP INDEX ' . $index[1] . ';' . "\n";
            }
            echo '</pre>';
        }
        /*echo '<textarea>'.print_r($indexDifferanceArray1, true).'</textarea>';
        echo '<textarea>'.print_r($indexDifferanceArray2, true).'</textarea>';*/
        $sql = array();
        foreach ($recreateTables AS $table) {
            $createSql = $db1->fetchRow('SHOW CREATE TABLE ' . $table);
            $createSql = $createSql['Create Table'];
            $createSql = str_replace('CREATE TABLE `' . $table . '`', 'CREATE TABLE `' . $table . '_new`', $createSql) . ';';
            $insertSQL = 'REPLACE INTO ' . $table . '_new SELECT * FROM ' . $table . ';';
            $renameSQl = 'RENAME TABLE ' . $table . ' TO ' . $table . '_backup;';
            $renameSQl2 = 'RENAME TABLE ' . $table . '_new TO ' . $table . ';';
            $sql[] = $createSql;
            $sql[] = $insertSQL;
            $sql[] = $renameSQl;
            $sql[] = $renameSQl2;
            $sql[] = "\n\n\n";
        }

        echo '<pre>' . implode("\n", $sql) . '</pre>';

        exit;
    }

    protected function _setKeyInArray($key, $array)
    {
        $newArray = array();

        foreach ($array AS $val) {
            $newArray[$val[$key]] = $val;
        }

        return $newArray;
    }

    protected function _getDbTables(Zend_Db_Adapter_Abstract $db1, Zend_Db_Adapter_Abstract $db2)
    {
        $list1 = $db1->fetchAll('SHOW TABLES;');
        $list2 = $db2->fetchAll('SHOW TABLES;');

        $tables1 = array();
        $tables2 = array();

        foreach ($list1 AS $table) {
            $table = array_shift($table);
            $tables1[$table] = $table;
        }
        foreach ($list2 AS $table) {
            $table = array_shift($table);
            $tables2[$table] = $table;
        }

        return array($tables1, $tables2);
    }

    /**
     * @param $dbName1
     * @param $dbName2
     * @return array
     */
    protected function _getDbConnections($dbName1, $dbName2)
    {

        // only use this for imports
        $connect_info = XenForo_Application::getConfig();

        $info1 = new Zend_Config(array(), true);
        $info2 = new Zend_Config(array(), true);

        foreach ($connect_info AS $key => $value) {
            if ($value instanceof Zend_Config) {
                $info1->$key = new Zend_Config(array(), true);
                $info2->$key = new Zend_Config(array(), true);
                foreach ($value AS $key2 => $value2) {
                    $info1->$key->$key2 = $value2;
                    $info2->$key->$key2 = $value2;
                }
            } else {
                $info1->$key = $value;
                $info2->$key = $value;
            }
        }

        $info1->db->dbname = $dbName1;
        $info2->db->dbname = $dbName2;
        $db1 = XenForo_Application::getInstance()->loadDb($info1->db);

        $db2 = XenForo_Application::getInstance()->loadDb($info2->db);

        return array($db1, $db2);
    }

    public function actionGenerateTable()
    {
        $data = array(
                'prefix_id' => XenForo_Input::UINT,
                'node_id' => XenForo_Input::UINT,
                'title' => XenForo_Input::STRING,
                'zip_code' => XenForo_Input::STRING,
                'specific_location' => XenForo_Input::STRING,
                'want_to_ship' => XenForo_Input::BOOLEAN,
                'is_for_sale' => XenForo_Input::BOOLEAN,
                'sale_price' => XenForo_Input::STRING,
                'is_for_trade' => XenForo_Input::BOOLEAN,
                'trade_price' => XenForo_Input::STRING,
                'bill_required' => XenForo_Input::BOOLEAN,
                'bill_information' => XenForo_Input::STRING,
                'caliber' => XenForo_Input::STRING,
                'disable_comments' => XenForo_Input::BOOLEAN
        );

        $fields = array();

        foreach ($data AS $fieldId => $type) {
            switch ($type) {
                case XenForo_Input::UINT:
                    $type = 'INT (11) UNSIGNED NOT NULL DEFAULT 0';
                    break;
                case XenForo_Input::INT:
                    $type = 'INT (11) NOT NULL DEFAULT 0';
                    break;
                case XenForo_Input::BOOLEAN:
                    $type = 'INT (1) UNSIGNED NOT NULL DEFAULT 0';
                    break;
                case XenForo_Input::STRING:
                default:
                    $type = 'VARCHAR(255) NOT NULL DEFAULT \'\'';
                    break;
            }
            $fields[] = "`$fieldId` $type";
        }

        $table = "
            CREATE TABLE IF NOT EXISTS `table_name` (
              `item_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
              " . implode(",\n", $fields) . "
              PRIMARY KEY (`item_id`)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8
        ";

        echo $table;
        exit;
    }

    public function actionGenerateOptionsModel()
    {
        $prefix = $this->_input->filterSingle('prefix', XenForo_Input::STRING);

        if (!$prefix) {
            return $this->responseError('No prefix found.');
        }

        $options = XenForo_Application::getOptions()->getOptions();

        $selectedOptions = array();

        foreach ($options AS $optionKey => $optionValue) {
            if (strpos($optionKey, $prefix) === 0) {
                $selectedOptions[] = $optionKey;
            }
        }

        sort($selectedOptions);

        foreach ($selectedOptions AS $optionName) {
            $optionFunctionName = 'get' . $this->underscoreToCamelCase(str_replace($prefix . '_', '', $optionName), true);
            echo 'public function ' . $optionFunctionName . '(){
    return $this->_getOption(\'' . $optionName . '\');
}';
        }

        exit;
    }

    public function actionBoardCleanup()
    {
        return $this->responseReroute('XenCentral_Framework_ControllerAdmin_Cleanup', 'BoardCleanup');
    }

    public function actionThreadCleanup()
    {
        return $this->responseReroute('XenCentral_Framework_ControllerAdmin_Cleanup', 'ThreadCleanup');
    }

    public function actionUsergroupCleanup()
    {
        return $this->responseReroute('XenCentral_Framework_ControllerAdmin_Cleanup', 'UsergroupCleanup');
    }

    public function actionDeleteUserFields()
    {
        return $this->responseReroute('XenCentral_Framework_ControllerAdmin_Cleanup', 'DeleteUserFields');
    }

    public function actionDeleteThreadPrefixes()
    {
        return $this->responseReroute('XenCentral_Framework_ControllerAdmin_Cleanup', 'DeleteThreadPrefixes');
    }

    public function actionCleanupUsers()
    {
        return $this->responseReroute('XenCentral_Framework_ControllerAdmin_Cleanup', 'CleanupUsers');
    }

    public function actionClearCache()
    {
        $this->_getCacheModel()->clean();

        return $this->responseMessage((new XenForo_Phrase('xcfw_cache_succesfully_cleaned')));
    }

    public function actionProductUpdater()
    {
        if ($this->isConfirmedPost()) {
            $fileTransfer = new Zend_File_Transfer_Adapter_Http();
            if ($fileTransfer->isUploaded('upload_file')) {
                $fileInfo = $fileTransfer->getFileInfo('upload_file');
                $fileName = $fileInfo['upload_file']['tmp_name'];
            } else {
                $fileName = $this->_input->filterSingle('server_file', XenForo_Input::STRING);
            }

            try {
                $xml = XenForo_Helper_DevelopmentXml::scanFile($fileName);
            } catch (Exception $e) {
                throw new XenForo_Exception(
                        new XenForo_Phrase('provided_file_was_not_valid_xml_file'), true
                );
            }

            if ($xml->getName() != 'addon') {
                throw new XenForo_Exception(new XenForo_Phrase('provided_file_is_not_an_add_on_xml_file'), true);
            }

            $addOnData = array(
                    'addon_id' => (string)$xml['addon_id'],
                    'title' => (string)$xml['title'],
                    'version_string' => (string)$xml['version_string'],
                    'version_id' => (int)$xml['version_id'],
                    'install_callback_class' => (string)$xml['install_callback_class'],
                    'install_callback_method' => (string)$xml['install_callback_method'],
                    'uninstall_callback_class' => (string)$xml['uninstall_callback_class'],
                    'uninstall_callback_method' => (string)$xml['uninstall_callback_method'],
                    'url' => (string)$xml['url'],
            );

            /** @var XenForo_Model_AddOn $addonModel */
            $addonModel = XenForo_Model::create('XenForo_Model_AddOn');

            $existingAddOn = $addonModel->verifyAddOnIsInstallable($addOnData, $addOnData['addon_id']);

            if ($addOnData['install_callback_class'] && $addOnData['install_callback_method']) {
                call_user_func(
                        array($addOnData['install_callback_class'], $addOnData['install_callback_method']),
                        $existingAddOn,
                        $addOnData,
                        $xml
                );
            }

            $addOnId = $addOnData['addon_id'];

            $phrases = XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->phrases->phrase);

            /** @var XenForo_Model_Template $phraseModel */
            $phraseModel = $addonModel->getModelFromCache('XenForo_Model_Phrase');
            $titles=array();
            foreach ($phrases AS $phrase) {
                $titles[] = (string)$phrase['title'];
            }
            $existingPhrases = $phraseModel->getPhrasesInLanguageByTitles($titles, 0);

            foreach ($phrases AS $phrase) {
                $title = (string)$phrase['title'];

                $phraseText=(string)$phrase;

                $dw = XenForo_DataWriter::create('XenForo_DataWriter_Phrase');
                if (isset($existingPhrases[$title])) {
                    if($existingPhrases[$title]['phrase_text']== $phraseText) {
                        continue;
                    }

                    $dw->setExistingData($existingPhrases[$title], true);
                    $dw->set('phrase_text', $phraseText);
                } else {
                    $dw->bulkSet(array(
                            'title' => $title,
                            'phrase_text' => (string)$phrase,
                            'global_cache' => (int)$phrase['global_cache'],
                            'version_id' => (int)$phrase['version_id'],
                            'version_string' => (string)$phrase['version_string'],
                            'language_id' => 0,
                            'addon_id' => $addOnId
                    ));
                }

                $dw->save();
            }

            /** @var XenForo_Model_AdminTemplate $templateModel */
            $templateModel = $addonModel->getModelFromCache('XenForo_Model_AdminTemplate');
            $templates = XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->admin_templates->template);
            $titles = array();
            foreach ($templates AS $template) {
                $titles[] = (string)$template['title'];
            }
            $existingTemplates = $templateModel->getAdminTemplatesByTitles($titles);
            foreach ($templates AS $template) {
                $templateName = (string)$template['title'];

                $templateHtml = XenForo_Helper_DevelopmentXml::processSimpleXmlCdata($template);

                $dw = XenForo_DataWriter::create('XenForo_DataWriter_AdminTemplate');
                if (isset($existingTemplates[$templateName])) {
                    if ($existingTemplates[$templateName]['template'] == $templateHtml) {
                        continue;
                    }

                    $dw->setExistingData($existingTemplates[$templateName], true);
                }

                $dw->set('title', $templateName);
                $dw->set('template', $templateHtml);
                $dw->set('addon_id', $addOnId);
                $dw->save();
            }

            /** @var XenForo_Model_Template $templateModel */
            $templateModel = $addonModel->getModelFromCache('XenForo_Model_Template');
            $templates = XenForo_Helper_DevelopmentXml::fixPhpBug50670($xml->templates->template);
            $titles = array();
            foreach ($templates AS $template) {
                $titles[] = (string)$template['title'];
            }
            $existingTemplates = $templateModel->getTemplatesInStyleByTitles($titles, 0);

            foreach ($templates AS $template) {
                $templateName = (string)$template['title'];
                $templateHtml = XenForo_Helper_DevelopmentXml::processSimpleXmlCdata($template);
                $dw = XenForo_DataWriter::create('XenForo_DataWriter_Template');
                if (isset($existingTemplates[$templateName])) {
                    if ($existingTemplates[$templateName]['template'] == $templateHtml) {
                        continue;
                    }
                    $dw->setExistingData($existingTemplates[$templateName], true);
                    $dw->set('template', $templateHtml);
                } else {
                    $dw->bulkSet(array(
                            'style_id' => 0,
                            'title' => (string)$template['title'],
                            'template' => $templateHtml,
                            'addon_id' => $addOnId,
                            'version_id' => (int)$template['version_id'],
                            'version_string' => (string)$template['version_string'],
                            'disable_modifications' => (int)$template['disable_modifications']
                    ));
                }

                $dw->save();
            }

            /** @var XenForo_Model_EmailTemplate $model */
            $model=XenForo_Model::create('XenForo_Model_EmailTemplate');
            $model->importEmailTemplatesAddOnXml($xml->email_templates, $addOnId, false);

            $this->getModelFromCache('XenForo_Model_Cron')->importCronEntriesAddOnXml($xml->cron, $addOnId);
            $this->getModelFromCache('XenForo_Model_CodeEvent')->importEventListenersAddOnXml($xml->code_event_listeners, $addOnId);

            return $this->responseMessage("Product is successfully upgraded.");
        } else {
            return $this->responseView('XenCentral_ViewAdmin_AddOn_Install', 'xcfw_addon_install');
        }
    }

    public function actionLogViewer()
    {
        return $this->responseView('XenCentral_ViewAdmin_XenCentral', 'xcfw_log_viewer', array());
    }

    public function actionShowLog()
    {
        if (!XenForo_Visitor::getInstance()->isSuperAdmin()) {
            return $this->responseError('Only super administrators are allowed to use this tool.');
        }
        $filePath = $this->_input->filterSingle('file_path', XenForo_Input::STRING);
        if (!file_exists($filePath)) {
            return $this->responseError("Could not find the file.");
        }

        $content = file_get_contents($filePath);
        echo nl2br($content);
        flush();

        $fp = fopen($filePath, "r");
        fseek($fp, filesize($filePath));
        while (true) {
            $line = fread($fp, 1024);
            if ($line) {
                echo nl2br($line);
                flush();
                while (ob_get_level()) {
                    ob_end_flush();
                }
            }
            sleep(0.5);
        }
        exit;
    }

    /**
     * @return XenCentral_Framework_Model_Cache
     */
    protected function _getCacheModel()
    {
        return $this->getModelFromCache('XenCentral_Framework_Model_Cache');
    }

    /**
     * @return XenCentral_Framework_Model_PaymentApi
     */
    protected function _getPaymentApiModel()
    {
        return $this->getModelFromCache('XenCentral_Framework_Model_PaymentApi');
    }

    protected function underscoreToCamelCase($string, $first_char_caps = false)
    {
        if ($first_char_caps == true) {
            $string[0] = strtoupper($string[0]);
        }
        $func = create_function('$c', 'return strtoupper($c[1]);');
        return preg_replace_callback('/_([a-z])/', $func, $string);
    }

}
