Jump to content

ECC Issue


Christopher Short

Recommended Posts

<?php

/**

 * CubeCart v6

 * ========================================

 * CubeCart is a registered trade mark of CubeCart Limited

 * Copyright CubeCart Limited 2015. All rights reserved.

 * UK Private Limited Company No. 5323904

 * ========================================

 * Web:   http://www.cubecart.com

 * Email:  {removed}

 * License:  GPL-3.0 https://www.gnu.org/licenses/quick-guide-gplv3.html

 */

/**

 * Configuration controller

 *

 * @author Technocrat

 * @author Al Brookbanks

 * @since 5.0.0

 */

class Config {

    /**

     * Current config

     *

     * @var array

     */

    private $_config = array();

    /**

     * Temp configs that should not be written to the db

     *

     * @var array

     */

    private $_temp  = array();

    /**

     * Write the config to the DB

     *

     * @var bool

     */

    private $_write_db = false;

    /**

     * Array of variables before config is written used for validation

     *

     * @var array

     */

    private $_pre_enc_config = array();

    /**

     * Class instance

     *

     * @var instance

     */

    protected static $_instance;

    ##############################################

    final protected function __construct($glob) {

        //Get the main config because it will be used

        if (isset($GLOBALS['db']) && ($result = $GLOBALS['db']->select('CubeCart_config', array('array'), array('name' => 'config'), false, 1, false, false)) !== false) {

            $array_out = $this->_json_decode($result[0]['array']);

        }

        //Remove the db password for safety

        unset($glob['dbpassword']);

        if (!empty($array_out)) {

            $this->_config['config'] = $this->_clean($array_out);

            //Merge the main global with the config

            if (is_array($this->_config['config'])) {

                $this->_config['config'] = array_merge($this->_config['config'], $glob);

            }

        } else {

            $this->_config['config'] = $glob;

        }

        

        $cache = (bool)$this->_config['config']['cache'];

        $GLOBALS['cache']->enable($cache);

        if(!$cache || (defined('CC_IN_ADMIN') && CC_IN_ADMIN)) {

            $GLOBALS['cache']->clear();

        }

    }

    public function __destruct() {

        //Do we need to write to the db

        if ($this->_write_db) {

            $this->_writeDB();

        }

    }

    /**

     * Setup the instance (singleton)

     *

     * @param $glob array Current globals

     *

     * @return Config

     */

    public static function getInstance($glob = array()) {

        if (!(self::$_instance instanceof self)) {

            self::$_instance = new self($glob);

        }

        return self::$_instance;

    }

    //=====[ Public ]=======================================

    /**

     * Is there a config element

     *

     * @param string $config_name

     * @param string $element

     *

     * @return bool

     */

    public function has($config_name, $element) {

        return ($this->get($config_name, $element)) !== false;

    }

    /**

     * Get a value from the config

     *

     * Not all config types are loaded from the start this

     * is done to save cycles and memory

     *

     * If element is empty the entire array of the config

     * is returned

     *

     * @param string $config_name

     * @param string $element

     *

     * @return mixed / false

     */

    public function get($config_name, $element = '') {

        //If there is an config

        if (isset($this->_config[$config_name])) {

            //If there is not an element the entire array

            if (empty($element)) {

                return $this->_config[$config_name];

            } else if (isset($this->_config[$config_name][$element])) {

                return $this->_config[$config_name][$element];

            }

            return false;

        }

        //If we reached this part try to fetch it

        $this->_fetchConfig($config_name);

        //Return it if found

        return $this->get($config_name, $element);

    }

    /**

     * Is an element empty

     *

     * @param string $config_name

     * @param string $element

     *

     * @return bool

     */

    public function isEmpty($config_name, $element) {

        //If the element isn't there then it is empty

        if (!$this->has($config_name, $element)) {

            return true;

        }

        return empty($this->_config[$config_name][$element]);

    }

    /**

     * Merge an emlemet to the config

     *

     * This is done for items that do not need to be recorded to the db

     * or are single use config items.  For example ssl enable/disable.

     *

     * @param string $config_name

     * @param string $element

     * @param string $data

     */

