<?php
/**
 * Base class for standard configuration
 * management that can be used as the base
 * for sub-plugin configuration array management
 *
 * @author jason.xie@victheme.com
 *
 */
abstract class VTCore_Wordpress_Models_Config {

  protected $options;
  protected $database;
  protected $filter;
  protected $loadFunction = 'get_option';
  protected $saveFunction = 'update_option';
  protected $deleteFunction = 'delete_option';


  /**
   * Main Construct method.
   * @param array $options
   */
  public function __construct($options = array()) {
    $this->register($options);
  }



  /**
   * Child class must extend this method
   * to register their object information
   *
   * @param array $options
   * @return VTCore_Wordpress_Config_Base
   */
  protected function register(array $options) {

    // Define the database name
    $this->database = '';

    // Set the default options
    $this->options = array();

    // Set the hookable filter name
    $this->filter = '';

    // Merge the user supplied options
    $this->merge($options);

    // Apply the hookable filter
    $this->filter();

    // Inject from database
    $this->load();

    return $this;
  }


  public function extract() {
    return $this->options;
  }


  public function set(array $value) {
    $this->options = $value;
    return $this;
  }


  public function reset() {
    $this->options = array();
    return $this;
  }


  public function add($keys, $value) {
    VTCore_Utility::setArrayValueKeys($this->options, $keys, $value);
    return $this;
  }


  public function mutate($keys, $value) {
    return $this->add($keys, $value);
  }


  public function change($keys, $value) {
    return $this->add($keys, $value);
  }


  public function get($keys, $sanitize = false) {
    $this->result = VTCore_Utility::getArrayValueKeys($this->options, $keys);

    if ($sanitize && $this->result) {
      if (is_array($this->result)) {
        $this->sanitizeType = $sanitize;
        array_walk_recursive($this->result, array($this, 'sanitizeRecursive'));
      }
      else {
        $this->result = $this->sanitize($this->result, $sanitize);
      }
    }

    return $this->result;
  }

  protected function sanitizeRecursive(&$value, $key) {
    $value = $this->sanitize($value, $this->sanitizeType);
  }

  
  public function sanitize($value, $type = 'attr') {
    switch ($type) {
      case 'attr' :
        $value = esc_attr($value);
        break;
      case 'url' :
        $value = esc_url($value);
        break;
      case 'js' :
        $value = esc_js($value);
        break;
      case 'html' :
        $value = esc_html($value);
        break;
      case 'post' :
        $value = wp_kses_post($value);
        break;
    }
    
    return $value;
  }


  public function remove($keys) {
    VTCore_Utility::removeArrayValueKeys($this->options, $keys);
    return $this;
  }


  public function merge($options) {
    if (is_array($options)) {
      $this->options = VTCore_Utility::arrayMergeRecursiveDistinct($options, $this->options);
    }
    else {
      $this->options = $options;
    }
    return $this;
  }


  public function insert($key, $options) {
    $this->options[$key] = $options;

    return $this;
  }


  public function load() {
    if ($this->database) {
      $function = $this->loadFunction;
      $this->merge($function($this->database, array()));
    }
    return $this;
  }


  public function save() {
    if ($this->database) {
      $function = $this->saveFunction;
      $function($this->database, $this->options);
    }
    return $this;
  }


  public function delete() {
    if ($this->database) {
      $function = $this->deleteFunction;
      $function($this->database);
    }
    return $this;
  }


  public function filter() {
    if ($this->filter) {
      $this->options = apply_filters($this->filter, $this->options);
    }
    return $this;
  }

}