/install/install_utils.php
PHP | 2124 lines | 1582 code | 279 blank | 263 comment | 291 complexity | 70e8cd44bc5535ad2d0e256ca8052172 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, BSD-3-Clause
Large files files are truncated, but you can click here to view the full file
- <?php
- if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
- /*********************************************************************************
- * SugarCRM Community Edition is a customer relationship management program developed by
- * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU Affero General Public License version 3 as published by the
- * Free Software Foundation with the addition of the following permission added
- * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
- * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
- * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
- *
- * 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.
- *
- * You should have received a copy of the GNU Affero General Public License along with
- * this program; if not, see http://www.gnu.org/licenses or write to the Free
- * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- *
- * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
- * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
- *
- * The interactive user interfaces in modified source and object code versions
- * of this program must display Appropriate Legal Notices, as required under
- * Section 5 of the GNU Affero General Public License version 3.
- *
- * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
- * these Appropriate Legal Notices must retain the display of the "Powered by
- * SugarCRM" logo. If the display of the logo is not reasonably feasible for
- * technical reasons, the Appropriate Legal Notices must display the words
- * "Powered by SugarCRM".
- ********************************************************************************/
- /*********************************************************************************
- * $Description: TODO: To be written. Portions created by SugarCRM are Copyright
- * (C) SugarCRM, Inc. All Rights Reserved. Contributor(s):
- * ______________________________________..
- * *******************************************************************************/
- require_once('include/utils/zip_utils.php');
- require_once('include/upload_file.php');
- ////////////////
- //// GLOBAL utility
- /**
- * Calls a custom function (if it exists) based on the first parameter,
- * and returns result of function call, or 'undefined' if the function doesn't exist
- * @param string function name to call in custom install hooks
- * @return mixed function call result, or 'undefined'
- */
- function installerHook($function_name, $options = array()){
- if(!isset($GLOBALS['customInstallHooksExist'])){
- if(file_exists('custom/install/install_hooks.php')){
- installLog("installerHook: Found custom/install/install_hooks.php");
- require_once('custom/install/install_hooks.php');
- $GLOBALS['customInstallHooksExist'] = true;
- }
- else{
- installLog("installerHook: Could not find custom/install/install_hooks.php");
- $GLOBALS['customInstallHooksExist'] = false;
- }
- }
- if($GLOBALS['customInstallHooksExist'] === false){
- return 'undefined';
- }
- else{
- if(function_exists($function_name)){
- installLog("installerHook: function {$function_name} found, calling and returning the return value");
- return $function_name($options);
- }
- else{
- installLog("installerHook: function {$function_name} not found in custom install hooks file");
- return 'undefined';
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- //// FROM welcome.php
- /**
- * returns lowercase lang encoding
- * @return string encoding or blank on false
- */
- function parseAcceptLanguage() {
- $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
- if(strpos($lang, ';')) {
- $exLang = explode(';', $lang);
- return strtolower(str_replace('-','_',$exLang[0]));
- } else {
- $match = array();
- if(preg_match("#\w{2}\-?\_?\w{2}#", $lang, $match)) {
- return strtolower(str_replace('-','_',$match[0]));
- }
- }
- return '';
- }
- ///////////////////////////////////////////////////////////////////////////////
- //// FROM localization.php
- /**
- * copies the temporary unzip'd files to their final destination
- * removes unzip'd files from system if $uninstall=true
- * @param bool uninstall true if uninstalling a language pack
- * @return array sugar_config
- */
- function commitLanguagePack($uninstall=false) {
- global $sugar_config;
- global $mod_strings;
- global $base_upgrade_dir;
- global $base_tmp_upgrade_dir;
- $errors = array();
- $manifest = urldecode($_REQUEST['manifest']);
- $zipFile = urldecode($_REQUEST['zipFile']);
- $version = "";
- $show_files = true;
- $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
- $zip_from_dir = ".";
- $zip_to_dir = ".";
- $zip_force_copy = array();
- if($uninstall == false && isset($_SESSION['INSTALLED_LANG_PACKS']) && in_array($zipFile, $_SESSION['INSTALLED_LANG_PACKS'])) {
- return;
- }
- // unzip lang pack to temp dir
- if(isset($zipFile) && !empty($zipFile)) {
- if(is_file($zipFile)) {
- unzip( $zipFile, $unzip_dir );
- } else {
- echo $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
- die(); // no point going any further
- }
- }
- // filter for special to/from dir conditions (langpacks generally don't have them)
- if(isset($manifest) && !empty($manifest)) {
- if(is_file($manifest)) {
- include($manifest);
- if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
- $zip_from_dir = $manifest['copy_files']['from_dir'];
- }
- if( isset( $manifest['copy_files']['to_dir'] ) && $manifest['copy_files']['to_dir'] != "" ){
- $zip_to_dir = $manifest['copy_files']['to_dir'];
- }
- if( isset( $manifest['copy_files']['force_copy'] ) && $manifest['copy_files']['force_copy'] != "" ){
- $zip_force_copy = $manifest['copy_files']['force_copy'];
- }
- if( isset( $manifest['version'] ) ){
- $version = $manifest['version'];
- }
- } else {
- $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
- }
- }
- // find name of language pack: find single file in include/language/xx_xx.lang.php
- $d = dir( "$unzip_dir/$zip_from_dir/include/language" );
- while( $f = $d->read() ){
- if( $f == "." || $f == ".." ){
- continue;
- }
- else if( preg_match("/(.*)\.lang\.php\$/", $f, $match) ){
- $new_lang_name = $match[1];
- }
- }
- if( $new_lang_name == "" ){
- die( $mod_strings['ERR_LANG_NO_LANG_FILE'].$zipFile );
- }
- $new_lang_desc = getLanguagePackName( "$unzip_dir/$zip_from_dir/include/language/$new_lang_name.lang.php" );
- if( $new_lang_desc == "" ){
- die( "No language pack description found at include/language/$new_lang_name.lang.php inside $install_file." );
- }
- // add language to available languages
- $sugar_config['languages'][$new_lang_name] = ($new_lang_desc);
- // get an array of all files to be moved
- $filesFrom = array();
- $filesFrom = findAllFiles($unzip_dir, $filesFrom);
- ///////////////////////////////////////////////////////////////////////////
- //// FINALIZE
- if($uninstall) {
- // unlink all pack files
- foreach($filesFrom as $fileFrom) {
- //echo "deleting: ".getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom))."<br>";
- @unlink(getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
- }
- // remove session entry
- if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS'])) {
- foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $langPack) {
- if($langPack == $zipFile) {
- unset($_SESSION['INSTALLED_LANG_PACKS'][$k]);
- unset($_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k]);
- unset($_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k]);
- $removedLang = $k;
- }
- }
- // remove language from config
- $new_langs = array();
- $old_langs = $sugar_config['languages'];
- foreach( $old_langs as $key => $value ){
- if( $key != $removedLang ){
- $new_langs += array( $key => $value );
- }
- }
- $sugar_config['languages'] = $new_langs;
- }
- } else {
- // copy filesFrom to filesTo
- foreach($filesFrom as $fileFrom) {
- @copy($fileFrom, getcwd().substr($fileFrom, strlen($unzip_dir), strlen($fileFrom)));
- }
- $_SESSION['INSTALLED_LANG_PACKS'][$new_lang_name] = $zipFile;
- $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$new_lang_name] = $version;
- $serial_manifest = array();
- $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
- $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
- $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
- $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$new_lang_name] = base64_encode(serialize($serial_manifest));
- }
- writeSugarConfig($sugar_config);
- return $sugar_config;
- }
- function commitPatch($unlink = false, $type = 'patch'){
- require_once('ModuleInstall/ModuleInstaller.php');
- require_once('include/entryPoint.php');
- global $mod_strings;
- global $base_upgrade_dir;
- global $base_tmp_upgrade_dir;
- global $db;
- $GLOBALS['db'] = $db;
- $errors = array();
- $files = array();
- global $current_user;
- $current_user = new User();
- $current_user->is_admin = '1';
- $old_mod_strings = $mod_strings;
- if(is_dir($base_upgrade_dir)) {
- $files = findAllFiles("$base_upgrade_dir/$type", $files);
- $mi = new ModuleInstaller();
- $mi->silent = true;
- $mod_strings = return_module_language('en', "Administration");
- foreach($files as $file) {
- if(!preg_match('#.*\.zip\$#', $file)) {
- continue;
- }
- // handle manifest.php
- $target_manifest = remove_file_extension( $file ) . '-manifest.php';
- include($target_manifest);
- $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
- unzip($file, $unzip_dir );
- if(file_exists("$unzip_dir/scripts/pre_install.php")){
- require_once("$unzip_dir/scripts/pre_install.php");
- pre_install();
- }
- if( isset( $manifest['copy_files']['from_dir'] ) && $manifest['copy_files']['from_dir'] != "" ){
- $zip_from_dir = $manifest['copy_files']['from_dir'];
- }
- $source = "$unzip_dir/$zip_from_dir";
- $dest = getcwd();
- copy_recursive($source, $dest);
- if(file_exists("$unzip_dir/scripts/post_install.php")){
- require_once("$unzip_dir/scripts/post_install.php");
- post_install();
- }
- $new_upgrade = new UpgradeHistory();
- $new_upgrade->filename = $file;
- $new_upgrade->md5sum = md5_file($file);
- $new_upgrade->type = $manifest['type'];
- $new_upgrade->version = $manifest['version'];
- $new_upgrade->status = "installed";
- //$new_upgrade->author = $manifest['author'];
- $new_upgrade->name = $manifest['name'];
- $new_upgrade->description = $manifest['description'];
- $serial_manifest = array();
- $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
- $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
- $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
- $new_upgrade->manifest = base64_encode(serialize($serial_manifest));
- $new_upgrade->save();
- unlink($file);
- }//rof
- }//fi
- $mod_strings = $old_mod_strings;
- }
- function commitModules($unlink = false, $type = 'module'){
- require_once('ModuleInstall/ModuleInstaller.php');
- require_once('include/entryPoint.php');
- global $mod_strings;
- global $base_upgrade_dir;
- global $base_tmp_upgrade_dir;
- global $db;
- $GLOBALS['db'] = $db;
- $errors = array();
- $files = array();
- global $current_user;
- $current_user = new User();
- $current_user->is_admin = '1';
- $old_mod_strings = $mod_strings;
- if(is_dir(sugar_cached("upload/upgrades"))) {
- $files = findAllFiles(sugar_cached("upload/upgrades/$type"), $files);
- $mi = new ModuleInstaller();
- $mi->silent = true;
- $mod_strings = return_module_language('en', "Administration");
- foreach($files as $file) {
- if(!preg_match('#.*\.zip\$', $file)) {
- continue;
- }
- $lic_name = 'accept_lic_'.str_replace('.', '_', urlencode(basename($file)));
- $can_install = true;
- if(isset($_REQUEST[$lic_name])){
- if($_REQUEST[$lic_name] == 'yes'){
- $can_install = true;
- }else{
- $can_install = false;
- }
- }
- if($can_install){
- // handle manifest.php
- $target_manifest = remove_file_extension( $file ) . '-manifest.php';
- if($type == 'langpack'){
- $_REQUEST['manifest'] = $target_manifest;
- $_REQUEST['zipFile'] = $file;
- commitLanguagePack();
- continue;
- }
- include($target_manifest);
- $unzip_dir = mk_temp_dir( $base_tmp_upgrade_dir );
- unzip($file, $unzip_dir );
- $_REQUEST['install_file'] = $file;
- $mi->install($unzip_dir);
- $new_upgrade = new UpgradeHistory();
- $new_upgrade->filename = $file;
- $new_upgrade->md5sum = md5_file($file);
- $new_upgrade->type = $manifest['type'];
- $new_upgrade->version = $manifest['version'];
- $new_upgrade->status = "installed";
- // $new_upgrade->author = $manifest['author'];
- $new_upgrade->name = $manifest['name'];
- $new_upgrade->description = $manifest['description'];
- $new_upgrade->id_name = (isset($installdefs['id_name'])) ? $installdefs['id_name'] : '';
- $serial_manifest = array();
- $serial_manifest['manifest'] = (isset($manifest) ? $manifest : '');
- $serial_manifest['installdefs'] = (isset($installdefs) ? $installdefs : '');
- $serial_manifest['upgrade_manifest'] = (isset($upgrade_manifest) ? $upgrade_manifest : '');
- $new_upgrade->manifest = base64_encode(serialize($serial_manifest));
- $new_upgrade->save();
- //unlink($file);
- }//fi
- }//rof
- }//fi
- $mod_strings = $old_mod_strings;
- }
- /**
- * creates UpgradeHistory entries
- * @param mode string Install or Uninstall
- */
- function updateUpgradeHistory() {
- if(isset($_SESSION['INSTALLED_LANG_PACKS']) && count($_SESSION['INSTALLED_LANG_PACKS']) > 0) {
- foreach($_SESSION['INSTALLED_LANG_PACKS'] as $k => $zipFile) {
- $new_upgrade = new UpgradeHistory();
- $new_upgrade->filename = $zipFile;
- $new_upgrade->md5sum = md5_file($zipFile);
- $new_upgrade->type = 'langpack';
- $new_upgrade->version = $_SESSION['INSTALLED_LANG_PACKS_VERSION'][$k];
- $new_upgrade->status = "installed";
- $new_upgrade->manifest = $_SESSION['INSTALLED_LANG_PACKS_MANIFEST'][$k];
- $new_upgrade->save();
- }
- }
- }
- /**
- * removes the installed language pack, but the zip is still in the cache dir
- */
- function removeLanguagePack() {
- global $mod_strings;
- global $sugar_config;
- $errors = array();
- $manifest = urldecode($_REQUEST['manifest']);
- $zipFile = urldecode($_REQUEST['zipFile']);
- if(isset($manifest) && !empty($manifest)) {
- if(is_file($manifest)) {
- if(!unlink($manifest)) {
- $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$manifest;
- }
- } else {
- $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$manifest;
- }
- unset($_SESSION['packages_to_install'][$manifest]);
- }
- if(isset($zipFile) && !empty($zipFile)) {
- if(is_file($zipFile)) {
- if(!unlink($zipFile)) {
- $errors[] = $mod_strings['ERR_LANG_CANNOT_DELETE_FILE'].$zipFile;
- }
- } else {
- $errors[] = $mod_strings['ERR_LANG_MISSING_FILE'].$zipFile;
- }
- }
- if(count($errors > 0)) {
- echo "<p class='error'>";
- foreach($errors as $error) {
- echo "{$error}<br>";
- }
- echo "</p>";
- }
- unlinkTempFiles($manifest, $zipFile);
- }
- /**
- * takes the current value of $sugar_config and writes it out to config.php (sorta the same as the final step)
- * @param array sugar_config
- */
- function writeSugarConfig($sugar_config) {
- ksort($sugar_config);
- $sugar_config_string = "<?php\n" .
- '// created: ' . date('Y-m-d H:i:s') . "\n" .
- '$sugar_config = ' .
- var_export($sugar_config, true) .
- ";\n?>\n";
- if(is_writable('config.php')) {
- write_array_to_file( "sugar_config", $sugar_config, "config.php");
- }
- }
- /**
- * uninstalls the Language pack
- */
- function uninstallLangPack() {
- global $sugar_config;
- // remove language from config
- $new_langs = array();
- $old_langs = $sugar_config['languages'];
- foreach( $old_langs as $key => $value ){
- if( $key != $_REQUEST['new_lang_name'] ){
- $new_langs += array( $key => $value );
- }
- }
- $sugar_config['languages'] = $new_langs;
- writeSugarConfig($sugar_config);
- }
- /**
- * retrieves the name of the language
- */
- if ( !function_exists('getLanguagePackName') ) {
- function getLanguagePackName($the_file) {
- require_once( "$the_file" );
- if( isset( $app_list_strings["language_pack_name"] ) ){
- return( $app_list_strings["language_pack_name"] );
- }
- return( "" );
- }
- }
- function getInstalledLangPacks($showButtons=true) {
- global $mod_strings;
- global $next_step;
- $ret = "<tr><td colspan=7 align=left>{$mod_strings['LBL_LANG_PACK_INSTALLED']}</td></tr>";
- //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
- $ret .= "<tr>
- <td width='15%' ><b>{$mod_strings['LBL_ML_NAME']}</b></td>
- <td width='15%' ><b>{$mod_strings['LBL_ML_VERSION']}</b></td>
- <td width='15%' ><b>{$mod_strings['LBL_ML_PUBLISHED']}</b></td>
- <td width='15%' ><b>{$mod_strings['LBL_ML_UNINSTALLABLE']}</b></td>
- <td width='15%' ><b>{$mod_strings['LBL_ML_DESCRIPTION']}</b></td>
- <td width='15%' ></td>
- <td width='15%' ></td>
- </tr>\n";
- $files = array();
- $files = findAllFiles(sugar_cached("upload/upgrades"), $files);
- if(isset($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])){
- if(count($_SESSION['INSTALLED_LANG_PACKS'] > 0)) {
- foreach($_SESSION['INSTALLED_LANG_PACKS'] as $file) {
- // handle manifest.php
- $target_manifest = remove_file_extension( $file ) . '-manifest.php';
- include($target_manifest);
- $name = empty($manifest['name']) ? $file : $manifest['name'];
- $version = empty($manifest['version']) ? '' : $manifest['version'];
- $published_date = empty($manifest['published_date']) ? '' : $manifest['published_date'];
- $icon = '';
- $description = empty($manifest['description']) ? 'None' : $manifest['description'];
- $uninstallable = empty($manifest['is_uninstallable']) ? 'No' : 'Yes';
- $manifest_type = $manifest['type'];
- $deletePackage = getPackButton('uninstall', $target_manifest, $file, $next_step, $uninstallable, $showButtons);
- //$ret .="<table width='100%' cellpadding='0' cellspacing='0' border='0'>";
- $ret .= "<tr>";
- $ret .= "<td width='15%' >".$name."</td>";
- $ret .= "<td width='15%' >".$version."</td>";
- $ret .= "<td width='15%' >".$published_date."</td>";
- $ret .= "<td width='15%' >".$uninstallable."</td>";
- $ret .= "<td width='15%' >".$description."</td>";
- $ret .= "<td width='15%' ></td>";
- $ret .= "<td width='15%' >{$deletePackage}</td>";
- $ret .= "</tr>";
- }
- } else {
- $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
- }
- } else {
- $ret .= "</tr><td colspan=7><i>{$mod_strings['LBL_LANG_NO_PACKS']}</i></td></tr>";
- }
- return $ret;
- }
- function uninstallLanguagePack() {
- return commitLanguagePack(true);
- }
- function getSugarConfigLanguageArray($langZip) {
- global $sugar_config;
- include(remove_file_extension($langZip)."-manifest.php");
- $ret = '';
- if(isset($installdefs['id']) && isset($manifest['name'])) {
- $ret = $installdefs['id']."::".$manifest['name']."::".$manifest['version'];
- }
- return $ret;
- }
- ///////////////////////////////////////////////////////////////////////////////
- //// FROM performSetup.php
- function getInstallDbInstance()
- {
- return DBManagerFactory::getTypeInstance($_SESSION['setup_db_type'], array("db_manager" => $_SESSION['setup_db_manager']));
- }
- function getDbConnection()
- {
- $dbconfig = array(
- "db_host_name" => $_SESSION['setup_db_host_name'],
- "db_user_name" => $_SESSION['setup_db_admin_user_name'],
- "db_password" => $_SESSION['setup_db_admin_password'],
- "db_host_instance" => $_SESSION['setup_db_host_instance'],
- "db_port" => $_SESSION['setup_db_port_num'],
- );
- if(empty($_SESSION['setup_db_create_database'])) {
- $dbconfig["db_name"] = $_SESSION['setup_db_database_name'];
- }
- $db = getInstallDbInstance();
- if(!empty($_SESSION['setup_db_options'])) {
- $db->setOptions($_SESSION['setup_db_options']);
- }
- $db->connect($dbconfig, true);
- return $db;
- }
- /**
- * creates the Sugar DB user (if not admin)
- */
- function handleDbCreateSugarUser() {
- global $mod_strings;
- global $setup_db_database_name;
- global $setup_db_host_name;
- global $setup_db_host_instance;
- global $setup_db_port_num;
- global $setup_db_admin_user_name;
- global $setup_db_admin_password;
- global $sugar_config;
- global $setup_db_sugarsales_user;
- global $setup_site_host_name;
- global $setup_db_sugarsales_password;
- echo $mod_strings['LBL_PERFORM_CREATE_DB_USER'];
- $db = getDbConnection();
- $db->createDbUser($setup_db_database_name, $setup_site_host_name, $setup_db_sugarsales_user, $setup_db_sugarsales_password);
- $err = $db->lastError();
- if($err == '') {
- echo $mod_strings['LBL_PERFORM_DONE'];
- } else {
- echo "<div style='color:red;'>";
- echo "An error occured when creating user:<br>";
- echo "$err<br>";
- echo "</div>";
- installLog("An error occured when creating user: $err");
- }
- }
- /**
- * ensures that the charset and collation for a given database is set
- * MYSQL ONLY
- */
- function handleDbCharsetCollation() {
- global $mod_strings;
- global $setup_db_database_name;
- global $setup_db_host_name;
- global $setup_db_admin_user_name;
- global $setup_db_admin_password;
- global $sugar_config;
- if($_SESSION['setup_db_type'] == 'mysql') {
- $db = getDbConnection();
- $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT CHARACTER SET utf8", true);
- $db->query("ALTER DATABASE `{$setup_db_database_name}` DEFAULT COLLATE utf8_general_ci", true);
- }
- }
- /**
- * creates the new database
- */
- function handleDbCreateDatabase() {
- global $mod_strings;
- global $setup_db_database_name;
- global $setup_db_host_name;
- global $setup_db_host_instance;
- global $setup_db_port_num;
- global $setup_db_admin_user_name;
- global $setup_db_admin_password;
- global $sugar_config;
- echo "{$mod_strings['LBL_PERFORM_CREATE_DB_1']} {$setup_db_database_name} {$mod_strings['LBL_PERFORM_CREATE_DB_2']} {$setup_db_host_name}...";
- $db = getDbConnection();
- if($db->dbExists($setup_db_database_name)) {
- $db->dropDatabase($setup_db_database_name);
- }
- $db->createDatabase($setup_db_database_name);
- echo $mod_strings['LBL_PERFORM_DONE'];
- }
- /**
- * handles creation of Log4PHP properties file
- * This function has been deprecated. Use SugarLogger.
- */
- function handleLog4Php() {
- return;
- }
- function installLog($entry) {
- global $mod_strings;
- $nl = '
- '.gmdate("Y-m-d H:i:s").'...';
- $log = clean_path(getcwd().'/install.log');
- // create if not exists
- if(!file_exists($log)) {
- $fp = @sugar_fopen($log, 'w+'); // attempts to create file
- if(!is_resource($fp)) {
- $GLOBALS['log']->fatal('could not create the install.log file');
- }
- } else {
- $fp = @sugar_fopen($log, 'a+'); // write pointer at end of file
- if(!is_resource($fp)) {
- $GLOBALS['log']->fatal('could not open/lock install.log file');
- }
- }
- if(@fwrite($fp, $nl.$entry) === false) {
- $GLOBALS['log']->fatal('could not write to install.log: '.$entry);
- }
- if(is_resource($fp)) {
- fclose($fp);
- }
- }
- /**
- * takes session vars and creates config.php
- * @return array bottle collection of error messages
- */
- function handleSugarConfig() {
- global $bottle;
- global $cache_dir;
- global $mod_strings;
- global $setup_db_host_name;
- global $setup_db_host_instance;
- global $setup_db_port_num;
- global $setup_db_sugarsales_user;
- global $setup_db_sugarsales_password;
- global $setup_db_database_name;
- global $setup_site_host_name;
- global $setup_site_log_dir;
- global $setup_site_log_file;
- global $setup_site_session_path;
- global $setup_site_guid;
- global $setup_site_url;
- global $setup_sugar_version;
- global $sugar_config;
- global $setup_site_log_level;
- echo "<b>{$mod_strings['LBL_PERFORM_CONFIG_PHP']} (config.php)</b><br>";
- ///////////////////////////////////////////////////////////////////////////////
- //// $sugar_config SETTINGS
- if( is_file('config.php') ){
- $is_writable = is_writable('config.php');
- // require is needed here (config.php is sometimes require'd from install.php)
- require('config.php');
- } else {
- $is_writable = is_writable('.');
- }
- // build default sugar_config and merge with new values
- $sugar_config = sugarArrayMerge(get_sugar_config_defaults(), $sugar_config);
- // always lock the installer
- $sugar_config['installer_locked'] = true;
- // we're setting these since the user was given a fair chance to change them
- $sugar_config['dbconfig']['db_host_name'] = $setup_db_host_name;
- if(!empty($setup_db_host_instance)) {
- $sugar_config['dbconfig']['db_host_instance'] = $setup_db_host_instance;
- } else {
- $sugar_config['dbconfig']['db_host_instance'] = '';
- }
- if(!isset($_SESSION['setup_db_manager'])) {
- $_SESSION['setup_db_manager'] = DBManagerFactory::getManagerByType($_SESSION['setup_db_type']);
- }
- $sugar_config['dbconfig']['db_user_name'] = $setup_db_sugarsales_user;
- $sugar_config['dbconfig']['db_password'] = $setup_db_sugarsales_password;
- $sugar_config['dbconfig']['db_name'] = $setup_db_database_name;
- $sugar_config['dbconfig']['db_type'] = $_SESSION['setup_db_type'];
- $sugar_config['dbconfig']['db_port'] = $setup_db_port_num;
- $sugar_config['dbconfig']['db_manager'] = $_SESSION['setup_db_manager'];
- if(!empty($_SESSION['setup_db_options'])) {
- $sugar_config['dbconfigoption'] = array_merge($sugar_config['dbconfigoption'], $_SESSION['setup_db_options']);
- }
- $sugar_config['cache_dir'] = $cache_dir;
- $sugar_config['default_charset'] = $mod_strings['DEFAULT_CHARSET'];
- $sugar_config['default_email_client'] = 'sugar';
- $sugar_config['default_email_editor'] = 'html';
- $sugar_config['host_name'] = $setup_site_host_name;
- $sugar_config['js_custom_version'] = '';
- $sugar_config['use_real_names'] = true;
- $sugar_config['disable_convert_lead'] = false;
- $sugar_config['log_dir'] = $setup_site_log_dir;
- $sugar_config['log_file'] = $setup_site_log_file;
- //Setup FTS
- if(!empty($_SESSION['fts_type']))
- $sugar_config['full_text_engine'] = array($_SESSION['fts_type'] => array('host'=> $_SESSION['fts_host'], 'port' => $_SESSION['fts_port']));
- // for silent install
- if(!empty($_SESSION['setup_fts_type']))
- {
- $sugar_config['full_text_engine'] = array($_SESSION['setup_fts_type'] => array('host'=> $_SESSION['setup_fts_host'], 'port' => $_SESSION['setup_fts_port']));
- if (isset($_SESSION['setup_fts_hide_config']))
- {
- $sugar_config['hide_full_text_engine_config'] = $_SESSION['setup_fts_hide_config'];
- }
- }
- /*nsingh(bug 22402): Consolidate logger settings under $config['logger'] as liked by the new logger! If log4pphp exists,
- these settings will be overwritten by those in log4php.properties when the user access admin->system settings.*/
- $sugar_config['logger'] =
- array ('level'=>$setup_site_log_level,
- 'file' => array(
- 'ext' => '.log',
- 'name' => 'sugarcrm',
- 'dateFormat' => '%c',
- 'maxSize' => '10MB',
- 'maxLogs' => 10,
- 'suffix' => ''), // bug51583, change default suffix to blank for backwards comptability
- );
- $sugar_config['session_dir'] = $setup_site_session_path;
- $sugar_config['site_url'] = $setup_site_url;
- $sugar_config['sugar_version'] = $setup_sugar_version;
- $sugar_config['tmp_dir'] = $cache_dir.'xml/';
- $sugar_config['upload_dir'] = 'upload/';
- // $sugar_config['use_php_code_json'] = returnPhpJsonStatus(); // true on error
- if( isset($_SESSION['setup_site_sugarbeet_anonymous_stats']) ){
- $sugar_config['sugarbeet'] = $_SESSION['setup_site_sugarbeet_anonymous_stats'];
- }
- $sugar_config['demoData'] = $_SESSION['demoData'];
- if( isset( $setup_site_guid ) ){
- $sugar_config['unique_key'] = $setup_site_guid;
- }
- if(empty($sugar_config['unique_key'])){
- $sugar_config['unique_key'] = md5( create_guid() );
- }
- // add installed langs to config
- // entry in upgrade_history comes AFTER table creation
- if(isset($_SESSION['INSTALLED_LANG_PACKS']) && is_array($_SESSION['INSTALLED_LANG_PACKS']) && !empty($_SESSION['INSTALLED_LANG_PACKS'])) {
- foreach($_SESSION['INSTALLED_LANG_PACKS'] as $langZip) {
- $lang = getSugarConfigLanguageArray($langZip);
- if(!empty($lang)) {
- $exLang = explode('::', $lang);
- if(is_array($exLang) && count($exLang) == 3) {
- $sugar_config['languages'][$exLang[0]] = $exLang[1];
- }
- }
- }
- }
- if(file_exists('install/lang.config.php')){
- include('install/lang.config.php');
- if(!empty($config['languages'])){
- foreach($config['languages'] as $lang=>$label){
- $sugar_config['languages'][$lang] = $label;
- }
- }
- }
- ksort($sugar_config);
- $sugar_config_string = "<?php\n" .
- '// created: ' . date('Y-m-d H:i:s') . "\n" .
- '$sugar_config = ' .
- var_export($sugar_config, true) .
- ";\n?>\n";
- if($is_writable && write_array_to_file( "sugar_config", $sugar_config, "config.php")) {
- // was 'Done'
- } else {
- echo 'failed<br>';
- echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_1']}</p>\n";
- echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_2']}</p>\n";
- echo "<TEXTAREA rows=\"15\" cols=\"80\">".$sugar_config_string."</TEXTAREA>";
- echo "<p>{$mod_strings['ERR_PERFORM_CONFIG_PHP_3']}</p>";
- $bottle[] = $mod_strings['ERR_PERFORM_CONFIG_PHP_4'];
- }
- //Now merge the config_si.php settings into config.php
- if(file_exists('config.php') && file_exists('config_si.php'))
- {
- require_once('modules/UpgradeWizard/uw_utils.php');
- merge_config_si_settings(false, 'config.php', 'config_si.php');
- }
- //// END $sugar_config
- ///////////////////////////////////////////////////////////////////////////////
- return $bottle;
- }
- /**
- * (re)write the .htaccess file to prevent browser access to the log file
- */
- function handleHtaccess(){
- global $mod_strings;
- $ignoreCase = (substr_count(strtolower($_SERVER['SERVER_SOFTWARE']), 'apache/2') > 0)?'(?i)':'';
- $htaccess_file = ".htaccess";
- $contents = '';
- $restrict_str = <<<EOQ
- # BEGIN SUGARCRM RESTRICTIONS
- EOQ;
- if (ini_get('suhosin.perdir') !== false && strpos(ini_get('suhosin.perdir'), 'e') !== false)
- {
- $restrict_str .= "php_value suhosin.executor.include.whitelist upload\n";
- }
- $restrict_str .= <<<EOQ
- RedirectMatch 403 {$ignoreCase}.*\.log$
- RedirectMatch 403 {$ignoreCase}/+not_imported_.*\.txt
- RedirectMatch 403 {$ignoreCase}/+(soap|cache|xtemplate|data|examples|include|log4php|metadata|modules)/+.*\.(php|tpl)
- RedirectMatch 403 {$ignoreCase}/+emailmandelivery\.php
- RedirectMatch 403 {$ignoreCase}/+upload
- RedirectMatch 403 {$ignoreCase}/+custom/+blowfish
- RedirectMatch 403 {$ignoreCase}/+cache/+diagnostic
- RedirectMatch 403 {$ignoreCase}/+files\.md5$
- # END SUGARCRM RESTRICTIONS
- EOQ;
- $cache_headers = <<<EOQ
- <FilesMatch "\.(jpg|png|gif|js|css|ico)$">
- <IfModule mod_headers.c>
- Header set ETag ""
- Header set Cache-Control "max-age=2592000"
- Header set Expires "01 Jan 2112 00:00:00 GMT"
- </IfModule>
- </FilesMatch>
- <IfModule mod_expires.c>
- ExpiresByType text/css "access plus 1 month"
- ExpiresByType text/javascript "access plus 1 month"
- ExpiresByType application/x-javascript "access plus 1 month"
- ExpiresByType image/gif "access plus 1 month"
- ExpiresByType image/jpg "access plus 1 month"
- ExpiresByType image/png "access plus 1 month"
- </IfModule>
- EOQ;
- if(file_exists($htaccess_file)){
- $fp = fopen($htaccess_file, 'r');
- $skip = false;
- while($line = fgets($fp)){
- if(preg_match("/\s*#\s*BEGIN\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = true;
- if(!$skip)$contents .= $line;
- if(preg_match("/\s*#\s*END\s*SUGARCRM\s*RESTRICTIONS/i", $line))$skip = false;
- }
- }
- $status = file_put_contents($htaccess_file, $contents . $restrict_str . $cache_headers);
- if( !$status ) {
- echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_1']}<span class=stop>{$htaccess_file}</span> {$mod_strings['ERR_PERFORM_HTACCESS_2']}</p>\n";
- echo "<p>{$mod_strings['ERR_PERFORM_HTACCESS_3']}</p>\n";
- echo $restrict_str;
- }
- return $status;
- }
- /**
- * (re)write the web.config file to prevent browser access to the log file
- */
- function handleWebConfig()
- {
- if ( !isset($_SERVER['IIS_UrlRewriteModule']) ) {
- return;
- }
- global $setup_site_log_dir;
- global $setup_site_log_file;
- global $sugar_config;
- // Bug 36968 - Fallback to using $sugar_config values when we are not calling this from the installer
- if (empty($setup_site_log_file)) {
- $setup_site_log_file = $sugar_config['log_file'];
- if ( empty($sugar_config['log_file']) ) {
- $setup_site_log_file = 'sugarcrm.log';
- }
- }
- if (empty($setup_site_log_dir)) {
- $setup_site_log_dir = $sugar_config['log_dir'];
- if ( empty($sugar_config['log_dir']) ) {
- $setup_site_log_dir = '.';
- }
- }
- $prefix = $setup_site_log_dir.empty($setup_site_log_dir)?'':'/';
- $config_array = array(
- array('1'=> $prefix.str_replace('.','\\.',$setup_site_log_file).'\\.*' ,'2'=>'log_file_restricted.html'),
- array('1'=> $prefix.'install.log' ,'2'=>'log_file_restricted.html'),
- array('1'=> $prefix.'upgradeWizard.log' ,'2'=>'log_file_restricted.html'),
- array('1'=> $prefix.'emailman.log' ,'2'=>'log_file_restricted.html'),
- array('1'=>'not_imported_.*.txt' ,'2'=>'log_file_restricted.html'),
- array('1'=>'XTemplate/(.*)/(.*).php' ,'2'=>'index.php'),
- array('1'=>'data/(.*).php' ,'2'=>'index.php'),
- array('1'=>'examples/(.*).php' ,'2'=>'index.php'),
- array('1'=>'include/(.*).php' ,'2'=>'index.php'),
- array('1'=>'include/(.*)/(.*).php' ,'2'=>'index.php'),
- array('1'=>'log4php/(.*).php' ,'2'=>'index.php'),
- array('1'=>'log4php/(.*)/(.*)' ,'2'=>'index.php'),
- array('1'=>'metadata/(.*)/(.*).php' ,'2'=>'index.php'),
- array('1'=>'modules/(.*)/(.*).php' ,'2'=>'index.php'),
- array('1'=>'soap/(.*).php' ,'2'=>'index.php'),
- array('1'=>'emailmandelivery.php' ,'2'=>'index.php'),
- array('1'=>'cron.php' ,'2'=>'index.php'),
- array('1'=> $sugar_config['upload_dir'].'.*' ,'2'=>'index.php'),
- );
- $xmldoc = new XMLWriter();
- $xmldoc->openURI('web.config');
- $xmldoc->setIndent(true);
- $xmldoc->setIndentString(' ');
- $xmldoc->startDocument('1.0','UTF-8');
- $xmldoc->startElement('configuration');
- $xmldoc->startElement('system.webServer');
- $xmldoc->startElement('rewrite');
- $xmldoc->startElement('rules');
- for ($i = 0; $i < count($config_array); $i++) {
- $xmldoc->startElement('rule');
- $xmldoc->writeAttribute('name', "redirect$i");
- $xmldoc->writeAttribute('stopProcessing', 'true');
- $xmldoc->startElement('match');
- $xmldoc->writeAttribute('url', $config_array[$i]['1']);
- $xmldoc->endElement();
- $xmldoc->startElement('action');
- $xmldoc->writeAttribute('type', 'Redirect');
- $xmldoc->writeAttribute('url', $config_array[$i]['2']);
- $xmldoc->writeAttribute('redirectType', 'Found');
- $xmldoc->endElement();
- $xmldoc->endElement();
- }
- $xmldoc->endElement();
- $xmldoc->endElement();
- $xmldoc->startElement('caching');
- $xmldoc->startElement('profiles');
- $xmldoc->startElement('remove');
- $xmldoc->writeAttribute('extension', ".php");
- $xmldoc->endElement();
- $xmldoc->endElement();
- $xmldoc->endElement();
- $xmldoc->startElement('staticContent');
- $xmldoc->startElement("clientCache");
- $xmldoc->writeAttribute('cacheControlMode', 'UseMaxAge');
- $xmldoc->writeAttribute('cacheControlMaxAge', '30.00:00:00');
- $xmldoc->endElement();
- $xmldoc->endElement();
- $xmldoc->endElement();
- $xmldoc->endElement();
- $xmldoc->endDocument();
- $xmldoc->flush();
- }
- /**
- * Drop old tables if table exists and told to drop it
- */
- function drop_table_install( &$focus ){
- global $db;
- global $dictionary;
- $result = $db->tableExists($focus->table_name);
- if( $result ){
- $focus->drop_tables();
- $GLOBALS['log']->info("Dropped old ".$focus->table_name." table.");
- return 1;
- }
- else {
- $GLOBALS['log']->info("Did not need to drop old ".$focus->table_name." table. It doesn't exist.");
- return 0;
- }
- }
- // Creating new tables if they don't exist.
- function create_table_if_not_exist( &$focus ){
- global $db;
- $table_created = false;
- // normal code follows
- $result = $db->tableExists($focus->table_name);
- if($result){
- $GLOBALS['log']->info("Table ".$focus->table_name." already exists.");
- } else {
- $focus->create_tables();
- $GLOBALS['log']->info("Created ".$focus->table_name." table.");
- $table_created = true;
- }
- return $table_created;
- }
- function create_default_users(){
- global $db;
- global $setup_site_admin_password;
- global $setup_site_admin_user_name;
- global $create_default_user;
- global $sugar_config;
- require_once('install/UserDemoData.php');
- //Create default admin user
- $user = new User();
- $user->id = 1;
- $user->new_with_id = true;
- $user->last_name = 'Administrator';
- $user->user_name = $setup_site_admin_user_name;
- $user->title = "Administrator";
- $user->status = 'Active';
- $user->is_admin = true;
- $user->employee_status = 'Active';
- $user->user_hash = User::getPasswordHash($setup_site_admin_password);
- $user->email = '';
- $user->picture = UserDemoData::_copy_user_image($user->id);
- $user->save();
- //Bug#53793: Keep default current user in the global variable in order to store 'created_by' info as default user
- // while installation is proceed.
- $GLOBALS['current_user'] = $user;
- if( $create_default_user ){
- $default_user = new User();
- $default_user->last_name = $sugar_config['default_user_name'];
- $default_user->user_name = $sugar_config['default_user_name'];
- $default_user->status = 'Active';
- if( isset($sugar_config['default_user_is_admin']) && $sugar_config['default_user_is_admin'] ){
- $default_user->is_admin = true;
- }
- $default_user->user_hash = User::getPasswordHash($sugar_config['default_password']);
- $default_user->save();
- }
- }
- function set_admin_password( $password ) {
- global $db;
- $user_hash = User::getPasswordHash($password);
- $query = "update users set user_hash='$user_hash' where id='1'";
- $db->query($query);
- }
- function insert_default_settings(){
- global $db;
- global $setup_sugar_version;
- global $sugar_db_version;
- $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromaddress', 'do_not_reply@example.com')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'fromname', 'SugarCRM')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_by_default', '1')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'on', '1')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('notify', 'send_from_assigning_user', '0')");
- /* cn: moved to OutboundEmail class
- $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpserver', 'localhost')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpport', '25')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'sendtype', 'smtp')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpuser', '')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtppass', '')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('mail', 'smtpauth_req', '0')");
- */
- $db->query("INSERT INTO config (category, name, value) VALUES ('info', 'sugar_version', '" . $sugar_db_version . "')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('MySettings', 'tab', '')");
- $db->query("INSERT INTO config (category, name, value) VALUES ('portal', 'on', '0')");
- //insert default tracker settings
- $db->query("INSERT INTO config (category, name, value) VALUES ('tracker', 'Tracker', '1')");
- $db->query( "INSERT INTO config (category, name, value) VALUES ( 'system', 'skypeout_on', '1')" );
- }
- // Returns true if the given file/dir has been made writable (or is already
- // writable).
- function make_writable($file)
- {
- $ret_val = false;
- if(is_file($file) || is_dir($file))
- {
- if(is_writable($file))
- {
- $ret_val = true;
- }
- else
- {
- $original_fileperms = fileperms($file);
- // add user writable permission
- $new_fileperms = $original_fileperms | 0x0080;
- @sugar_chmod($file, $new_fileperms);
- clearstatcache();
- if(is_writable($file))
- {
- $ret_val = true;
- }
- else
- {
- // add group writable permission
- $new_fileperms = $original_fileperms | 0x0010;
- @chmod($file, $new_fileperms);
- clearstatcache();
- if(is_writable($file))
- {
- $ret_val = true;
- }
- else
- {
- // add world writable permission
- $new_fileperms = $original_fileperms | 0x0002;
- @chmod($file, $new_fileperms);
- clearstatcache();
- if(is_writable($file))
- {
- $ret_val = true;
- }
- }
- }
- }
- }
- return $ret_val;
- }
- function recursive_make_writable($start_file)
- {
- $ret_val = make_writable($start_file);
- if($ret_val && is_dir($start_file))
- {
- // PHP 4 alternative to scandir()
- $files = array();
- $dh = opendir($start_file);
- $filename = readdir($dh);
- while(!empty($filename))
- {
- if($filename != '.' && $filename != '..' && $filename != '.svn')
- {
- $files[] = $filename;
- }
- $filename = readdir($dh);
- }
- foreach($files as $file)
- {
- $ret_val = recursive_make_writable($start_file . '/' . $file);
- if(!$ret_val)
- {
- $_SESSION['unwriteable_module_files'][dirname($file)] = dirname($file);
- $fnl_ret_val = false;
- //break;
- }
- }
- }
- if(!$ret_val)
- {
- $unwriteable_directory = is_dir($start_file) ? $start_file : dirname($start_file);
- if($unwriteable_directory[0] == '.'){$unwriteable_directory = substr($unwriteable_directory,1);}
- $_SESSION['unwriteable_module_files'][$unwriteable_directory] = $unwriteable_directory;
- $_SESSION['unwriteable_module_files']['failed'] = true;
- }
- return $ret_val;
- }
- function recursive_is_writable($start_file)
- {
- $ret_val = is_writable($start_file);
- if($ret_val && is_dir($start_file))
- {
- // PHP 4 alternative to scandir()
- $files = array();
- $dh = opendir($start_file);
- $filename = readdir($dh);
- while(!empty($filename))
- {
- if($filename != '.' && $filename != '..' && $filename != '.svn')
- {
- $files[] = $filename;
- }
- $filename = readdir($dh);
- }
- foreach($files as $file)
- {
- $ret_val = recursive_is_writable($start_file . '/' . $file);
- if(!$ret_val)
- {
- break;
- }
- }
- }
- return $ret_val;
- }
- // one place for form validation/conversion to boolean
- function get_boolean_from_request( $field ){
- if( !isset($_REQUEST[$field]) ){
- return( false );
- }
- if( ($_REQUEST[$field] == 'on') || ($_REQUEST[$field] == 'yes') ){
- return(true);
- }
- else {
- return(false);
- }
- }
- function stripslashes_checkstrings($value){
- if(is_string($value)){
- return stripslashes($value);
- }
- return $value;
- }
- function print_debug_array( $name, $debug_array ){
- ksort( $debug_array );
- print( "$name vars:\n" );
- print( "(\n" );
- foreach( $debug_array as $key => $value ){
- if( stristr( $key, "password" ) ){
- $value = "WAS SET";
- }
- print( " [$key] => $value\n" );
- }
- print( ")\n" );
- }
- function print_debug_comment(){
- if( !empty($_REQUEST['debug']) ){
- $_SESSION['debug'] = $_REQUEST['debug'];
- }
- if( !empty($_SESSION['debug']) && …
Large files files are truncated, but you can click here to view the full file