Location: PHPKode > projects > Sierra-php PHP Application Framework > sierra/lib/workflow/SRA_WorkflowTask.php
<?php
// {{{ Header
/*
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | SIERRA : PHP Application Framework  http://code.google.com/p/sierra-php |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 | Copyright 2005 Jason Read                                               |
 |                                                                         |
 | Licensed under the Apache License, Version 2.0 (the "License");         |
 | you may not use this file except in compliance with the License.        |
 | You may obtain a copy of the License at                                 |
 |                                                                         |
 |     http://www.apache.org/licenses/LICENSE-2.0                          |
 |                                                                         |
 | Unless required by applicable law or agreed to in writing, software     |
 | distributed under the License is distributed on an "AS IS" BASIS,       |
 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.|
 | See the License for the specific language governing permissions and     |
 | limitations under the License.                                          |
 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
 */
// }}}

// {{{ Imports
require_once('model/SRA_AttributeValidator.php');
require_once('workflow/SRA_WorkflowDecision.php');
// }}}

// {{{ Constants
/**
 * identifies that the task due date should be relative to the current date
 * @type int
 */
define('SRA_WORKFLOW_TASK_DUE_DATE_REL_CUR', 0);

/**
 * identifies that the task due date should be relative to the wf start date
 * @type int
 */
define('SRA_WORKFLOW_TASK_DUE_DATE_REL_WF_START', 1);

/**
 * identifies that the task due date should be relative to the wf due date
 * @type int
 */
define('SRA_WORKFLOW_TASK_DUE_DATE_REL_WF_DUE_DATE', 2);

/**
 * identifies that the task due date should be relative to the step due date
 * @type int
 */
define('SRA_WORKFLOW_TASK_DUE_DATE_REL_STEP_DUE_DATE', 3);
// }}}

// {{{ SRA_WorkflowTask
/**
 * defines a unit of work within a workflow. tasks are created within the 
 * context of a workflow "step". tasks can be either interactive or 
 * auto-completed. auto-completed tasks do not require any user intervention in 
 * order to complete while interactive tasks do. interactive tasks are those 
 * tasks containing a "view" and those flagged as "interactive". the unit of 
 * work performed by a task is either the "eval*" PHP code or the "view" or 
 * the user "check off" when it is designated "interactive". therefore, at least 
 * one of those values must exist for each task
 * 
 * @author  Jason Read <hide@address.com>
 * @package sierra.workflow
 */
class SRA_WorkflowTask {
  // {{{ Attributes
  // public attributes
  
  /**
	 * if an entity pertains to this task, setting this flag to true will result 
   * in that entity being inserted/updated upon successful completion of the 
   * task (if interactive, otherwise performed when the task is initialized)
	 * @type boolean
	 */
	var $commit;
  
  /**
	 * the identifier of another workflow to connect to when this task is 
   * completed. NOTE: the connect-to workflow will be initialized using the same 
   * params as this task
	 * @type string
	 */
	var $connectTo;
  
  /**
   * constraint group for this task. used to determine whether or not this task 
   * is added to its step at the time that it is created
   * @type SRA_WorkflowConstraintGroup
   */
  var $constraintGroup;
  
  /**
   * the description of this task as determined by the config "resource-descr"
   * @type string
   */
  var $desciption;
  
  /**
   * an explicit date or relative due-date expression. explicit dates should be 
   * entered in the format "YYYY-MM-DD HH:MM:SS" (time is optional). relative 
   * expressions utilize the same format except that any of the date values 
   * (YYYY, MM, DD, HH, MM, or SS) may be replaced with a relative modifier in 
   * the format "+n" where n is the increase from the current timestamp. For 
   * example, to specify the 1st of the following month, the dueDate would be: 
   * "+0-+1-01" - where +0 signifies the current year, and +1 signifies the 
   * following month. if the current month was december (12), the following 
   * month will be January and the year will be incremented automatically. 
   * Another example: to specify exactly one week from the current time, 
   * dueDate would be "+0-+0-+7" - where the first +0 signifies the current 
   * year, the second +0 signifies the current month, and +7 signifies 7 days 
   * from the current date. month and year rollovers resulting in the 1 week 
   * jump will be automatically applied (for example, if the action was created 
   * on 12/28). negative increments can be applied by enclosing the increment 
   * value "n" in parenthesis. for example, to specify 1 month minus 1 week from 
   * the current date, dueDate would be: "+0-+1-+(7)". the increment value "n" 
   * may also be an action or workflow parameter using the format "${param name}
   * @type string
   */
  var $dueDate;
  
