Classes

File io/data/config/ConfigManager.class.php

File io/data/config/ConfigManager.class.php

  1:   2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20:  21:  22:  23:  24:  25:  26:  27:  28:  29:  30:  31:  32:  33:  34:  35:  36:  37:  38:  39:  40:  41:  42:  43:  44:  45:  46:  47:  48:  49:  50:  51:  52:  53:  54:  55:  56:  57:  58:  59:  60:  61:  62:  63:  64:  65:  66:  67:  68:  69:  70:  71:  72:  73:  74:  75:  76:  77:  78:  79:  80:  81:  82:  83:  84:  85:  86:  87:  88:  89:  90:  91:  92:  93:  94:  95:  96:  97:  98:  99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 
<?php
/**
 * This class manages config loading and saving. It makes a two-level lazy loading:
 * <ul>
 *  <li>A top-level cache which avoids loading a data if it has already been done since the
 * beginning of the current page generation. This cache has a short life span: it's flushed
 * as of the PHP interpreter reaches the end of the page generation.</li>
 *  <li>A filesystem or shared RAM cache to avoid querying the database many times to obtain the same value.
 * This cache is less powerful than the previous one but it has an infinite life span. Indeed, it's
 * valid until the value changes and the manager is asked to store it</li>
 * </ul>
 * @package     IO
 * @subpackage  Data\config
 * @copyright   &copy; 2005-2019 PHPBoost
 * @license     https://www.gnu.org/licenses/gpl-3.0.html GNU/GPL-3.0
 * @author      Benoit SAUTEL <ben.popeye@phpboost.com>
 * @version     PHPBoost 5.2 - last update: 2017 03 13
 * @since       PHPBoost 3.0 - 2009 09 16
 * @contributor Julien BRISWALTER <j1.seth@phpboost.com>
*/

class ConfigManager
{
    /**
     * Loads the data identified by the parameters.
     * @param $classname Name of the class which is expected to be returned
     * @param $module_name Name of the module owning the entry to load
     * @param $entry_name If the module wants to manage several entries,
     * it's the name of the entry you want to load
     * @return ConfigData The loaded data
     */
    public static function load($classname, $module_name, $entry_name = '')
    {
        try
        {
            return CacheManager::try_load($classname, $module_name, $entry_name);
        }
        catch(CacheDataNotFoundException $ex)
        {
            $data = null;
            try
            {
                $data = self::load_in_db($module_name, $entry_name);
                CacheManager::save($data, $module_name, $entry_name);
            }
            catch(ConfigNotFoundException $ex)
            {
                $data = new $classname();
                $data->set_default_values();
                $name = self::compute_entry_name($module_name, $entry_name);
                self::save_in_db($name, $data);
                CacheManager::save($data, $module_name, $entry_name);
            }
            catch (PHPBoostNotInstalledException $ex)
            {
                $data = new $classname();
                $data->set_default_values();
            }
            catch (MySQLUnexistingDatabaseException $ex)
            {
                $data = new $classname();
                $data->set_default_values();
            }
            catch (MySQLQuerierException $ex)
            {
                $data = new $classname();
                $data->set_default_values();
            }

            return $data;
        }
    }

    /**
     * @return ConfigData
     */
    private static function load_in_db($module_name, $entry_name = '')
    {
        $name = self::compute_entry_name($module_name, $entry_name);

        try
        {
            $result = PersistenceContext::get_querier()->select_single_row(DB_TABLE_CONFIGS, array('value'), 'WHERE name = :name', array('name' => $name));
        }
        catch(RowNotFoundException $ex)
        {
            throw new ConfigNotFoundException($name);
        }

        $required_value = @unserialize($result['value']);
        if ($required_value === false)
        {
            throw new ConfigNotFoundException($name);
        }

        return $required_value;
    }

    /**
     * @return string
     */
    private static function compute_entry_name($module_name, $entry_name)
    {
        if (!empty($entry_name))
        {
            return Url::encode_rewrite($module_name . '-' . $entry_name);
        }
        else
        {
            return Url::encode_rewrite($module_name);
        }
    }

    /**
     * Saves in the data base (DB_TABLE_CONFIGS table) the data and has it become persistent.
     * @param string $module_name Name of the module owning this entry
     * @param ConfigData $data Data to save
     * @param string $entry_name The name of the entry if the module uses several entries
     */
    public static function save($module_name, ConfigData $data, $entry_name = '')
    {
        $name = self::compute_entry_name($module_name, $entry_name);

        self::save_in_db($name, $data);

        CacheManager::save($data, $module_name, $entry_name);
    }

    /**
     * Delete an configuration in the database and the cache
     * @param string $module_name Name of the module owning this entry
     * @param string $entry_name The name of the entry if the module uses several entries
     */
    public static function delete($module_name, $entry_name = '')
    {
        $name = self::compute_entry_name($module_name, $entry_name);

        try {
            PersistenceContext::get_querier()->delete(DB_TABLE_CONFIGS, 'WHERE name=:name', array('name' => $name));
        } catch (MySQLQuerierException $e) {
        }

        CacheManager::invalidate($module_name, $entry_name);
    }

    private static function save_in_db($name, ConfigData $data)
    {
        $serialized_data = TextHelper::serialize($data);

        $update = PersistenceContext::get_querier()->inject('UPDATE ' . DB_TABLE_CONFIGS . ' SET value = :value WHERE name = :name', array('value' => $serialized_data, 'name' => $name));

        if ($update->get_affected_rows() == 0)
        {
            // If the update requests finds the row but has nothing to update, it affects 0 rows
            $count = PersistenceContext::get_querier()->count(DB_TABLE_CONFIGS, 'WHERE name = :name', array('name' => $name));

            if ($count == 0)
            {
                PersistenceContext::get_querier()->inject('INSERT INTO ' . DB_TABLE_CONFIGS . ' (name, value) VALUES (:name, :value)', array('name' => $name, 'value' => $serialized_data));
            }
        }
    }
}
?>