/** * Cloudrexx * * @link http://www.cloudrexx.com * @copyright Cloudrexx AG 2007-2015 * * According to our dual licensing model, this program can be used either * under the terms of the GNU Affero General Public License, version 3, * or under a proprietary license. * * The texts of the GNU Affero General Public License with an additional * permission and of our proprietary license can be found at and * in the LICENSE file you have received along with this program. * * 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 Affero General Public License for more details. * * "Cloudrexx" is a registered trademark of Cloudrexx AG. * The licensing of the program under the AGPLv3 does not imply a * trademark license. Therefore any rights, title and interest in * our trademarks remain entirely with us. */ function _utf8Update() { global $objUpdate, $_DBCONFIG, $objDatabase, $_ARRAYLANG, $_CORELANG; $preferedCollation = 'utf8_unicode_ci'; $usedCollation = ''; $result = true; // fetch currently used collation try { $objResult = \Cx\Lib\UpdateUtil::sql('SHOW CREATE TABLE `' . DBPREFIX . 'access_users`'); if ($objResult->EOF) { setUpdateMsg(sprintf($_ARRAYLANG['TXT_UNABLE_GETTING_DATABASE_TABLE_STRUCTURE'], DBPREFIX . 'access_users')); return false; } $createStatement = $objResult->fields['Create Table']; // note: if charset latin1 is used, collation won't be set $matches = array(); if (preg_match('/COLLATE=([a-z_0-9]*)/', $createStatement, $matches)) { $usedCollation = $matches[1]; } \DBG::dump('Currently used collation: ' . $usedCollation); } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e); } // fetch available collations $arrCollations = _getUtf8Collations(); if (!is_array($arrCollations)) { return $arrCollations; } if (!isset($_SESSION['contrexx_update']['update']['core'])) { $_SESSION['contrexx_update']['update']['core'] = array(); } // note: $usedCollation is the currently used collation. // in case $usedCollation is non-utf8, then the following var // won't be set. This will cause the update system to ask the user // to select an utf8 collation. if (in_array($usedCollation, $arrCollations)) { $_SESSION['contrexx_update']['update']['core']['utf8_collation'] = $usedCollation; } if (isset($_DBCONFIG['charset']) && $_DBCONFIG['charset'] == 'utf8') { // do not update templates if they should be utf8 already $_SESSION['contrexx_update']['update']['utf'] = true; } // show dialog to select utf8 collation if (empty($_SESSION['contrexx_update']['update']['core']['utf8_collation'])) { if (isset($_POST['dbCollation']) && in_array($objUpdate->stripslashes($_POST['dbCollation']), $arrCollations)) { $_SESSION['contrexx_update']['update']['core']['utf8_collation'] = $objUpdate->stripslashes($_POST['dbCollation']); } else { $collationMenu = '<select name="dbCollation">'; foreach ($arrCollations as $collation) { $collationMenu .= '<option value="' . $collation . '"' . ($collation == $preferedCollation ? ' selected="selected"' : '') . '>' . $collation . '</option>'; } $collationMenu .= '</select><br />'; setUpdateMsg($_ARRAYLANG['TXT_SELECT_DB_COLLATION'], 'title'); setUpdateMsg(sprintf($_ARRAYLANG['TXT_SELECT_DB_COLLATION_MSG'] . '<br /><br />', $collationMenu), 'msg'); setUpdateMsg('<input type="submit" value="' . $_CORELANG['TXT_CONTINUE_UPDATE'] . '" name="updateNext" /><input type="hidden" name="processUpdate" id="processUpdate" />', 'button'); return false; } } // WRITE COLLATION TO CONFIG FILE IF NECESSARY if (empty($_DBCONFIG['collation'])) { \DBG::msg('New collation set in _utf8Update(): ' . $_SESSION['contrexx_update']['update']['core']['utf8_collation']); // configuration.php will get written by core.php's _writeNewConfigurationFile() $_DBCONFIG['collation'] = $_SESSION['contrexx_update']['update']['core']['utf8_collation']; // IMPORTANT! // setting result to 'charset_changed' will cause a reinitialization of the update system // to ensure that the db-connections use the proper charset/collation $result = 'charset_changed'; } // SET DATABASE CHARSET AND COLLATION try { $objDbStatement = \Cx\Lib\UpdateUtil::sql("SHOW CREATE DATABASE `" . $_DBCONFIG['database'] . "`"); if (!preg_match('#DEFAULT\\sCHARACTER\\sSET\\sutf8\\sCOLLATE\\s' . $_SESSION['contrexx_update']['update']['core']['utf8_collation'] . '#s', $objDbStatement->fields['Create Database'])) { \Cx\Lib\UpdateUtil::sql("ALTER DATABASE `" . $_DBCONFIG['database'] . "` DEFAULT CHARACTER SET utf8 COLLATE " . $objUpdate->addslashes($_SESSION['contrexx_update']['update']['core']['utf8_collation'])); } } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e); } // CHANGE TABLE CHARSET AND COLLATION $arrContrexxTables = array(DBPREFIX . 'access_group_dynamic_ids', DBPREFIX . 'access_group_static_ids', DBPREFIX . 'access_rel_user_group', DBPREFIX . 'access_settings', DBPREFIX . 'access_users', DBPREFIX . 'access_user_attribute', DBPREFIX . 'access_user_attribute_name', DBPREFIX . 'access_user_attribute_value', DBPREFIX . 'access_user_core_attribute', DBPREFIX . 'access_user_groups', DBPREFIX . 'access_user_mail', DBPREFIX . 'access_user_network', DBPREFIX . 'access_user_profile', DBPREFIX . 'access_user_title', DBPREFIX . 'access_user_validity', DBPREFIX . 'module_block_blocks', DBPREFIX . 'module_block_categories', DBPREFIX . 'module_block_rel_lang_content', DBPREFIX . 'module_block_rel_pages', DBPREFIX . 'module_block_settings', DBPREFIX . 'module_blog_categories', DBPREFIX . 'module_blog_comments', DBPREFIX . 'module_blog_messages', DBPREFIX . 'module_blog_messages_lang', DBPREFIX . 'module_blog_message_to_category', DBPREFIX . 'module_blog_networks', DBPREFIX . 'module_blog_networks_lang', DBPREFIX . 'module_blog_settings', DBPREFIX . 'module_blog_votes', DBPREFIX . 'module_calendar', DBPREFIX . 'module_calendar_categories', DBPREFIX . 'module_calendar_form_data', DBPREFIX . 'module_calendar_form_fields', DBPREFIX . 'module_calendar_registrations', DBPREFIX . 'module_calendar_settings', DBPREFIX . 'module_calendar_style', DBPREFIX . 'module_checkout_settings_general', DBPREFIX . 'module_checkout_settings_mails', DBPREFIX . 'module_checkout_settings_yellowpay', DBPREFIX . 'module_checkout_transactions', DBPREFIX . 'module_contact_form', DBPREFIX . 'module_contact_form_data', DBPREFIX . 'module_contact_form_field', DBPREFIX . 'module_contact_form_field_lang', DBPREFIX . 'module_contact_form_lang', DBPREFIX . 'module_contact_form_submit_data', DBPREFIX . 'module_contact_recipient', DBPREFIX . 'module_contact_recipient_lang', DBPREFIX . 'module_contact_settings', DBPREFIX . 'backend_areas', DBPREFIX . 'backups', DBPREFIX . 'content_node', DBPREFIX . 'content_page', DBPREFIX . 'core_country', DBPREFIX . 'core_mail_template', DBPREFIX . 'core_setting', DBPREFIX . 'core_text', DBPREFIX . 'ids', DBPREFIX . 'languages', DBPREFIX . 'lib_country', DBPREFIX . 'log', DBPREFIX . 'log_entry', DBPREFIX . 'modules', DBPREFIX . 'module_repository', DBPREFIX . 'sessions', DBPREFIX . 'settings', DBPREFIX . 'settings_image', DBPREFIX . 'settings_smtp', DBPREFIX . 'skins', DBPREFIX . 'module_data_categories', DBPREFIX . 'module_data_messages', DBPREFIX . 'module_data_messages_lang', DBPREFIX . 'module_data_message_to_category', DBPREFIX . 'module_data_placeholders', DBPREFIX . 'module_data_settings', DBPREFIX . 'module_directory_categories', DBPREFIX . 'module_directory_dir', DBPREFIX . 'module_directory_inputfields', DBPREFIX . 'module_directory_levels', DBPREFIX . 'module_directory_mail', DBPREFIX . 'module_directory_rel_dir_cat', DBPREFIX . 'module_directory_rel_dir_level', DBPREFIX . 'module_directory_settings', DBPREFIX . 'module_directory_settings_google', DBPREFIX . 'module_directory_vote', DBPREFIX . 'module_docsys', DBPREFIX . 'module_docsys_categories', DBPREFIX . 'module_docsys_entry_category', DBPREFIX . 'module_downloads_category', DBPREFIX . 'module_downloads_category_locale', DBPREFIX . 'module_downloads_download', DBPREFIX . 'module_downloads_download_locale', DBPREFIX . 'module_downloads_group', DBPREFIX . 'module_downloads_group_locale', DBPREFIX . 'module_downloads_rel_download_category', DBPREFIX . 'module_downloads_rel_download_download', DBPREFIX . 'module_downloads_rel_group_category', DBPREFIX . 'module_downloads_settings', DBPREFIX . 'module_ecard_ecards', DBPREFIX . 'module_ecard_settings', DBPREFIX . 'module_egov_configuration', DBPREFIX . 'module_egov_orders', DBPREFIX . 'module_egov_products', DBPREFIX . 'module_egov_product_calendar', DBPREFIX . 'module_egov_product_fields', DBPREFIX . 'module_egov_settings', DBPREFIX . 'module_feed_category', DBPREFIX . 'module_feed_news', DBPREFIX . 'module_feed_newsml_association', DBPREFIX . 'module_feed_newsml_categories', DBPREFIX . 'module_feed_newsml_documents', DBPREFIX . 'module_feed_newsml_providers', DBPREFIX . 'module_filesharing', DBPREFIX . 'module_filesharing_mail_template', DBPREFIX . 'module_forum_access', DBPREFIX . 'module_forum_categories', DBPREFIX . 'module_forum_categories_lang', DBPREFIX . 'module_forum_notification', DBPREFIX . 'module_forum_postings', DBPREFIX . 'module_forum_rating', DBPREFIX . 'module_forum_settings', DBPREFIX . 'module_forum_statistics', DBPREFIX . 'module_gallery_categories', DBPREFIX . 'module_gallery_comments', DBPREFIX . 'module_gallery_language', DBPREFIX . 'module_gallery_language_pics', DBPREFIX . 'module_gallery_pictures', DBPREFIX . 'module_gallery_settings', DBPREFIX . 'module_gallery_votes', DBPREFIX . 'module_guestbook', DBPREFIX . 'module_guestbook_settings', DBPREFIX . 'module_jobs', DBPREFIX . 'module_jobs_categories', DBPREFIX . 'module_jobs_location', DBPREFIX . 'module_jobs_rel_loc_jobs', DBPREFIX . 'module_jobs_settings', DBPREFIX . 'module_knowledge_articles', DBPREFIX . 'module_knowledge_article_content', DBPREFIX . 'module_knowledge_categories', DBPREFIX . 'module_knowledge_categories_content', DBPREFIX . 'module_knowledge_settings', DBPREFIX . 'module_knowledge_tags', DBPREFIX . 'module_knowledge_tags_articles', DBPREFIX . 'module_livecam', DBPREFIX . 'module_livecam_settings', DBPREFIX . 'module_market', DBPREFIX . 'module_market_categories', DBPREFIX . 'module_market_mail', DBPREFIX . 'module_market_paypal', DBPREFIX . 'module_market_settings', DBPREFIX . 'module_market_spez_fields', DBPREFIX . 'module_media_settings', DBPREFIX . 'module_mediadir_categories', DBPREFIX . 'module_mediadir_categories_names', DBPREFIX . 'module_mediadir_comments', DBPREFIX . 'module_mediadir_entries', DBPREFIX . 'module_mediadir_forms', DBPREFIX . 'module_mediadir_form_names', DBPREFIX . 'module_mediadir_inputfields', DBPREFIX . 'module_mediadir_inputfield_names', DBPREFIX . 'module_mediadir_inputfield_types', DBPREFIX . 'module_mediadir_inputfield_verifications', DBPREFIX . 'module_mediadir_levels', DBPREFIX . 'module_mediadir_level_names', DBPREFIX . 'module_mediadir_mails', DBPREFIX . 'module_mediadir_mail_actions', DBPREFIX . 'module_mediadir_masks', DBPREFIX . 'module_mediadir_order_rel_forms_selectors', DBPREFIX . 'module_mediadir_rel_entry_categories', DBPREFIX . 'module_mediadir_rel_entry_inputfields', DBPREFIX . 'module_mediadir_rel_entry_levels', DBPREFIX . 'module_mediadir_settings', DBPREFIX . 'module_mediadir_settings_num_categories', DBPREFIX . 'module_mediadir_settings_num_entries', DBPREFIX . 'module_mediadir_settings_num_levels', DBPREFIX . 'module_mediadir_settings_perm_group_forms', DBPREFIX . 'module_mediadir_votes', DBPREFIX . 'module_memberdir_directories', DBPREFIX . 'module_memberdir_name', DBPREFIX . 'module_memberdir_settings', DBPREFIX . 'module_memberdir_values', DBPREFIX . 'module_news', DBPREFIX . 'module_news_categories', DBPREFIX . 'module_news_categories_locale', DBPREFIX . 'module_news_comments', DBPREFIX . 'module_news_locale', DBPREFIX . 'module_news_settings', DBPREFIX . 'module_news_settings_locale', DBPREFIX . 'module_news_stats_view', DBPREFIX . 'module_news_teaser_frame', DBPREFIX . 'module_news_teaser_frame_templates', DBPREFIX . 'module_news_ticker', DBPREFIX . 'module_news_types', DBPREFIX . 'module_news_types_locale', DBPREFIX . 'module_newsletter', DBPREFIX . 'module_newsletter_access_user', DBPREFIX . 'module_newsletter_attachment', DBPREFIX . 'module_newsletter_category', DBPREFIX . 'module_newsletter_confirm_mail', DBPREFIX . 'module_newsletter_email_link', DBPREFIX . 'module_newsletter_email_link_feedback', DBPREFIX . 'module_newsletter_rel_cat_news', DBPREFIX . 'module_newsletter_rel_usergroup_newsletter', DBPREFIX . 'module_newsletter_rel_user_cat', DBPREFIX . 'module_newsletter_settings', DBPREFIX . 'module_newsletter_template', DBPREFIX . 'module_newsletter_tmp_sending', DBPREFIX . 'module_newsletter_user', DBPREFIX . 'module_newsletter_user_title', DBPREFIX . 'module_podcast_category', DBPREFIX . 'module_podcast_medium', DBPREFIX . 'module_podcast_rel_category_lang', DBPREFIX . 'module_podcast_rel_medium_category', DBPREFIX . 'module_podcast_settings', DBPREFIX . 'module_podcast_template', DBPREFIX . 'module_recommend', DBPREFIX . 'module_shop_article_group', DBPREFIX . 'module_shop_attribute', DBPREFIX . 'module_shop_categories', DBPREFIX . 'module_shop_currencies', DBPREFIX . 'module_shop_customer_group', DBPREFIX . 'module_shop_discountgroup_count_name', DBPREFIX . 'module_shop_discountgroup_count_rate', DBPREFIX . 'module_shop_discount_coupon', DBPREFIX . 'module_shop_importimg', DBPREFIX . 'module_shop_lsv', DBPREFIX . 'module_shop_manufacturer', DBPREFIX . 'module_shop_option', DBPREFIX . 'module_shop_orders', DBPREFIX . 'module_shop_order_attributes', DBPREFIX . 'module_shop_order_items', DBPREFIX . 'module_shop_payment', DBPREFIX . 'module_shop_payment_processors', DBPREFIX . 'module_shop_pricelists', DBPREFIX . 'module_shop_products', DBPREFIX . 'module_shop_rel_countries', DBPREFIX . 'module_shop_rel_customer_coupon', DBPREFIX . 'module_shop_rel_discount_group', DBPREFIX . 'module_shop_rel_payment', DBPREFIX . 'module_shop_rel_product_attribute', DBPREFIX . 'module_shop_rel_shipper', DBPREFIX . 'module_shop_shipment_cost', DBPREFIX . 'module_shop_shipper', DBPREFIX . 'module_shop_vat', DBPREFIX . 'module_shop_zones', DBPREFIX . 'stats_browser', DBPREFIX . 'stats_colourdepth', DBPREFIX . 'stats_config', DBPREFIX . 'stats_country', DBPREFIX . 'stats_hostname', DBPREFIX . 'stats_javascript', DBPREFIX . 'stats_operatingsystem', DBPREFIX . 'stats_referer', DBPREFIX . 'stats_requests', DBPREFIX . 'stats_requests_summary', DBPREFIX . 'stats_screenresolution', DBPREFIX . 'stats_search', DBPREFIX . 'stats_spiders', DBPREFIX . 'stats_spiders_summary', DBPREFIX . 'stats_visitors', DBPREFIX . 'stats_visitors_summary', DBPREFIX . 'module_u2u_address_list', DBPREFIX . 'module_u2u_message_log', DBPREFIX . 'module_u2u_sent_messages', DBPREFIX . 'module_u2u_settings', DBPREFIX . 'module_u2u_user_log', DBPREFIX . 'voting_additionaldata', DBPREFIX . 'voting_email', DBPREFIX . 'voting_rel_email_system', DBPREFIX . 'voting_results', DBPREFIX . 'voting_system', DBPREFIX . 'module_feed_newsml_content_item', DBPREFIX . 'module_newsletter_system', DBPREFIX . 'module_newsletter_config', DBPREFIX . 'module_shop_shipment'); // fetch table collations try { $objInstalledTable = \Cx\Lib\UpdateUtil::sql("SHOW TABLE STATUS LIKE '" . DBPREFIX . "%'"); while (!$objInstalledTable->EOF) { $arrInstalledTables[$objInstalledTable->fields['Name']] = $objInstalledTable->fields['Collation']; $objInstalledTable->MoveNext(); } } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e); } // remove existing constraints $arrInstalledTableNames = array_keys($arrInstalledTables); if (!isset($_SESSION['contrexx_update']['update']['core']['constraints'])) { $_SESSION['contrexx_update']['update']['core']['constraints'] = array(); } try { foreach ($arrInstalledTableNames as $table) { // fetch constraints $constraints = \Cx\Lib\UpdateUtil::get_constraints($table); // check if any constraints are set if (!count($constraints)) { continue; } // backup constraint definition (will be restored after the data has been migrated) $_SESSION['contrexx_update']['update']['core']['constraints'][$table] = $constraints; // remove constraints \Cx\Lib\UpdateUtil::set_constraints($table, array()); } } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e); } // migrate tables to utf8 collation try { foreach ($arrContrexxTables as $table) { $converted = false; if (in_array($table, $arrInstalledTableNames)) { if ($arrInstalledTables[$table] == $_SESSION['contrexx_update']['update']['core']['utf8_collation']) { continue; } else { \DBG::msg('UTF-8: Migrate DB-Table: ' . $table); if (!in_array($table . '_new', $arrInstalledTableNames)) { $objTableStructure = \Cx\Lib\UpdateUtil::sql("SHOW CREATE TABLE `" . $table . "`"); $objTableStructure->fields['Create Table'] = preg_replace(array('/TABLE `' . $table . '/', '/collate[\\s|=][a-z0-9_]+_bin/i', '/default current_timestamp on update current_timestamp/i', '/character\\s+set[\\s|=][a-z0-9_]+/i', '/collate[\\s|=][a-z0-9_]+/i', '/default charset=[a-z0-9_]+/i'), array('TABLE `' . $table . '_new', 'BINARY', '', '', '', ''), $objTableStructure->fields['Create Table']); \Cx\Lib\UpdateUtil::sql($objTableStructure->fields['Create Table'] . " DEFAULT CHARSET=utf8 COLLATE=" . $objUpdate->addslashes($_SESSION['contrexx_update']['update']['core']['utf8_collation']) . ";\n"); } $objResult = \Cx\Lib\UpdateUtil::sql("SELECT COUNT(1) AS rowCount FROM `" . $table . "`"); $oriCount = $objResult->fields['rowCount']; $objResult = \Cx\Lib\UpdateUtil::sql("SELECT COUNT(1) AS rowCount FROM `" . $table . "_new`"); $newCount = $objResult->fields['rowCount']; if ($oriCount !== $newCount) { // migrate data \Cx\Lib\UpdateUtil::sql("TRUNCATE TABLE `" . $table . "_new`"); \Cx\Lib\UpdateUtil::sql("INSERT INTO `" . $table . "_new` SELECT * FROM `" . $table . "`"); } \Cx\Lib\UpdateUtil::sql("DROP TABLE `" . $table . "`"); $converted = true; } } if (in_array($table . '_new', $arrInstalledTableNames) || $converted) { \Cx\Lib\UpdateUtil::sql("RENAME TABLE `" . $table . "_new` TO `" . $table . "`"); } if (!checkTimeoutLimit()) { return 'timeout'; } } } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e); } // reset constraints try { foreach ($_SESSION['contrexx_update']['update']['core']['constraints'] as $table => $constraints) { // set constraints \Cx\Lib\UpdateUtil::set_constraints($table, $constraints); } } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e); } // migrate themes to utf8 if (!isset($_SESSION['contrexx_update']['update']['utf'])) { if (_convertThemes2UTF()) { $_SESSION['contrexx_update']['update']['utf'] = true; } else { return false; } } // $result is either TRUE or 'charset_changed' in case the charset/collation has been changed return $result; }
private function processUpdate() { global $_CORELANG, $_CONFIG, $_ARRAYLANG; $this->objTemplate->addBlockfile('CONTENT', 'process', 'process.html'); if (($return = $this->_loadUpdateLanguage()) !== true) { $this->objTemplate->setVariable('UPDATE_ERROR_MSG', $return); $this->objTemplate->parse('updateProcessError'); } elseif (($arrVersions = $this->getAvailabeVersions()) === false || !@(include_once UPDATE_UPDATES . '/' . $_SESSION['contrexx_update']['version'] . '/' . $arrVersions[$_SESSION['contrexx_update']['version']]['script'])) { $this->objTemplate->setVariable('UPDATE_ERROR_MSG', $_CORELANG['TXT_UPDATE_UNABLE_TO_START']); $this->objTemplate->parse('updateProcessError'); } else { if (!$this->_isNewerVersion($_CONFIG['coreCmsVersion'], $_SESSION['contrexx_update']['version'])) { $result = true; } else { if (!empty($_POST['execution_time'])) { $_SESSION['contrexx_update']['max_execution_time'] = intval($_POST['execution_time']); if (intval($_POST['execution_time']) < 20) { setUpdateMsg('<div class="message-warning">' . $_CORELANG['TXT_UPDATE_EXECUTION_TIME'] . '</div>', 'msg'); setUpdateMsg('<input type="submit" value="' . $_CORELANG['TXT_CONTINUE_UPDATE'] . '" name="updateNext" /><input type="hidden" name="processUpdate" id="processUpdate" />', 'button'); $result = false; } else { die('{"time": ' . intval($_POST['execution_time']) . '}'); } } else { try { if (!activateDebugging()) { throw new \Exception("The debugging file couldn't be created."); } $result = true; } catch (\Exception $e) { setUpdateMsg($_CORELANG['TXT_UPDATE_DBG_FILE'], 'msg'); setUpdateMsg('<input type="submit" value="' . $_CORELANG['TXT_CONTINUE_UPDATE'] . '" name="updateNext" /><input type="hidden" name="skipDebugMsg" id="skipDebugMsg" value="skipDebugMsg" />', 'button'); if (empty($_POST['skipDebugMsg'])) { $result = false; } } if ($result !== false) { DBG::msg('-------------------------------------------------------------'); DBG::msg('CLOUDREXX UPDATE - NEW REQUEST'); DBG::msg('Date: ' . date('d.m.Y H:i:s')); DBG::msg('Get-Params:'); DBG::dump($_GET); DBG::msg('User: '******'contrexx_update']['username']); DBG::msg('-------------------------------------------------------------'); $result = executeContrexxUpdate(); } } } if ($result !== true) { if (!empty($this->arrStatusMsg['error'])) { $this->objTemplate->setVariable('UPDATE_ERROR_MSG', implode('<br />', $this->arrStatusMsg['error'])); $this->objTemplate->parse('updateProcessError'); } if (empty($this->arrStatusMsg['title'])) { $this->arrStatusMsg['title'] = 'Update Fehler'; } if (empty($this->arrStatusMsg['button'])) { $this->arrStatusMsg['button'] = '<input type="submit" value="' . $_CORELANG['TXT_UPDATE_TRY_AGAIN'] . '" name="updateNext" /><input type="hidden" name="processUpdate" id="processUpdate" />'; } if (!empty($this->arrStatusMsg['dialog']) && empty($this->arrStatusMsg['error'])) { $this->objTemplate->hideBlock('processStatus'); $dialogContent = implode('<br />', $this->arrStatusMsg['msg']); if (!$this->ajax) { $dialogContent = str_replace(array('\'', "\r\n"), array('\\\'', ''), $dialogContent); } $this->objTemplate->setVariable('PROCESS_DIALOG_CONTENT', $dialogContent); if ($this->ajax) { $this->html['dialog'] = $this->arrStatusMsg['dialog']; $this->objTemplate->parse('ajaxDialogContent'); } else { $this->objTemplate->parse('dialogContent'); } } else { if (!empty($this->arrStatusMsg['timeout']) && empty($this->arrStatusMsg['error'])) { $this->html['timeout'] = $this->arrStatusMsg['timeout']; } else { $this->objTemplate->hideBlock('dialogContent'); $this->objTemplate->hideBlock('ajaxDialogContent'); $this->objTemplate->setVariable(array('UPDATE_PROCESS_TITLE' => $_CORELANG['TXT_UPDATE_UPDATE_PROCESS'], 'UPDATE_STATUS_TITLE' => $this->arrStatusMsg['title'], 'UPDATE_STATUS' => str_replace('[[SQL_INFO_TITLE]]', $this->arrStatusMsg['title'], implode('<br />', $this->arrStatusMsg['msg'])))); $this->setNavigation($this->arrStatusMsg['button']); } } } else { $this->objTemplate->hideBlock('dialogContent'); $this->objTemplate->hideBlock('ajaxDialogContent'); $this->objTemplate->hideBlock('processStatus'); $urlFrontend = ASCMS_PATH_OFFSET !== '' ? ASCMS_PATH_OFFSET : '/'; if (!empty($_SESSION['contrexx_update']['modified_files']) && count($_SESSION['contrexx_update']['modified_files'])) { foreach ($_SESSION['contrexx_update']['modified_files'] as $arrFile) { $this->objTemplate->setVariable(array('BACKUP_FILE_SRC' => $arrFile['src'], 'BACKUP_FILE_DST' => $arrFile['dst'])); $this->objTemplate->parse('backed_file'); } $this->objTemplate->parse('backed_files'); } else { $this->objTemplate->hideblock('backed_files'); } if (!empty($_SESSION['contrexx_update']['modified_cmds']) && count($_SESSION['contrexx_update']['modified_cmds'])) { foreach ($_SESSION['contrexx_update']['modified_cmds'] as $arrCmds) { $this->objTemplate->setVariable(array('CHANGED_CMD_PAGE_TITLE' => $arrCmds['pageTitle'], 'CHANGED_CMD_ORIG_CMD' => $arrCmds['origCmd'], 'CHANGED_CMD_NEW_CMD' => $arrCmds['newCmd'])); $this->objTemplate->parse('changed_cmd'); } $this->objTemplate->parse('changed_cmds'); } else { $this->objTemplate->hideblock('changed_cmds'); } $this->objTemplate->setVariable(array('TXT_UPDATE_UPDATE_FINISHED' => $_CORELANG['TXT_UPDATE_UPDATE_FINISHED'], 'URL_FRONTEND' => $urlFrontend, 'URL_BACKEND' => ASCMS_PATH_OFFSET . ASCMS_BACKEND_PATH, 'UPDATE_VERSION_INSTALLED' => $this->getLiteralRepresentationOfVersion($_SESSION['contrexx_update']['version']), 'UPDATE_VERSION_NUMBER' => $_SESSION['contrexx_update']['version'])); $this->objTemplate->parse('finish'); $_SESSION['contrexx_update']['step'] = 0; $_SESSION['contrexx_update']['update'] = array(); } } $this->objTemplate->parse('process'); if ($this->ajax) { $this->html['content'] = $this->objTemplate->get('process'); } }
public function preResolve(\Cx\Core\Routing\Url $url) { if ($this->cx->getMode() != \Cx\Core\Core\Controller\Cx::MODE_FRONTEND) { return; } $em = $this->cx->getDb()->getEntityManager(); $rewriteRuleRepo = $em->getRepository($this->getNamespace() . '\\Model\\Entity\\RewriteRule'); $rewriteRules = $rewriteRuleRepo->findAll(array(), array('order' => 'asc')); $last = false; $originalUrl = clone $url; foreach ($rewriteRules as $rewriteRule) { try { $url = $rewriteRule->resolve($url, $last); } catch (\Exception $e) { // This is thrown if the regex of the rule is not valid } if ($last) { break; } } if ($originalUrl->toString() != $url->toString()) { if ($rewriteRule->getRewriteStatusCode() != \Cx\Core\Routing\Model\Entity\RewriteRule::REDIRECTION_TYPE_INTERN) { $headers = array('Location' => $url->toString()); if ($rewriteRule->getRewriteStatusCode() == 301) { array_push($headers, $_SERVER['SERVER_PROTOCOL'] . ' 301 Moved Permanently'); } $this->getComponent('Cache')->writeCacheFileForRequest(null, $headers, ''); \Cx\Core\Csrf\Controller\Csrf::header('Location: ' . $url->toString(), true, $rewriteRule->getRewriteStatusCode()); die; } try { \DBG::log('Fetching content from ' . $url->toString()); $request = new \HTTP_Request2($url->toString(), \HTTP_Request2::METHOD_GET); $request->setConfig(array('follow_redirects' => true)); $response = $request->send(); $content = $response->getBody(); foreach ($response->getHeader() as $key => $value) { if (in_array($key, array('content-encoding', 'transfer-encoding'))) { continue; } \Cx\Core\Csrf\Controller\Csrf::header($key . ':' . $value); } $continue = false; die($content); } catch (\HTTP_Request2_Exception $e) { \DBG::dump($e); } } }
/** * Fetches a json response via HTTP request * @todo Support cookies (to allow login and similiar features) * @param string $url URL to get json from * @param array $data (optional) HTTP post data * @param boolean $secure (optional) Wheter to verify peer using SSL or not, default false * @param string $certificateFile (optional) Local certificate file for non public SSL certificates * @param array Set an optional HTTP Authentication method and supply its login credentials. * The supplied array must comply with the following structure: * <pre class="brush: php"> * $httpAuth = array( * 'httpAuthMethod' => 'none|basic|disgest', * 'httpAuthUsername' => '<username>', * 'httpAuthPassword' => '<password>', * ); * </pre> * @return mixed Decoded JSON on success, false otherwise */ public function getJson($url, $data = array(), $secure = false, $certificateFile = '', $httpAuth = array(), $files = array()) { $request = new \HTTP_Request2($url, \HTTP_Request2::METHOD_POST); if (!empty($httpAuth)) { switch ($httpAuth['httpAuthMethod']) { case 'basic': $request->setAuth($httpAuth['httpAuthUsername'], $httpAuth['httpAuthPassword'], \HTTP_Request2::AUTH_BASIC); break; case 'disgest': $request->setAuth($httpAuth['httpAuthUsername'], $httpAuth['httpAuthPassword'], \HTTP_Request2::AUTH_DIGEST); break; case 'none': default: break; } } foreach ($data as $name => $value) { $request->addPostParameter($name, $value); } if (!empty($files)) { foreach ($files as $fieldId => $file) { $request->addUpload($fieldId, $file); } } if ($this->sessionId !== null) { $request->addCookie(session_name(), $this->sessionId); } $request->setConfig(array('ssl_verify_host' => false, 'ssl_verify_peer' => false, 'follow_redirects' => true, 'strict_redirects' => true)); $response = $request->send(); //echo '<pre>';var_dump($response->getBody());echo '<br /><br />'; $cookies = $response->getCookies(); foreach ($cookies as &$cookie) { if ($cookie['name'] === session_name()) { $this->sessionId = $cookie['value']; break; } } if ($response->getStatus() != 200) { \DBG::msg(__METHOD__ . ' Request failed! Status: ' . $response->getStatus()); \DBG::msg('URL: ' . $url); \DBG::dump($data); return false; } $body = json_decode($response->getBody()); if ($body === NULL) { \DBG::msg(__METHOD__ . ' failed!'); \DBG::dump($response->getBody()); } return $body; }
protected function fetchResponse($license, $_CONFIG, $forceTemplate, $_CORELANG) { $v = preg_split('#\\.#', $_CONFIG['coreCmsVersion']); $e = $_CONFIG['coreCmsEdition']; $version = current($v); unset($v[key($v)]); foreach ($v as $part) { $version *= 100; $version += $part; } $srvUri = 'updatesrv1.contrexx.com'; $srvPath = '/'; $data = array('installationId' => $license->getInstallationId(), 'licenseKey' => $license->getLicenseKey(), 'edition' => $license->getEditionName(), 'version' => $this->coreCmsVersion, 'versionstate' => $this->coreCmsStatus, 'domainName' => $this->domainUrl, 'sendTemplate' => $forceTemplate); if (true) { try { $objFile = new \Cx\Lib\FileSystem\File(ASCMS_INSTANCE_PATH . ASCMS_INSTANCE_OFFSET . '/config/License.lic'); $rawData = $objFile->getData(); $response = json_decode(base64_decode($rawData)); } catch (\Cx\Lib\FileSystem\FileSystemException $e) { $license->setState(License::LICENSE_ERROR); $license->setGrayzoneMessages(array(\FWLanguage::getLanguageCodeById(LANG_ID) => new Message(\FWLanguage::getLanguageCodeById(LANG_ID), $_CORELANG['TXT_LICENSE_COMMUNICATION_ERROR']))); $license->check(); throw $e; } return $response; } $a = $_SERVER['REMOTE_ADDR']; $r = 'http://'; if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') { $r = 'https://'; } $r .= $_SERVER['SERVER_NAME'] . ASCMS_INSTANCE_OFFSET; $request = new \HTTP_Request2('http://' . $srvUri . $srvPath . '?v=' . $version, \HTTP_Request2::METHOD_POST); $request->setHeader('X-Edition', $e); $request->setHeader('X-Remote-Addr', $a); $request->setHeader('Referer', $r); $jd = new \Cx\Core\Json\JsonData(); $request->addPostParameter('data', $jd->json($data)); try { $objResponse = $request->send(); if ($objResponse->getStatus() !== 200) { $license->setState(License::LICENSE_ERROR); $license->setGrayzoneMessages(array(\FWLanguage::getLanguageCodeById(LANG_ID) => new Message(\FWLanguage::getLanguageCodeById(LANG_ID), $_CORELANG['TXT_LICENSE_COMMUNICATION_ERROR']))); $license->check(); return null; } else { \DBG::dump($objResponse->getBody()); $response = json_decode($objResponse->getBody()); } } catch (\HTTP_Request2_Exception $objException) { $license->setState(License::LICENSE_ERROR); $license->setGrayzoneMessages(array(\FWLanguage::getLanguageCodeById(LANG_ID) => new Message(\FWLanguage::getLanguageCodeById(LANG_ID), $_CORELANG['TXT_LICENSE_COMMUNICATION_ERROR']))); $license->check(); throw $objException; } return $response; }
/** * Initializes the Cx class * This does everything related to Cloudrexx. * @param string $mode (optional) Use constants, one of self::MODE_[FRONTEND|BACKEND|CLI|MINIMAL] * @param string $configFilePath The absolute path to a Cloudrexx configuration * file (configuration.php) that shall be loaded * instead of the default one. * @param boolean $setAsPreferred Whether or not to set the Cx instance as preferred instance to be used */ protected function __construct($mode = null, $configFilePath = null, $setAsPreferred = false, $checkInstallationStatus = true) { // register this new Cx instance // will be used by \Cx\Core\Core\Controller\Cx::instanciate() self::registerInstance($this, $configFilePath, $setAsPreferred); try { /** * This starts time measurement * Timer will get stopped in finalize() method */ $this->startTimer(); /** * Load config/configuration.php */ $this->loadConfig($configFilePath); /** * Loads the basic configuration ($_CONFIG) from config/settings.php */ $this->loadSettings(); /** * Checks if the system has been installed (CONTREXX_INSTALLED). * If not, the user will be redirected to the web-installer. */ if ($checkInstallationStatus) { $this->checkInstallationStatus(); } /** * Verifies that the basic configuration ($_CONFIG) has bee loaded. * If not, the system will halt. */ $this->checkBasicConfiguration(); /** * Sets the path to the customizing directory (/customizing) of the website, * if the associated functionality has been activatd. */ $this->setCustomizingPath(); /** * Sets the mode Cloudrexx runs in * One of self::MODE_[FRONTEND|BACKEND|CLI|MINIMAL] */ $this->setMode($mode); /** * Early initializations. Verifies that the system is online (not suspended). * Initializes the ClassLoader, the legacy Environment variables and executes * the preInit-hook-scripts. Finally it verifies the requested HTTP-Host. */ $this->preInit(); /** * Defines the core constants (ASCMS_*) of Cloudrexx as defined in config/set_constants.php * and config/SetCustomizableConstants.php. */ $this->defineLegacyConstants(); /** * Loads ClassLoader, EventManager and Database connection * For now, this also loads some legacy things like API, AdoDB, Env and InitCMS */ $this->init(); /** * In order to make this file customizable, we explicitly * search for a subclass of Cx\Core\Core\Controller\Cx named Cx\Customizing\Core\Cx * If such a class is found, it is loaded and this request will be stopped */ $this->handleCustomizing(); /** * Initialize license */ $this->preComponentLoad(); /** * Loads all active components */ $this->loadComponents(); $this->postComponentLoad(); /** * Initialize request * Request is not initialized for command mode */ $this->postInit(); /** * Since we have a valid state now, we can start executing * all of the component's hook methods. * This initializes the main template, executes all hooks * and parses the template. * * This is not executed automaticly in minimal. Invoke it * yourself if necessary and be sure to handle exceptions. * * Command mode is different ;-) */ if ($this->mode == self::MODE_MINIMAL) { return; } $this->loadContrexx(); } catch (InstanceException $e) { return; } catch (\Cx\Core\Error\Model\Entity\ShinyException $e) { if ($this->mode != self::MODE_BACKEND) { throw new \Exception($e->getMessage()); } // reset root of Cx\Core\Html\Sigma to backend template path $this->template->setRoot($this->codeBaseAdminTemplatePath); $this->template->setVariable('ADMIN_CONTENT', $e->getBackendViewMessage()); $this->setPostContentLoadPlaceholders(); $this->finalize(); die; } catch (\Exception $e) { \header($_SERVER['SERVER_PROTOCOL'] . ' 500 Server Error'); if (file_exists($this->websiteDocumentRootPath . '/offline.html')) { $offlinePath = $this->websiteDocumentRootPath; } else { $offlinePath = $this->codeBaseDocumentRootPath; } echo file_get_contents($offlinePath . '/offline.html'); \DBG::msg('Cloudrexx initialization failed! ' . get_class($e) . ': "' . $e->getMessage() . '"'); \DBG::msg('In file ' . $e->getFile() . ' on Line ' . $e->getLine()); \DBG::dump($e->getTrace()); die; } }
/** * Merges CSS definitions of modules with updated template * @return mixed Additional CSS definitions as string or false on error */ function _calculateNewCss(&$viewUpdateTable, &$moduleStyles, $objUpdate) { global $_CONFIG; // Calculate new CSS definitions $additionalCss = array(); foreach ($viewUpdateTable as $module => $data) { $version = $data['version']; $dependencies = $data['dependencies']; // only add css if the installed version is older than $version if (!$objUpdate->_isNewerVersion($_CONFIG['coreCmsVersion'], $version)) { continue; } if (!isset($moduleStyles[$module])) { \DBG::msg('No style definitions for module "' . $module . '" in this theme type'); continue; } if (!isset($additionalCss[$module])) { $additionalCss[$module] = $moduleStyles[$module]; } foreach ($dependencies as $module) { if (!isset($additionalCss[$module])) { $additionalCss[$module] = $moduleStyles[$module]; } } } \DBG::msg('--- added modules css definitions for modules: ---'); \DBG::dump(array_keys($additionalCss)); $additionalCss = implode("\r\n\r\n", $additionalCss); return $additionalCss; }
\DBG::dump($calendarMigration); return $calendarMigration; } // rewrite backendAreas require_once dirname(__FILE__) . '/components/core/backendAreas.php'; $backendAreasUpdate = _updateBackendAreas(); if ($backendAreasUpdate !== true) { return $backendAreasUpdate; } } elseif ($objUpdate->_isNewerVersion($_CONFIG['coreCmsVersion'], '3.1.1')) { $calendarComponentUpdateFile = dirname(__FILE__) . '/components/module/calendar.php'; require_once $calendarComponentUpdateFile; $CalendarUpdate31 = new CalendarUpdate31(); $calendarMigration = $CalendarUpdate31->migrateContentPages(); if ($calendarMigration !== true) { \DBG::dump($calendarMigration); return $calendarMigration; } } /*************************************** * * CONTACT: Add multi-file upload field * **************************************/ if ($objUpdate->_isNewerVersion($_CONFIG['coreCmsVersion'], '3.1.0')) { try { \Cx\Lib\UpdateUtil::table(DBPREFIX . 'module_contact_form_field', array('id' => array('type' => 'INT(10)', 'unsigned' => true, 'notnull' => true, 'auto_increment' => true, 'primary' => true), 'id_form' => array('type' => 'INT(10)', 'unsigned' => true, 'notnull' => true, 'default' => '0'), 'type' => array('type' => 'ENUM(\'text\',\'label\',\'checkbox\',\'checkboxGroup\',\'country\',\'date\',\'file\',\'multi_file\',\'fieldset\',\'hidden\',\'horizontalLine\',\'password\',\'radio\',\'select\',\'textarea\',\'recipient\',\'special\')', 'notnull' => true, 'default' => 'text'), 'special_type' => array('type' => 'VARCHAR(20)', 'notnull' => true), 'is_required' => array('type' => 'SET(\'0\',\'1\')', 'notnull' => true, 'default' => '0'), 'check_type' => array('type' => 'INT(3)', 'notnull' => true, 'default' => '1'), 'order_id' => array('type' => 'SMALLINT(5)', 'unsigned' => true, 'notnull' => true, 'default' => '0'))); // change all fields currently set to 'file' to 'multi_file' ('multi_file' is same as former 'file' in previous versions) \Cx\Lib\UpdateUtil::sql("UPDATE `" . DBPREFIX . "module_contact_form_field` SET `type` = 'multi_file' WHERE `type` = 'file'"); } catch (\Cx\Lib\UpdateException $e) { return \Cx\Lib\UpdateUtil::DefaultActionHandler($e);
/** * Update given object to database * Callable from RecursiveArrayAccess class on offsetSet * * @param RecursiveArrayAccess $recursiveArrayAccess session object array */ public static function updateToDb($recursiveArrayAccess) { if (empty($recursiveArrayAccess->id) && (string) $recursiveArrayAccess->offset != '') { $query = 'INSERT INTO ' . DBPREFIX . 'session_variable SET `parent_id` = "' . intval($recursiveArrayAccess->parentId) . '", `sessionid` = "' . static::getInstance()->sessionid . '", `key` = "' . contrexx_input2db($recursiveArrayAccess->offset) . '", `value` = ""'; \Env::get('db')->Execute($query); $recursiveArrayAccess->id = \Env::get('db')->Insert_ID(); } foreach ($recursiveArrayAccess->data as $key => $value) { if ($recursiveArrayAccess->isDirty($key)) { if (is_a($value, 'Cx\\Core\\Model\\RecursiveArrayAccess')) { $serializedValue = ''; } else { // is_callable() can return true for type array, so we need to check that it is not an array if (!is_array($value) && !is_string($value) && is_callable($value)) { \DBG::dump('Function for session index ' . $key . ' can not be stored, saving functions in session is not supported. Please use json instead'); continue; } $serializedValue = contrexx_input2db(serialize($value)); } $query = 'INSERT INTO ' . DBPREFIX . 'session_variable SET `parent_id` = "' . intval($recursiveArrayAccess->id) . '", `sessionid` = "' . static::getInstance()->sessionid . '", `key` = "' . contrexx_input2db($key) . '", `value` = "' . $serializedValue . '" ON DUPLICATE KEY UPDATE `value` = "' . $serializedValue . '"'; \Env::get('db')->Execute($query); } if (is_a($value, 'Cx\\Core\\Model\\RecursiveArrayAccess')) { $value->parentId = intval($recursiveArrayAccess->id); static::updateToDb($value); } } }