  /**
   * if the task dueDate is relative, this attribute determines what it is 
   * relative to. the following options are available:
   *  0: the date/time when the task was invoked (default)
   *  1: the workflow start date
   *  2: the workflow due date (should not be greater)
   *  3: the task step due date (should not be greater)
   * the SRA_WORKFLOW_TASK_DUE_DATE_REL_* constants are defined for these 
   * options
   * @type int
   */
  var $dueDateRel;
  
  /**
   * see SRA_WorkflowStep::entity - when the task pertains to a step, this will 
   * override the step entity. when the task pertains to the workflow, this 
   * attribute is required if the task involves an entity
   * @type string
   */
  var $entity;
  
  /**
   * see SRA_WorkflowStep::entityId
   * @type string
   */
  var $entityId;
  
  /**
   * see SRA_WorkflowStep::entityPk
   * @type string
   */
  var $entityPk;
  
  /**
   * a PHP code block that should be invoked for a particular task. this code 
   * segment will have access to any current workflow entities using the 
   * entityId as the variable name as well as to the SraWorkflow, 
   * SraWorkflowStep and SraWorkflowTask instances using the variable names 
   * $workflow, $step (when applicable) and $task. This code block MUST return 
   * TRUE, or the workflow will enter an error state. this code is invoked AFTER 
   * the task is completed successfully (if a "view" is defined for the task, 
   * this would be when that view is completed/confirmed)
   * @type string
   */
  var $evalAfter;
  
  /**
   * Like "evalAfter", "evalBefore" also specifies a PHP code block that should 
   * be invoked for a particular task. however, this code is invoked at the same 
   * time that the task is created. the difference between "evalBefore" and 
   * "evalAfter" is only applicable to interractive tasks (tasks with associated 
   * views)
   * @type string
   */
  var $evalBefore;
  
  /**
   * is this task interactive? use this to create a "check-off" task... a task 
   * that a user must simply check of having completed. tasks with a "view" are 
   * interactive but in a different way because the view must be displayed and 
   * entity optionally validated (when "validate" is specified) in order for 
   * them to be considered completed. only the owner of this task, or the owner 
   * of the enclosing step, or the owner of the enclosing workflow may 
   * "check off" a task. this attribute will be automatically set to TRUE if a 
   * "view" is assigned to this task
   * @type boolean
   */
  var $interactive;
  
  /**
   * the name of this task as determined by the config "resource"
   * @type string
   */
  var $name;
  
  /**
	 * should notifications be sent for this task? this value overrides the 
   * enclosing workflow or step 'notify' flag
	 * @type boolean
	 */
	var $notify;
  
  /**
   * whether or not all participants in this workflow (past and present) should 
   * be notified (using the "notify-tpl") when this task is created. the default 
   * behavior is to only notify the new owner(s) of the task
   * @type boolean
   */
  var $notifyAll;
  
  /**
   * whether or not notifications should be sent when this task is created 
   * regardless of whether or not it is interactive. the default value for this 
   * attribute is FALSE, meaning notifications will only be sent for the task if 
   * it is interactive
   * @type boolean
   */
  var $notifyAlways;
  
  /**
   * if "notifyAttachView" is specified, this attribute must also be provided 
   * specifying what to name the attached file. this value may contain 
   * workflow/step parameters in the format ${param name}. it may also contain 
   * entity attributes in the format {$attribute name} (after being parsed for 
   * parameter names, it will be passed through the VO parseString method of 
   * the enclosing step entity)
   * @type string
   */
  var $notifyAttachName;
  
