<?php
/**
 * Manage application and plugins configurations with key/value pair.
 * **nb:** It's possible to specify namespace in order to distinct global configuration to plugin custom configuration
 * @author valentin carruesco
 * @category Core
 * @license MIT
 */
class Configuration extends Entity {
    public $id,$key,$value;
    public $confTab;
    public $entityLabel = 'Configuration';
    protected $fields = array(
        'id' => array('label'=>'Identifiant','type'=>'key'),
        'key' => array('label'=>'Clée','type'=>'longstring'),
        'value' => array('label'=>'Valeur','type'=>'longstring')
    );

    /**
     * Get all configurations from database OR session if it was yet loaded
     * This function is called at start of program and global var '$conf' is filled with response, so use global $conf instead of call this function.
     * #### Example
     * ```php
     * $confs = Configuration::getAll();
     * var_dump($confs);
     * ```.
     * @return array Array of configurations
     */
    public function getAll() {
        if (!isset($_SESSION['configuration'])) {

            $configurationManager = new self();
            $configs = $configurationManager->loadAll();
            $this->confTab = array();

            foreach ($configs as $config)
                $this->confTab[$config->key] = decrypt($config->value);

            $_SESSION['configuration'] = serialize($this->confTab);
        } else {
            $this->confTab = unserialize($_SESSION['configuration']);
        }
    }

    //Défini / récupère un set de configurations générique
    public static function setting($name,$settings=null){
        if(!isset($settings)) return isset($GLOBALS['setting'][$name]) ? $GLOBALS['setting'][$name] : array();
        $GLOBALS['setting'][$name] = $settings;
    }

    //Met en page (tableau html) un set de configuration générique
    public static function html($name){
        global $conf;
        $options = isset($GLOBALS['setting'][$name]) ? $GLOBALS['setting'][$name] : array(); ?>

        <table id="<?php echo $name; ?>-setting-form" class="table table-striped <?php echo $name; ?>-setting-form">
            <tbody>
            <?php foreach($options as $key=>$infos):
                if(!is_array($infos)): ?>
                <tr><th colspan="2" class="bg-secondary text-light py-2 align-middle"><h4 class="m-0"><i class="fas fa-angle-right"></i> <?php echo $infos;?></h4></th></tr>
                <?php continue; endif;
                $confValue = $conf->get($key);


                $infos['attributes'] = empty($infos['attributes']) ? array() : $infos['attributes'];
                if(isset($confValue)) $infos['value'] = htmlentities($confValue);

                //retro compatibilité parameters / attributes
                if(isset($infos['parameters'])){
                    foreach($infos['parameters'] as $attribute=>$parameter){
                        if(isset($infos['attributes'][$attribute])) continue;
                        $infos['attributes'][$attribute] = $attribute.'="'.$parameter.'"';
                   }
                }
                $infos['id'] = $key;

                if(!empty( $infos['placeholder'])) $infos['placeholder'] = '"'. $infos['placeholder'].'"';
                if(!empty( $infos['placeholder'])) $infos['attributes']['placeholder'] = $infos['placeholder'] ;

                $field = FieldType::toHtml($infos,null,array('allowCustomLabel'=>false));
                ?>
                <tr class="<?php echo $key; ?>">
                    <th class="align-middle position-relative"><?php echo $field['label']; ?>
                    <?php if (!empty($field['legend'])): ?>
                        <small class="text-muted"> - <?php echo $field['legend']; ?></small>
                    <?php endif; ?>
                    </th>
                    <td class="align-middle position-relative">
                    <?php
                        if($infos['type']=='dropzone' && isset($infos['attributes']['documents'])){
                            $infos['attributes']['value'] = array($infos['attributes']['documents']);
                            unset($infos['attributes']['documents']);
                        }
                        echo $field['input'];
                    ?>
                    </td>
                </tr>
            <?php endforeach; ?>
            </tbody>
        </table>
        <?php
    }

    /**
     * Get configuration value from it key
     * #### Example
     * ```php
     * global $conf; // global var, contain configurations
     * echo $conf->get('myConfigKey'); // print myConfigKey value
     * ```.
     * @param string configuration key
     * @param string configuration namespace (default is 'conf')
     *
     * @return string valeur de la configuration
     */
    public function get($key) {
        return isset($this->confTab[$key]) ? htmlspecialchars_decode($this->confTab[$key]) : '';
    }

    /**
     * Update or insert configuration value in database with specified key
     * #### Example
     * ```php
     * global $conf; // global var, contain configurations
     * echo $conf->put('myNewConfigKey','hello!'); //create configuration myNewConfigKey with value 'hello!'
     * echo $conf->put('myNewConfigKey','hello 2!'); //update configuration myNewConfigKey with value 'hello2!'
     * ```.
     *
     * @param string configuration key
     * @param string configuration value
     * @param string configuration namespace (default is 'conf')
     */
    public function put($key, $value) {
        $secured_value = encrypt($value);
        $configurationManager = new self();
        if(isset($this->confTab[$key])) {
            $configurationManager->change(array('value' => $secured_value), array('key' => $key));
        } else {
            $configurationManager->add($key, $secured_value);
        }
        $this->confTab[$key] = $value;
        unset($_SESSION['configuration']);
    }

    /**
     * Remove configuration value in database with specified key
     * #### Example
     * ```php
     * global $conf; // global var, contain configurations
     * echo $conf->remove('myNewConfigKey'); //delete myNewConfigKey from 'conf' default namespace
     * echo $conf->remove('myNewConfigKey','myCustomPluginConfig'); //delete myNewConfigKey from 'myCustomPluginConfig' namespace
     * ```.
     *
     * @param string configuration key
     * @param string configuration namespace (default is 'conf')
     */
    public function add($key, $value) {
        $config = new self();
        $config->key = $key;
        $config->value = $value;
        $config->save();

        $this->confTab[$key] = $value;
        unset($_SESSION['configuration']);
    }
}
