<?php
/**
 * Define a dynamicfield.
 * @author Charles DUBOIS
 * @category Plugin
 * @license MIT
 */
class DynamicField extends Entity{

	public $id;
	public $slug; //Slug (Texte)
	public $type; //Type (Liste)
	public $label; //Libellé (Texte)
	public $mandatory; //Obligatoire (Booléen)
	public $readonly; //Lecture seule (Booléen)
	public $sort; //Ordre (Entier)
	public $default; //Valeur par défaut (Texte)
	public $description; //Description (Texte)
	public $meta; //Meta (Texte Long)
	public $form; //Formulaire (int)
	public $row; //Line (int)
	public $column; //Colonne (int)
	public $state; //Etat (Texte)

	protected $TABLE_NAME = 'dynamicform_field';
	public $entityLabel = 'Formulaire';
	public $fields = array(
		'id' => 'key',
		'slug' => array('type'=>'string', 'label' => 'Slug'),
		'type' => array('type'=>'string', 'label' => 'Type'),
		'label' => array('type'=>'string', 'label' => 'Libellé'),
		'mandatory' => array('type'=>'boolean', 'label' => 'Obligatoire'),
		'readonly' => array('type'=>'boolean', 'label' => 'Lecture seule'),
		'default' => array('type'=>'string', 'label' => 'Valeur par défaut'),
		'description' => array('type'=>'string', 'label' => 'Description'),
		'meta' => array('type'=>'longstring', 'label' => 'Meta'),
		'state' => array('type'=>'string', 'label' => 'Etat'),
		'form' => array('type'=>'string', 'label' => 'Formulaire','link'=>'plugin/dynamicform/DynamicForm.class.php'),
		'row' => array('type'=>'string', 'label' => 'Ligne'),
		'sort' => array('type'=>'int', 'label' => 'Ordre'),
		'column' => array('type'=>'string', 'label' => 'Colonne')
	);



	//Colonnes indexées
	public $indexes = array('form');


	/**
	 * Enregistre un champ dynamique en fonction de son type (fieldType) et de ses options de contexte (firm, scope, uid)
	 * @param <Array> tableau de paramètres composé de :
	 * $params['field'] le champ dynamique à afficher format array provenant de l'objet dynamicField
	 * $params['value'] la valeur du champ dynamique
	 * $params['types'] les fieldType::available() passés en paramètres pour question de perf
	 * $params['options'] les options contextuelles de mise en page, firm, scope, uid...
	 */
	public static function record($params){
		global $myFirm;
		Plugin::need('dynamicform/DynamicValue');
		if(!isset($params['field'])) throw new Exception('Champ non identifié');
		if(!isset($params['value'])) throw new Exception('Valeur non identifiée');
		if(!isset($params['options'])) throw new Exception('Options du champ non identifiées');
		$types = isset($params['types']) ? $params['types'] : FieldType::available();

		$type = $types[$params['field']->type];

		$value = DynamicValue::load(array_merge(array('field'=>$params['field']->id,'firm'=>$myFirm->id),$params['options']));
		$value = $value ? $value : new DynamicValue();

		$valueTable = DynamicValue::tableName();
		foreach($params['field']->foreign() as $key => $val) {
			if(strpos($key, $valueTable)===false) continue;
			$key = str_replace($valueTable.'_join_', '', $key);
			if(($key == 'created' || $key == 'creator')  &&  empty($val)) continue;
			$value->$key = $val;
		}

		//Si une valeur existe déja en base
		$value->firm = $myFirm->id;
		if(isset($params['options']['firm'])) $value->firm = $params['options']['firm'];
		if(!empty($params['options']['scope'])) $value->scope = $params['options']['scope'];
		if(!empty($params['options']['uid'])) $value->uid = $params['options']['uid'];

		$value->field = $params['field']->id;
		$value->value = $params['value'];

		try{
			//Si necessaire, le type transforme/verifie la valeur avant enregistrement
			//(ex: le mdp est crypté avant save)
			if(property_exists($type,"onSave")){
				$method = $type->onSave;
				$value->value = $method($value->value,$params);
			}
			if(!is_null($value->value))
				$value->save();

		}catch(Exception $e){
			throw new Exception("Champ ".$params['field']->label." : ".$e->getMessage());
		}
	}

	/**
	 * Affiche un champ dynamique en fonction de son type (fieldType) et de ses options de contexte (firm, scope, uid)
	 * @param <Array> tableau de paramètres composé de :
	 * $params['field'] le champ dynamique à afficher format array provenant de l'objet dynamicField
	 * $params['value'] la valeur du champ dynamique
	 * $params['types'] les fieldType::available() passés en paramètres pour question de perf
	 * $params['options'] les options contextuelles de mise en page, firm, scope, uid...
	 * @return <String> tableau des options de ciblage des champs à récupérer
	 */
	public static function show($params){
		global $myFirm;

		$params['options'] = isset($params['options']) ? $params['options'] : array();
		$types = !isset($params['types']) || is_null($params['types']) ? FieldType::available() : $params['types'];
		$value = isset($params['value']) ? $params['value'] : '';
		$field = $params['field'];

		$options = array_merge(array(
			'label' => 'block', // inline (input group) / block (label classique) / none (pas de label)
			'legend' => 'block', // block (span text muted) / none (pas de label)
			'scope' => '', // ex : client
			'uid' => '', // ex : 12 
			'firm' => $myFirm->id // ex : 1 
		),$params['options']);

		$field['options'] = $options;

		$stream = '';

		if(is_string($field['type']))
			$field['type'] = $types[$field['type']];

		$type = $field['type'];

		$field['type'] = $field['type']->slug;


		//On remplit les metas quoi qu'il en soit pour pouvoir récupérer toutes les valeurs d'un dictionary / list
		if(isset($field['meta']) && !empty($field['meta'])){
			$meta = json_decode(base64_decode($field['meta']),true);
			if(is_array($meta)){
				foreach($meta as $index=>$item)
					$field['attributes']['data-'.$index] = $item;
			}
		}

		//On remplit avec la valeurs existant en bdd si existante
		if(!empty($value)){
			$field['value'] = $value;
			if(property_exists($type,"onLoad")){
				$method = $type->onLoad;
				$field['value'] = $method($field['value']);
			}
		}

		$field['id'] = $field['slug'];
		if(isset($field['mandatory']) && $field['mandatory'] == 1) $field['required'] = true;
		if(isset($field['readonly']) && $field['readonly'] == 1) $field['attributes'] = array('readonly'=>'"readonly"');

		if(!empty($options['input-class'])){
		    if(!isset($field['attributes']['class'])) $field['attributes']['class'] = '';
		    $field['attributes']['class'] = $field['attributes']['class'].' '.$options['input-class'];
		}

		$line = FieldType::toHtml($field,$types);

		if($options['label'] == 'block' && !empty($line['label'])) $stream .= '<label>'.$line['label'].'</label>';
		if($options['legend'] == 'block' && !empty($line['legend'])) $stream .= '<span class="text-muted">'.$line['legend'].'</span>';
		if($options['label'] == 'inline'){
			$stream .= '<div class="input-group mb-1 '.$options['input-group-class'].'">';
			$stream .= '<div class="input-group-prepend">
		 		<label class="input-group-text" for="'.$field['id'].'">'.$line['label'].'</label>
			</div>';
		}
		$stream .= $line['input'];
		if($options['label'] == 'inline') $stream .= '</div>';

		return $stream;
	}
}
?>