  /**
   * an entity view that should be attached to the email notification sent when 
   * this task is invoked. this view may be either text, pdf or some other 
   * output format. it will be output directly to a file, renamed to 
   * "notifyAttachName" and attached to the email notification(s)
   * @type string
   */
  var $notifyAttachView;
  
  /**
	 * overrides the default step/workflow value for this attribute
	 * @type string
	 */
	var $notifyBcc;
  
  /**
	 * overrides the default step/workflow value for this attribute
	 * @type string
	 */
	var $notifyCc;
  
  /**
	 * overrides the default step/workflow value for this attribute
	 * @type string
	 */
	var $notifyFrom;
  
  /**
	 * additional email addresses that should be notified when this task is 
   * created. these will be notified regardless of whether or not other 
   * notifications are being sent. the $wfUser template variable will NOT be 
   * present for these recipients. if the task is not interactive, 
   * "notifyAlways" MUST be true in order for notifications to be sent to these 
   * recipients
	 * @type array
	 */
	var $notifyRecipients;
  
  /**
	 * whether or not ONLY the "notifyRecipients" should be sent notifications for 
   * this task
	 * @type boolean
	 */
	var $notifyRecipientsOnly;

  /**
   * overrides the default step/workflow value for this attribute
   * @type string
   */
  var $notifySubject;
  
  /**
   * overrides the default step/workflow value for this attribute
   * @type string
   */
  var $notifyTpl;
  
  /**
   * overrides the default step/workflow value for this attribute
   * @type string
   */
  var $notifyTplHtml;
  
  /**
   * the label resource for this task
   * @type string
   */
  var $resource;
  
  /**
   * the resources used to provide a description for this task
   * @type string
   */
  var $resourceDesc;
  
  /**
   * if this task is the responsibility of a user other than the owner of the 
   * enclosing step, this attribute may specify a "role" or group of users that 
   * it should be assigned to. all users within that role will be notified, be 
   * assigned responsibility for and have equal access to complete the task. 
   * this attribute may also reference a workflow parameter using the format 
   * ${param name}
   * @type string
   */
  var $role;
  
  /**
   * if this task is the responsibility of a user other than the owner of the 
   * enclosing step, this attribute may specify the identifier of that user. 
   * this user will be notified and given responsibility to complete this task 
   * when it is created. this attribute may also reference a workflow parameter 
   * using the format ${param name}
   * @type mixed
   */
  var $user;
  
  /**
   * if this task includes a "view" requiring user input, this attribute may be 
   * specified identifying a validation constraint that should be applied to the 
   * entity after the "view" has been processed. if this validation passes 
   * successfully, the task will be considered completed, otherwise, the task 
   * will loop back on itself with the validation errors assigned to it. if this 
   * attribute is set to "1", then the entity validation will be invoked 
   * (without a specific validation identifier)
   * @type string
   */
  var $validate;
  
  /**
   * a space separated list of names of attributes that should be excluded from 
   * the entity validation. if a validation error is returned for one of these 
   * attributes, validation failure will not be triggered
   * @type array
   */
  var $validateIgnore;
  
  /**
   * if the enclosing step has an entity assigned (based on the "entityId" 
   * attribute) this attribute may be specified identifying the entity view that 
   * this task should display to the user. if this view requires input from the 
   * user, a "validate" identifier may also be specified determining the 
   * validation on that input that should occur prior to the task being 
   * completed. tasks with a "view" assigned are always interactive. multiple 
   * views can be specified each separated by a space (each view will be 
   * rendered an concatenated starting with the first)
   * @type string
   */
  var $view;
	
  // }}}
  
