<?php
/**
 * Define a workflowevent.
 * Un evenement peut etre déclaré (register) puis executé (triiger) et
 * lancement de ce fait tous les workflow attachés a celui ci
 * @author Administrateur
 * @category Plugin
 * @license MIT
 */
class WorkflowEvent extends Entity{
	public $id;
	public $slug; //Slug (Texte)
	public $workflow; //Workflow (Entier)
	const EVENT_CRON = 'cron';
	protected $TABLE_NAME = 'workflow_workflow_event';
	public $fields = array(
		'id' => 'key',
		'slug' => 'string',
		'workflow' => array('type'=>'int','link'=>'plugin/workflow/Workflow.class.php')
	);



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

	//Renvois les événements (par défaut et plugin) en fonction du slug fournis ou du type de workflow compatibles
    public static function events($slug = null,$type=null,$getContext = false){
		//Récuperation des événements plugins et par défaut
		$events = array();
		Plugin::callHook("workflow_event",array(&$events) );
		//Si le type est précisé, on ne retourne que les evenements qui correspondent
		if(isset($type)){
			foreach ($events as $key => $event) {
				if($event['type'] != $type) unset($events[$key]);
			}
		}
		if(!isset($slug)) return $events;

		//On ne retourne que les evenements et pas les autres infos fournies dans la déclaration de l'evenemtn (register)
		foreach ($events as $eventGroup) {
			foreach ($eventGroup['events'] as $currentSlug=>$event) {
				if($currentSlug == $slug){
					if($getContext) return $eventGroup;
					return array(
						'label' => $event,
						'type' =>$eventGroup['type']
					);
				}
			}
		}

		return  array(
			'label' => 'Non définit',
			'type' => Workflow::TYPE_GLOBAL
		);
	}





	public static function registerEntity($file,$options = array()){
		require_once($file);
		$class = str_replace('.class.php','',basename($file));
		$plugin = basename(dirname($file));
		$slug = strtolower($plugin.'-'.$class);
		$instance = new $class();
		$fields = array();

		foreach ($instance->fields as $field => $type) {
			if(isset($options['fields-remove']) && in_array($field, $options['fields-remove'])) continue;
            if(!is_array($type)) $type = array('type'=>$type,'column'=>$field);
            if(!isset( $type['column'] )) $type['column'] = $field;
            $label = isset($type['label'])? $type['label']:$field;
            $fields[$field] = array('label'=>$label,'type'=>$type['type']);
        }

		return array(
			'type' => Workflow::TYPE_ENTITY,
			'entity' => array(
				'label' => $class::entityLabel(),
				'file' => $file,
				'class' => $class,
				'slug' => $slug,
				'fields' => $fields
			),
			'events' => array(
				$slug.'-create' => 'A la création',
				$slug.'-update' => 'A la modification',
				$slug.'-delete' => 'A la suppression'
			)
		);
	}

	public static function registerList($file,$options = array()){
		require_once($file);
		$class = str_replace('.class.php','',basename($file));
		$plugin = basename(dirname($file));
		$slug = strtolower($plugin.'-'.$class);
		$instance = new $class();
		$fields = array();

		foreach ($instance->fields as $field => $type) {
			if(isset($options['fields-remove']) && in_array($field, $options['fields-remove'])) continue;
            if(!is_array($type)) $type = array('type'=>$type,'column'=>$field);
            if(!isset( $type['column'] )) $type['column'] = $field;
            $label = isset($type['label'])? $type['label']:$field;
            $fields[$field] = array('label'=>$label,'type'=>$type['type']);
        }

        $options = array_merge(array('events'=>array()),$options);

		return array(
			'type' => Workflow::TYPE_LIST,
			'list' => function(){
				require_once($file);
				return $class::loadAll();
			},
			'entity' => array(
				'label' => $class::entityLabel(),
				'file' => $file,
				'class' => $class,
				'slug' => $slug,
				'fields' => $fields
			),
			'events' => $options['events']
		);
	}


	//lancer un evenement en fonction de son slug et des parametres fournis lors du lancement
	public static function trigger($slug,$parameters = array(),$workflow = null){
		require_once(__DIR__.SLASH.'Workflow.class.php');

		$causes = Workflow::causes();
		$logs = '';
		$where = array('slug'=>$slug);
		if(isset($workflow)) $where['workflow'] = $workflow;

		//continue l'execution du workflow même si le navigateur se déconnecte
		ignore_user_abort(true);
		set_time_limit(0);

		//Récuperation des workflows lié a cet évenement
		foreach(self::loadAll($where, null, null,  array('*'), 1) as $event){
			//récuperation du workflow
			$workflow = $event->join('workflow');
			//Ajout des infos de l'évenement au tableau des parametres utilisé par les causes/effet
			$parameters['event'] = $event->toArray();

			$eventType = WorkflowEvent::events($event->slug,null,true);

			if($eventType['type'] == Workflow::TYPE_LIST && isset($eventType['list'])){
				$parameters['list'] = $eventType['list']();
			}

			//Lancement du workflow concerné (on lui donne les type de causes possible pour des raison de perfs)
			$logs = $workflow->run($causes,$parameters);
			//Ajout des résultats du lancement à l'historique du workflow
			$history = new History();
			$history->scope = 'workflow';
			$history->uid = $workflow->id;
			$history->comment = implode('<br/>',$logs);
			$history->icon = History::TYPE_COMMENT;
			$history->save();
		}

		return $logs;
	}

}
?>