    public function merge($config_name, $element, $data) {

        if (!empty($element)) {

            $this->_temp[$config_name][$element] = $data;

            $this->_config[$config_name][$element] = $data;

        } else {

            if (is_array($data)) {

                if (isset($this->_temp[$config_name])) {

                    $this->_temp[$config_name] = merge_array($this->_temp[$config_name], $data);

                } else {

                    $this->_temp[$config_name] = $data;

                }

                $this->_config[$config_name] = merge_array($this->_config[$config_name], $data);

            }

        }

    }

    /**

     * Set a config value

     *

     * If no element is set then the entire config is

     * set to the data

     *

     * @param string $config_name

     * @param string $element

     * @param string $data

     * @param bool $force_write

     *

     * @return bool

     */

    public function set($config_name, $element, $data, $force_write = false) {

        //Clean up the config array

        if (is_array($data) && !empty($element)) {

            array_walk_recursive($data, create_function('&$s, $k', '$s=stripslashes($s);'));

            $data = $this->_json_encode($data);

        } else if (is_array($data)) {

                array_walk_recursive($data, create_function('&$s, $k', '$s=stripslashes($s);'));

            } else {

            $data = stripslashes($data);

        }

        /**

         * Check to see if the data is the same as it was.

         * If it is we dont need to do anything

         */

        if ($this->get($config_name, $element) == $data) {

            return true;

        }

        //If there isn't an element assign the entire thing

        if (empty($element)) {

            $this->_config[$config_name] = $data;

        } else {

            $this->_config[$config_name][$element] = $data;

        }

        //Write the to the db

        if (!$force_write) {

            $this->_write_db = true;

        } else {

            $this->_writeDB();

            $this->_write_db = false;

        }

        return true;

    }

    //=====[ Private ]=======================================

    /**

     * Strip slashes

     *

     * @param array $array

     *

     * @return array

     */

    private function _clean($array) {

        array_walk_recursive($array, create_function('&$s,$k', '$s=stripslashes($s);'));

        return $array;

    }

    /**

     * Fetch config data

     *

     * @param string $name

     */

    private function _fetchConfig($name) {

        //Clean up the entire config array

        $this->_config[$name] = array();

        //If the DB class exists and the config row exists

        if (isset($GLOBALS['db']) && ($result = $GLOBALS['db']->select('CubeCart_config', array('array'), array('name' => $name), false, 1, false)) !== false) {

            $array_out = $this->_json_decode($result[0]['array']);

            if (($module = $GLOBALS['db']->select('CubeCart_modules', array('status', 'countries'), array('folder' => $name), false, 1, false)) !== false) {

                $array_out = array_merge($module[0], $array_out);

            }

            if (!empty($array_out)) {

                $this->_config[$name] = $this->_clean($array_out);

            }

        }

    }

    /**

     * Json decode but convert if serialized

     */

    private function _json_decode($string) {

        if (preg_match('/^a:[0-9]/', $string)) { // convert from serialized and next save will convert

            $array = unserialize($string);

            if (isset($array['offline_content']) && !empty($array['offline_content'])) {

                $array['offline_content'] = base64_decode($array['offline_content']);

            }

            if (isset($array['store_copyright']) && !empty($array['store_copyright'])) {

                $array['store_copyright'] = base64_decode($array['store_copyright']);

            }

            return $array;

        } else {

            return json_decode(base64_decode($string), true);

        }

    }

    /**

     * Json encode

     */

    private function _json_encode($array) {

        $this->_pre_enc_config = $array;

        return base64_encode(json_encode($array));

    }

    /**

     * Write config to db

     */