  // {{{ Operations
  // constructor(s)
	// {{{ SRA_WorkflowTask
	/**
	 * parses the workflow configuration data and sets the appropriate instance 
   * variables. if there is a problem with the configuration, the instance 
   * variable "err" will be assigned to an appropriate error object (the error 
   * will be logged)
   * @param array $conf the configuration to parse
   * @param SRA_Workflow $workflow the workflow this task pertains to
   * @param SRA_WorkflowStep $step the step that this task pertains to (if 
   * applicable)
   * @access  public
	 */
	function SRA_WorkflowTask($conf, & $workflow, & $step) {
    if ($step) {
      $owner =& $step;
    }
    else {
      $owner =& $workflow;
    }
    
    $this->commit = isset($conf['attributes']['commit']) && $conf['attributes']['commit'] == '1';
    $this->connectTo = isset($conf['attributes']['connect-to']) ? $conf['attributes']['connect-to'] : NULL;
    if ($this->connectTo && !SRA_Workflow::isValid(SRA_WorkflowManager::getWorkflowSetup($this->connectTo))) {
      $err =  'connect-to "' . $this->connectTo . '" is not valid';
    }
    if (!$err && isset($conf['attributes']['resource-descr']) && !($this->description = $workflow->resources->getString($conf['attributes']['resource-descr']))) {
      $err = 'resource-descr "' . $conf['attributes']['resource-descr'] . '" is not valid';
    }
    else if (isset($conf['attributes']['resource-descr'])) {
      $this->resourceDescr = $conf['attributes']['resource-descr'];
    }
    $this->dueDate = isset($conf['attributes']['due-date']) ? $conf['attributes']['due-date'] : NULL;
    $this->dueDateRel = isset($conf['attributes']['due-date-rel']) ? $conf['attributes']['due-date-rel'] : SRA_WORKFLOW_TASK_DUE_DATE_REL_CUR;
    $this->entity = isset($conf['attributes']['entity']) ? $conf['attributes']['entity'] : ($step ? $step->entity : NULL);
    $this->entityId = isset($conf['attributes']['entity-id']) ? $conf['attributes']['entity-id'] : ($step ? $step->entityId : NULL);
    $this->entityPk = isset($conf['attributes']['entity-pk']) ? $conf['attributes']['entity-pk'] : ($step ? $step->entityPk : NULL);
    if (!$err && $this->entity && !$this->entityId) {
      $err = 'no entity id specified for entity ' . $this->entity;
    }
    $this->evalAfter = isset($conf['eval-after'][0]) ? $conf['eval-after'][0]['xml_value'] : (isset($conf['eval-after'][1]) ? $conf['eval-after'][1]['xml_value'] : NULL);
    $this->evalBefore = isset($conf['eval-before'][0]) ? $conf['eval-before'][0]['xml_value'] : (isset($conf['eval-before'][1]) ? $conf['eval-before'][1]['xml_value'] : (isset($conf['eval-before'][2]) ? $conf['eval-before'][2]['xml_value'] : NULL));
    $this->interactive = isset($conf['attributes']['view']) || (isset($conf['attributes']['interactive']) && $conf['attributes']['interactive'] == '1') ? TRUE : FALSE;
    if (!$err && (!isset($conf['attributes']['resource']) || !($this->name = $workflow->resources->getString($conf['attributes']['resource'])))) {
      $err = 'resource "' . $conf['attributes']['resource'] . '" is not valid';
    }
    else {
      $this->resource = $conf['attributes']['resource'];
    }
    $this->notify = isset($conf['attributes']['notify']) ? ($conf['attributes']['notify'] == '1' ? TRUE : FALSE) : $owner->notify;
    $this->notifyAll = isset($conf['attributes']['notify-all']) && $conf['attributes']['notify-all'] == '1';
    $this->notifyAlways = isset($conf['attributes']['notify-always']) && $conf['attributes']['notify-always'] == '1';
    $this->notifyAttachName = isset($conf['attributes']['notify-att-name']) ? $conf['attributes']['notify-att-name'] : NULL;
    $this->notifyAttachView = isset($conf['attributes']['notify-att-view']) ? $conf['attributes']['notify-att-view'] : NULL;
    if ($this->notifyAttachView && !$this->entityId) {
      $err = 'notify attach view ' . $this->notifyAttachView . ' cannot be specified without a step entity id';
    }
    $this->notifyBcc = isset($conf['attributes']['notify-bcc']) ? $conf['attributes']['notify-bcc'] : NULL;
    $this->notifyCc = isset($conf['attributes']['notify-cc']) ? $conf['attributes']['notify-cc'] : NULL;
    $this->notifyFrom = isset($conf['attributes']['notify-from']) ? $conf['attributes']['notify-from'] : $owner->notifyFrom;
    $this->notifyRecipients = isset($conf['attributes']['notify-recipients']) ? explode(' ', $conf['attributes']['notify-recipients']) : NULL;
    $this->notifyRecipientsOnly = isset($conf['attributes']['notify-recipients-only']) && $conf['attributes']['notify-recipients-only'] == '1';
    if (!$err && $this->notifyRecipients) {
      foreach($this->notifyRecipients as $email) {
        if (!SRA_AttributeValidator::email($email)) {
          $err = 'the notify-recipient "' . $email . '" is not valid';
          break;
        }
      }
    }
    $this->notifySubject = isset($conf['attributes']['notify-subject']) ? $conf['attributes']['notify-subject'] : $owner->notifySubject;
    if (!$err && $this->notifySubject && !($this->notifySubject = $workflow->resources->getString($this->notifySubject))) {
      $err = 'notify subject "' . $this->notifySubject . '" is not valid';
    }
    $tpl =& SRA_Controller::getAppTemplate();
    $this->notifyTpl = isset($conf['attributes']['notify-tpl']) ? $conf['attributes']['notify-tpl'] : NULL;
    if (!$err && $this->notifyTpl && !$tpl->validateTemplate($this->notifyTpl)) {
      $err = 'notify template "' . $this->notifyTpl . '" is not valid';
    }
    $this->notifyTplHtml = isset($conf['attributes']['notify-tpl-html']) ? $conf['attributes']['notify-tpl-html'] : NULL;
    if (!$err && $this->notifyTplHtml && !$tpl->validateTemplate($this->notifyTplHtml)) {
      $err = 'notify html template "' . $this->notifyTplHtml . '" is not valid';
    }
    
    $this->role = isset($conf['attributes']['role']) ? $conf['attributes']['role'] : (!isset($conf['attributes']['user']) && $step ? $step->role : NULL);
    if ($this->role && !$workflow->roleEntity) {
      $err = 'role cannot be specified when there is no role entity assigned in the workflow';
    }
    $this->user = isset($conf['attributes']['user']) ? $conf['attributes']['user'] : (!isset($conf['attributes']['role']) && $step ? $step->user : NULL);
    $this->validate = isset($conf['attributes']['validate']) ? explode(' ', $conf['attributes']['validate']) : NULL;
    $this->validateIgnore = isset($conf['attributes']['validate-ignore']) ? explode(' ', $conf['attributes']['validate-ignore']) : NULL;
    $this->view = isset($conf['attributes']['view']) ? $conf['attributes']['view'] : NULL;
    
    if ($this->view && !$this->entityId) {
      $err = 'view ' . $this->view . ' cannot be specified without an entityId';
    }
    
    if (!$err && isset($conf['constraint-group'][0]) && !SRA_WorkflowConstraintGroup::isValid($this->constraintGroup = new SRA_WorkflowConstraintGroup($conf['constraint-group'][0], $workflow, $this))) {
      $err = "constraint group produced error";
    }
    
    if ($err) { $this->err = SRA_Error::logError('SRA_WorkflowTask::SRA_WorkflowTask: ' . $this->id . ' Failed - ' . $err, __FILE__, __LINE__); }
	}
	// }}}
	
	
	// Static methods
	
	// {{{ isValid
	/**
	 * Static method that returns true if the object parameter is a SRA_WorkflowTask object.
	 *
	 * @param  Object $object The object to validate
	 * @access	public
	 * @return	boolean
	 */
	function isValid( & $object ) {
		return (is_object($object) && (!isset($object->err) || !SRA_Error::isError($object->err)) && strtolower(get_class($object)) == 'sra_workflowtask');
	}
	// }}}
	
  
  // private operations

  
}
// }}}
?>
Return current item: Sierra-php PHP Application Framework