    private function _writeDB() {

        if (!empty($this->_config) && is_array($this->_config)) {

            foreach ($this->_config as $config => $data) {

                //Remove data that was merged in

                if (!empty($this->_temp) && isset($this->_temp[$config])) {

                    $match = array_intersect_key($this->_temp[$config], $this->_config[$config]);

                    if (!empty($match)) {

                        foreach ($match as $k => $v) {

                            unset($data[$k]);

                        }

                    }

                }

                //If there is a problem abort

                if (empty($data)) {

                    continue;

                }

                $record = array('array' => $this->_json_encode($data));

                if (strlen($record['array']) > 65535 || strlen($config) > 100) {

                    trigger_error('Config write size error: '.$config, E_USER_ERROR);

                }

                if (Database::getInstance()->count('CubeCart_config', 'name', array('name' => $config))) {

                    //Safeguard to prevent config loss

                    if ($config=='config' && !isset($this->_pre_enc_config['store_name'])) {

                        return false;

                    } else {

                        Database::getInstance()->update('CubeCart_config', $record, array('name' => $config));

                    }

                } else {

                    $record['name'] = $config;

                    Database::getInstance()->insert('CubeCart_config', $record);

                }

            }

        }

    }

}

Link to comment
Share on other sites

The Cache class is created before the Config class is created, so for Config to not find Cache means that PHP maybe has crashed, is shutting down, and in the shutting down, is processing the destruction of a class that calls on Config -- which has already been destroyed.

 

Check the admin, System Logs, Error Log tab for any other errors near this one.

Link to comment
Share on other sites

The Cache class is created before the Config class is created, so for Config to not find Cache means that PHP maybe has crashed, is shutting down, and in the shutting down, is processing the destruction of a class that calls on Config -- which has already been destroyed.

 

Check the admin, System Logs, Error Log tab for any other errors near this one.

I have sever similar to:

File: [seo.class.php] Line: [624] "INSERT INTO `cc_CubeCart_seo_urls` (`type`,`item_id`,`path`,`custom`) VALUES ('cat','15','rocket-motors/loki-research/nozzles','0');" - Duplicate entry 'rocket-motors/loki-research/nozzles' for key 'PRIMARY'

 

but they are 2 days old and don't look related to me.

Link to comment
Share on other sites

They don't look related to me either, but then, "Duplicate entry" errors aren't supposed to happen either.

 

Does this happen reliably? Can you give a sequence of steps that will absolutely cause this error to appear?

 

If so, I have a diagnostic file that may be able to trace out where the problem begins, which the trail ends at line 77.

 

If you cannot determine what steps would reliably cause this error, then finding the cause will be more difficult.

 

In the meantime, you can try this edit:

      if ( isset($GLOBALS['cache']) && is_object($GLOBALS['cache']) ) { // << == NEW LINE
        $cache = (bool)$this->_config['config']['cache'];
        $GLOBALS['cache']->enable($cache);
        if(!$cache || (defined('CC_IN_ADMIN') && CC_IN_ADMIN)) {
            $GLOBALS['cache']->clear();
        }
      } // << == NEW LINE

This says that only if Cache is present, then do this part.

 

I compared CC600 and CC601 to see if there is any code changes related to this, and there isn't.

Link to comment
Share on other sites

They don't look related to me either, but then, "Duplicate entry" errors aren't supposed to happen either.

 

Does this happen reliably? Can you give a sequence of steps that will absolutely cause this error to appear?

 

If so, I have a diagnostic file that may be able to trace out where the problem begins, which the trail ends at line 77.

 

If you cannot determine what steps would reliably cause this error, then finding the cause will be more difficult.

 

In the meantime, you can try this edit:

      if ( isset($GLOBALS['cache']) && is_object($GLOBALS['cache']) ) { // << == NEW LINE
        $cache = (bool)$this->_config['config']['cache'];
        $GLOBALS['cache']->enable($cache);
        if(!$cache || (defined('CC_IN_ADMIN') && CC_IN_ADMIN)) {
            $GLOBALS['cache']->clear();
        }
      } // << == NEW LINE

This says that only if Cache is present, then do this part.

 

I compared CC600 and CC601 to see if there is any code changes related to this, and there isn't.

Um, you're the man!!! this fixed ECC login issues. Now to find out why ecc pulledmy quickbooks data with a - sign in front of the numbers to give me negative inventory. Thanks for your help again.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...