/**
  * Walk through the cloned process and replace the item runner placeholders
  *
  * @param core_kernel_classes_Resource $processDefinition            
  */
 protected function process(core_kernel_classes_Resource $processDefinition)
 {
     $report = new common_report_Report(common_report_Report::TYPE_SUCCESS);
     $activities = wfEngine_models_classes_ProcessDefinitionService::singleton()->getAllActivities($processDefinition);
     foreach ($activities as $activity) {
         $services = wfEngine_models_classes_ActivityService::singleton()->getInteractiveServices($activity);
         foreach ($services as $service) {
             $serviceDefinition = $service->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CALLOFSERVICES_SERVICEDEFINITION));
             if ($serviceDefinition->getUri() == INSTANCE_ITEMCONTAINER_SERVICE) {
                 $item = taoWfTest_models_classes_WfTestService::singleton()->getItemByService($service);
                 if (is_null($item)) {
                     $report->add($this->fail(__('No valid item found for service "%s"', $service->getLabel())));
                 } else {
                     $itemReport = $this->subCompile($item);
                     if ($itemReport->getType() == common_report_Report::TYPE_SUCCESS) {
                         $serviceCall = $itemReport->getData();
                         $storedServiceCall = $serviceCall->toOntology();
                         // remove old service
                         wfEngine_models_classes_InteractiveServiceService::singleton()->deleteInteractiveService($service);
                         $activity->removePropertyValue(new core_kernel_classes_Property(PROPERTY_ACTIVITIES_INTERACTIVESERVICES), $service);
                         // add new service
                         $activity->setPropertyValue(new core_kernel_classes_Property(PROPERTY_ACTIVITIES_INTERACTIVESERVICES), $storedServiceCall);
                     }
                     $report->add($itemReport);
                     if ($itemReport->getType() != common_report_Report::TYPE_SUCCESS) {
                         $report->setType($itemReport->getType());
                     }
                 }
             }
         }
     }
     return $report;
 }
 private function replaceItemRunner(core_kernel_classes_Resource $workflow, $directory)
 {
     $authoringService = wfAuthoring_models_classes_ProcessService::singleton();
     // foreach activity in workflow
     foreach (wfEngine_models_classes_ProcessDefinitionService::singleton()->getAllActivities($workflow) as $activity) {
         foreach (wfEngine_models_classes_ActivityService::singleton()->getInteractiveServices($activity) as $service) {
             $serviceDefinition = $service->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CALLOFSERVICES_SERVICEDEFINITION));
             if ($serviceDefinition->getUri() == self::OLD_ITEMRUNNER_SERVICE) {
                 $this->out('to replace: ' . $service->getLabel());
                 // retrieve item
                 $item = $this->getItem($service);
                 // create service
                 $itemDirectory = $this->createNamedSubDirectory($directory, $activity);
                 $newService = $this->compileItem($item, $itemDirectory);
                 $newService->setLabel($service->getLabel());
                 $activity->removePropertyValue(new core_kernel_classes_Property(PROPERTY_ACTIVITIES_INTERACTIVESERVICES), $service);
                 //delete its related properties
                 $deleted = $authoringService->deleteActualParameters($service);
                 //delete call of service itself
                 $deleted = $service->delete(true);
                 $activity->setPropertyValue(new core_kernel_classes_Property(PROPERTY_ACTIVITIES_INTERACTIVESERVICES), $newService);
             }
         }
         $this->out('done activity: ' . $activity->getLabel());
     }
 }
 public function flatten()
 {
     //clone activities and connectors
     $processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     $activities = $processDefinitionService->getAllActivities($this->processDefinition);
     foreach ($activities as $activity) {
         $this->flattenProcessActivity($activity);
     }
 }
 /**
  * tests initialization
  */
 public function setUp()
 {
     TaoPhpUnitTestRunner::initTest();
     $processDefinitionClass = new core_kernel_classes_Class(CLASS_PROCESS);
     $processDefinition = $processDefinitionClass->createInstance('processForUnitTest', 'created for the unit test of process definition service');
     if ($processDefinition instanceof core_kernel_classes_Resource) {
         $this->processDefinition = $processDefinition;
     } else {
         $this->fail('fail to create a process definition resource');
     }
     $this->authoringService = wfAuthoring_models_classes_ProcessService::singleton();
     $this->service = wfEngine_models_classes_ProcessDefinitionService::singleton();
 }
 public function __construct()
 {
     parent::__construct();
     $this->processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     $processDefinitionUri = urldecode($this->getRequestParameter('processDefinitionUri'));
     if (!empty($processDefinitionUri) && common_Utils::isUri($processDefinitionUri)) {
         $process = new core_kernel_classes_Resource($processDefinitionUri);
         if ($process->hasType(new core_kernel_classes_Class(CLASS_PROCESS))) {
             $this->processDefinition = $process;
         } else {
             $this->setErrorMessage(__('The resource is not a process definition'));
         }
     } else {
         $this->setErrorMessage(__('No process definition uri given'));
     }
 }
 public function authoring($processDefinitionUri)
 {
     // This action is not available when running
     // the service mode !
     $processDefinitionUri = urldecode($processDefinitionUri);
     $userViewData = wfEngine_helpers_UsersHelper::buildCurrentUserForView();
     $this->setData('userViewData', $userViewData);
     $processAuthoringData = array();
     $processAuthoringData['processUri'] = $processDefinitionUri;
     $processAuthoringData['processLabel'] = "Process' variables initialization";
     $processAuthoringData['variables'] = array();
     // Process variables retrieving.
     $processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     $variables = $processDefinitionService->getProcessVars(new core_kernel_classes_Resource($processDefinitionUri));
     foreach ($variables as $key => $variable) {
         $name = $variable['name'];
         $propertyKey = $key;
         //urlencode?
         $processAuthoringData['variables'][] = array('name' => $name, 'key' => $propertyKey);
     }
     $this->setData('processAuthoringData', $processAuthoringData);
     $this->setView('process_initialization.tpl');
 }
 /**
  * Short description of method createProcessExecution
  *
  * @access public
  * @author Somsack Sipasseuth, <*****@*****.**>
  * @param  Resource processDefinition
  * @param  string name
  * @param  string comment
  * @param  array variablesValues
  * @return core_kernel_classes_Resource
  */
 public function createProcessExecution(core_kernel_classes_Resource $processDefinition, $name, $comment = '', $variablesValues = array())
 {
     $returnValue = null;
     common_Logger::i('Creating processexecution for ' . $processDefinition->getUri());
     if (empty($comment)) {
         $comment = "create by processExecutionService on " . date("d-m-Y H:i:s");
     }
     $processInstance = $this->processInstancesClass->createInstance($name, $comment);
     $this->setStatus($processInstance, 'started');
     $processInstance->setPropertyValue($this->processInstancesExecutionOfProp, $processDefinition);
     $processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     $initialActivities = $processDefinitionService->getRootActivities($processDefinition);
     if (!count($initialActivities)) {
         //manage special case of empty process:
         $this->setStatus($processInstance, 'finished');
         $processInstance->setComment('empty process execution of ' . $processDefinition->getLabel());
         $returnValue = $processInstance;
     } else {
         $activityExecutions = array();
         foreach ($initialActivities as $activity) {
             $activityExecution = $this->activityExecutionService->createActivityExecution($activity, $processInstance);
             if (!is_null($activityExecution)) {
                 $activityExecutions[$activityExecution->getUri()] = $activityExecution;
             }
         }
         //foreach first tokens, assign the user input prop values:
         $codes = array();
         foreach ($variablesValues as $uri => $value) {
             // have to skip name because doesnt work like other variables
             if ($uri != RDFS_LABEL && common_Utils::isUri($uri)) {
                 $property = new core_kernel_classes_Property($uri);
                 //assign property values to them:
                 foreach ($activityExecutions as $activityExecution) {
                     $activityExecution->setPropertyValue($property, $value);
                 }
                 //prepare the array of codes to be inserted as the "variables" property of the current token
                 $code = $property->getUniquePropertyValue($this->processVariablesCodeProp);
                 $codes[] = (string) $code;
             }
         }
         //set serialized codes array into variable property:
         $propActivityExecutionVariables = new core_kernel_classes_Property(PROPERTY_ACTIVITY_EXECUTION_VARIABLES);
         foreach ($activityExecutions as $activityExecution) {
             $activityExecution->setPropertyValue($propActivityExecutionVariables, serialize($codes));
         }
         if ($this->setCurrentActivityExecutions($processInstance, $activityExecutions)) {
             $returnValue = $processInstance;
         }
     }
     return $returnValue;
 }
 /**
  * 
  * Main page of wfEngine containning 2 sections : 
  *  - Processes Execution in progress or just started
  *  - Processes Definition user may instanciate
  * 
  * @return void
  */
 public function index()
 {
     //init required services
     $activityExecutionService = wfEngine_models_classes_ActivityExecutionService::singleton();
     $processExecutionService = wfEngine_models_classes_ProcessExecutionService::singleton();
     $processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     $userService = wfEngine_models_classes_UserService::singleton();
     //get current user:
     $currentUser = $userService->getCurrentUser();
     //init variable that save data to be used in the view
     $processViewData = array();
     $userViewData = wfEngine_helpers_UsersHelper::buildCurrentUserForView();
     $this->setData('userViewData', $userViewData);
     //list of available process executions:
     $processInstancesClass = new core_kernel_classes_Class(CLASS_PROCESSINSTANCES);
     $processExecutions = $processInstancesClass->getInstances();
     foreach ($processExecutions as $processExecution) {
         if (!is_null($processExecution) && $processExecution instanceof core_kernel_classes_Resource) {
             try {
                 $processDefinition = $processExecutionService->getExecutionOf($processExecution);
             } catch (wfEngine_models_classes_ProcessExecutionException $e) {
                 $processDefinition = null;
                 $processExecutionService->deleteProcessExecution($processExecution);
                 continue;
             }
             $processStatus = $processExecutionService->getStatus($processExecution);
             if (is_null($processStatus) || !$processStatus instanceof core_kernel_classes_Resource) {
                 continue;
             }
             $currentActivities = array();
             // Bypass ACL Check if possible...
             if ($processStatus->getUri() == INSTANCE_PROCESSSTATUS_FINISHED) {
                 $processViewData[] = array('type' => $processDefinition->getLabel(), 'label' => $processExecution->getLabel(), 'uri' => $processExecution->getUri(), 'activities' => array(array('label' => '', 'uri' => '', 'may_participate' => false, 'finished' => true, 'allowed' => true)), 'status' => $processStatus);
                 continue;
             } else {
                 $currentActivityExecutions = $processExecutionService->getCurrentActivityExecutions($processExecution);
                 foreach ($currentActivityExecutions as $uri => $currentActivityExecution) {
                     $isAllowed = $activityExecutionService->checkAcl($currentActivityExecution, $currentUser, $processExecution);
                     $activityExecFinishedByUser = false;
                     $assignedUser = $activityExecutionService->getActivityExecutionUser($currentActivityExecution);
                     if (!is_null($assignedUser) && $assignedUser->getUri() == $currentUser->getUri()) {
                         $activityExecFinishedByUser = $activityExecutionService->isFinished($currentActivityExecution);
                     }
                     $currentActivity = $activityExecutionService->getExecutionOf($currentActivityExecution);
                     $currentActivities[] = array('label' => $currentActivity->getLabel(), 'uri' => $uri, 'may_participate' => $processStatus->getUri() != INSTANCE_PROCESSSTATUS_FINISHED && $isAllowed, 'finished' => $processStatus->getUri() == INSTANCE_PROCESSSTATUS_FINISHED, 'allowed' => $isAllowed, 'activityEnded' => $activityExecFinishedByUser);
                 }
                 $processViewData[] = array('type' => $processDefinition->getLabel(), 'label' => $processExecution->getLabel(), 'uri' => $processExecution->getUri(), 'activities' => $currentActivities, 'status' => $processStatus);
             }
         }
     }
     //list of available process definitions:
     $processDefinitionClass = new core_kernel_classes_Class(CLASS_PROCESS);
     $availableProcessDefinitions = $processDefinitionClass->getInstances();
     //filter process that can be initialized by the current user (2nd check...)
     $authorizedProcessDefinitions = array();
     foreach ($availableProcessDefinitions as $processDefinition) {
         if ($processDefinitionService->checkAcl($processDefinition, $currentUser)) {
             $authorizedProcessDefinitions[] = $processDefinition;
         }
     }
     $this->setData('availableProcessDefinition', $authorizedProcessDefinitions);
     $this->setData('processViewData', $processViewData);
     $this->setView('main.tpl');
 }
 /**
  * Short description of method getTestItems
  *
  * @access public
  * @author Joel Bout, <*****@*****.**>
  * @param
  *            Resource test
  * @return array
  */
 public function getTestItems(core_kernel_classes_Resource $test)
 {
     $items = array();
     $processService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     // get the associated process, set in the test content property
     $process = $test->getUniquePropertyValue(new core_kernel_classes_Property(TEST_TESTCONTENT_PROP));
     // get list of all activities:
     $activities = $processService->getAllActivities($process);
     $totalNumber = count($activities);
     // find the first one: property isinitial == true (must be only one, if not error) and set as the currentActivity:
     $currentActivity = null;
     foreach ($activities as $activity) {
         $isIntial = $activity->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_ACTIVITIES_ISINITIAL));
         if (!is_null($isIntial) && $isIntial instanceof core_kernel_classes_Resource) {
             if ($isIntial->getUri() == GENERIS_TRUE) {
                 $currentActivity = $activity;
                 break;
             }
         }
     }
     if (is_null($currentActivity)) {
         return $items;
     }
     // start the loop:
     for ($i = 0; $i < $totalNumber; $i++) {
         $item = $this->getItemByActivity($currentActivity);
         if (!is_null($item)) {
             $items[$i] = $item;
         }
         // get its connector (check the type is "sequential) if ok, get the next activity
         $connector = $currentActivity->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_STEP_NEXT));
         $nextActivity = null;
         if (!is_null($connector)) {
             $connectorType = $connector->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_CONNECTORS_TYPE));
             if ($connectorType->getUri() == INSTANCE_TYPEOFCONNECTORS_SEQUENCE) {
                 $nextActivity = $connector->getUniquePropertyValue(new core_kernel_classes_Property(PROPERTY_STEP_NEXT));
             }
         }
         if (!is_null($nextActivity)) {
             $currentActivity = $nextActivity;
         } else {
             if ($i == $totalNumber - 1) {
                 // it is normal, since it is the last activity and item
             } else {
                 throw new common_Exception('the next activity of the connector is not found');
             }
         }
     }
     return $items;
 }
 private function executeProcessCBA($processDefinition, $unitUri, $countryCode, $languageCode, $simulationOptions)
 {
     $activityExecutionService = wfEngine_models_classes_ActivityExecutionService::singleton();
     $processExecutionService = wfEngine_models_classes_ProcessExecutionService::singleton();
     $processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
     $loginProperty = new core_kernel_classes_Property(PROPERTY_USER_LOGIN);
     $processExecName = 'Test Translation Process Execution';
     $processExecComment = 'created by ' . __CLASS__ . '::' . __METHOD__;
     $users = $this->getAuthorizedUsersByCountryLanguage($countryCode, $languageCode);
     if (empty($users)) {
         $this->fail("cannot find the authorized npm, verifier and reconciler for this country-language : {$countryCode}/{$languageCode}");
         return;
     }
     //check that the xliff and vff exist for the given country-language:
     $unit = new core_kernel_classes_Resource($unitUri);
     $vffRevision = 0;
     $xliffRevision = 0;
     $initVariables = array($this->vars['unitUri']->getUri() => $unit->getUri(), $this->vars['countryCode']->getUri() => $countryCode, $this->vars['languageCode']->getUri() => $languageCode, $this->vars['npm']->getUri() => $users['npm'], $this->vars['reconciler']->getUri() => $users['reconciler'], $this->vars['verifier']->getUri() => $users['verifier'], $this->vars['xliff']->getUri() => $xliffRevision, $this->vars['vff']->getUri() => $vffRevision);
     $this->changeUser($this->userLogins['consortium'][1]);
     $this->assertTrue($processDefinitionService->checkAcl($processDefinition, $this->currentUser));
     $processInstance = $processExecutionService->createProcessExecution($processDefinition, $processExecName, $processExecComment, $initVariables);
     $this->assertEqual($processDefinition->getUri(), $processExecutionService->getExecutionOf($processInstance)->getUri());
     $processInstance->setPropertyValue($this->properties[TranslationProcessHelper::getPropertyName('unitUri')], $unit);
     $processInstance->setPropertyValue($this->properties[TranslationProcessHelper::getPropertyName('countryCode')], $countryCode);
     $processInstance->setPropertyValue($this->properties[TranslationProcessHelper::getPropertyName('languageCode')], $languageCode);
     $this->assertTrue($processExecutionService->checkStatus($processInstance, 'started'));
     $this->out(__METHOD__, true);
     $this->processExecutions[$processInstance->getUri()] = $processInstance;
     $currentActivityExecutions = $processExecutionService->getCurrentActivityExecutions($processInstance);
     $this->assertEqual(count($currentActivityExecutions), 1);
     if (isset($simulationOptions['execute']) && $simulationOptions['execute'] === false) {
         return;
     }
     $this->out("<strong>Forward transitions:</strong>", true);
     $nbTranslators = isset($simulationOptions['translations']) && intval($simulationOptions['translations']) >= 1 ? intval($simulationOptions['translations']) : 2;
     //>=1
     $nbLoops = isset($simulationOptions['repeatLoop']) ? intval($simulationOptions['repeatLoop']) : 1;
     $nbBacks = isset($simulationOptions['repeatBack']) ? intval($simulationOptions['repeatBack']) : 0;
     $stopProbability = isset($simulationOptions['stopProbability']) ? floatval($simulationOptions['stopProbability']) : 0;
     $loopsCounter = array();
     $indexActivityTranslate = 2;
     //the index of the activity in the process definition
     $indexActivityOffset = $indexActivityTranslate + $nbTranslators;
     $iterations = $indexActivityOffset + 10;
     $gotoManifest = array($indexActivityOffset + 3 => array($indexActivityOffset + 2, $indexActivityOffset + 4), $indexActivityOffset + 4 => array($indexActivityOffset + 5, $indexActivityOffset + 6), $indexActivityOffset + 5 => array($indexActivityOffset + 4, $indexActivityOffset + 6), $indexActivityOffset + 6 => array($indexActivityOffset + 4, $indexActivityOffset + 7), $indexActivityOffset + 9 => array($indexActivityOffset + 6, $indexActivityOffset + 10), $indexActivityOffset + 10 => array($indexActivityOffset + 9, $indexActivityOffset + 11));
     $this->changeUser($this->userLogins[$countryCode]['NPM']);
     $selectedTranslators = array();
     $i = 1;
     $activityIndex = $i;
     while ($activityIndex <= $iterations) {
         $activityExecutions = $processExecutionService->getCurrentActivityExecutions($processInstance);
         $activityExecution = null;
         $activity = null;
         if ($activityIndex >= $indexActivityTranslate && $activityIndex < $indexActivityOffset) {
             $this->assertEqual(count($activityExecutions), $nbTranslators);
             //parallel translation branch:
             foreach ($activityExecutions as $activityExec) {
                 if (!$activityExecutionService->isFinished($activityExec)) {
                     $activityExecution = $activityExec;
                     break;
                 }
             }
         } else {
             $this->assertEqual(count($activityExecutions), 1);
             $activityExecution = reset($activityExecutions);
         }
         $activity = $activityExecutionService->getExecutionOf($activityExecution);
         $this->out("<strong>Iteration {$i} : activity no{$activityIndex} : " . $activity->getLabel() . "</strong>", true);
         $this->out("current user : "******"' . $this->currentUser->getUri() . '"', true);
         $this->checkAccessControl($activityExecution);
         $currentActivityExecution = null;
         //for loop managements:
         $goto = 0;
         if ($activityIndex >= $indexActivityTranslate && $activityIndex < $indexActivityOffset) {
             //we are executing the translation activity:
             $this->assertFalse(empty($selectedTranslators));
             $theTranslator = null;
             foreach ($selectedTranslators as $translatorUri) {
                 $translator = new core_kernel_classes_Resource($translatorUri);
                 if ($activityExecutionService->checkAcl($activityExecution, $translator)) {
                     $theTranslator = $translator;
                     break;
                 }
             }
             $this->assertNotNull($theTranslator);
             $login = (string) $theTranslator->getUniquePropertyValue($loginProperty);
             $this->assertFalse(empty($login));
             $this->bashCheckAcl($activityExecution, array($login));
             $this->changeUser($login);
             $currentActivityExecution = $this->initCurrentActivityExecution($activityExecution);
             //execute service:
             $this->assertTrue($this->executeServiceTranslate(array('translatorUri' => $theTranslator->getUri())));
         } else {
             //check ACL:
             switch ($activityIndex) {
                 case 1:
                     $login = $this->userLogins[$countryCode]['NPM'];
                     $this->assertFalse(empty($login));
                     $this->bashCheckAcl($activityExecution, array($login));
                     $this->changeUser($login);
                     $currentActivityExecution = $this->initCurrentActivityExecution($activityExecution);
                     //execute service:
                     $translators = $this->getAuthorizedUsersByCountryLanguage($countryCode, $languageCode, $nbTranslators);
                     $selectedTranslators = $translators['translators'];
                     $this->assertTrue($this->executeServiceSelectTranslators($selectedTranslators));
                     break;
                 case $indexActivityOffset:
                 case $indexActivityOffset + 2:
                 case $indexActivityOffset + 7:
                 case $indexActivityOffset + 10:
                     //reconciliation:
                     //correct verification issues:
                     //scoring definition and testing:
                     //country sign off:
                     $login = $this->userLogins[$countryCode][$languageCode]['reconciler'];
                     $this->assertFalse(empty($login));
                     $this->bashCheckAcl($activityExecution, array($login), array_rand($this->users, 5));
                     $this->changeUser($login);
                     $currentActivityExecution = $this->initCurrentActivityExecution($activityExecution);
                     break;
                 case $indexActivityOffset + 1:
                 case $indexActivityOffset + 5:
                 case $indexActivityOffset + 8:
                     //verify translations :
                     ////verification followup :
                     //scoring verification :
                     $login = $this->userLogins[$countryCode][$languageCode]['verifier'];
                     $this->assertFalse(empty($login));
                     $this->bashCheckAcl($activityExecution, array($login), array_rand($this->users, 5));
                     $this->changeUser($login);
                     $currentActivityExecution = $this->initCurrentActivityExecution($activityExecution);
                     break;
                 case $indexActivityOffset + 4:
                     //correct layout, by developers:
                     $developersLogins = $this->userLogins['developer'];
                     $this->bashCheckAcl($activityExecution, $developersLogins);
                     $j = 1;
                     foreach (array_rand($developersLogins, 3) as $k) {
                         $this->out("developer no{$j} " . $developersLogins[$k] . " corrects layout", true);
                         $this->changeUser($developersLogins[$k]);
                         $currentActivityExecution = $this->initCurrentActivityExecution($activityExecution);
                         //check if all developers can access the activity, even after it has been taken:
                         $this->bashCheckAcl($activityExecution, $developersLogins, array_rand($this->users, 8));
                         $j++;
                     }
                     $this->changeUser($developersLogins[array_rand($developersLogins)]);
                     break;
                 case $indexActivityOffset + 3:
                 case $indexActivityOffset + 6:
                 case $indexActivityOffset + 9:
                     //final check:
                     $developersLogins = $this->userLogins['testDeveloper'];
                     $this->bashCheckAcl($activityExecution, $developersLogins);
                     $j = 1;
                     foreach (array_rand($developersLogins, 2) as $k) {
                         $this->out("test developer no{$j} " . $developersLogins[$k] . " makes final check", true);
                         $this->changeUser($developersLogins[$k]);
                         $currentActivityExecution = $this->initCurrentActivityExecution($activityExecution);
                         //check if all developers can access the activity, even after it has been taken:
                         $this->bashCheckAcl($activityExecution, $developersLogins, array_rand($this->users, 5));
                         $j++;
                     }
                     $this->changeUser($developersLogins[array_rand($developersLogins)]);
                     break;
             }
             $loopName = '';
             switch ($activityIndex) {
                 case $indexActivityOffset + 3:
                     if (empty($loopName)) {
                         $loopName = 'TDreview';
                     }
                 case $indexActivityOffset + 4:
                     if (empty($loopName)) {
                         $loopName = 'layoutCheck';
                     }
                 case $indexActivityOffset + 5:
                     if (empty($loopName)) {
                         $loopName = 'opticalCheck';
                     }
                 case $indexActivityOffset + 6:
                     if (empty($loopName)) {
                         $loopName = 'finalCheck';
                     }
                 case $indexActivityOffset + 9:
                     if (empty($loopName)) {
                         $loopName = 'TDsignOff';
                     }
                 case $indexActivityOffset + 10:
                     if (empty($loopName)) {
                         $loopName = 'countrySignOff';
                     }
                     if (!isset($loopsCounter[$loopName])) {
                         //						$loopsCounter = array(); //reinitialize the loops counter
                         $loopsCounter[$loopName] = $nbLoops;
                         $goto = $gotoManifest[$activityIndex][0];
                         //go backward
                         $this->executeServicePositionVariable($loopName, false, "execute service {$activity->getLabel()}");
                     } else {
                         $goto = $gotoManifest[$activityIndex][1];
                         //go forward
                         $this->executeServicePositionVariable($loopName, true, "execute service {$activity->getLabel()}");
                     }
                     break;
             }
         }
         //transition to next activity
         $transitionResult = $processExecutionService->performTransition($processInstance, $currentActivityExecution);
         $goto = intval($goto);
         if ($activityIndex == $indexActivityTranslate + $nbTranslators + 9 && $goto == $indexActivityTranslate + $nbTranslators + 6) {
             //the same users are authorized to execute the current and the next activity (final check and correct layout)
             $this->assertEqual(count($transitionResult), 1);
             $this->assertTrue($processExecutionService->checkStatus($processInstance, 'resumed'));
         } else {
             if ($activityIndex == $iterations && $goto == $iterations + 1) {
                 //test finished:
                 $this->assertEqual(count($transitionResult), 0);
                 $this->assertTrue($processExecutionService->isFinished($processInstance));
             } else {
                 if ($activityIndex >= $indexActivityTranslate && $activityIndex < $indexActivityTranslate + $nbTranslators) {
                     //translate activities:
                     $this->assertFalse($transitionResult);
                     $this->assertTrue($processExecutionService->isPaused($processInstance));
                 } else {
                     $this->assertEqual(count($transitionResult), 0);
                     $this->assertTrue($processExecutionService->isPaused($processInstance));
                 }
             }
         }
         //manage next activity index:
         if ($goto) {
             $activityIndex = $goto;
         } else {
             $activityIndex++;
         }
         //increment iteration counts:
         $i++;
         $this->out("activity status : " . $activityExecutionService->getStatus($currentActivityExecution)->getLabel());
         $this->out("process status : " . $processExecutionService->getStatus($processInstance)->getLabel());
         $rand = rand(0, $iterations);
         $prob = $activityIndex * $stopProbability;
         if ($rand < $prob) {
             $this->out("process instance stopped by probability");
             break;
         }
         if ($i > 30) {
             break;
         }
     }
     $activityExecutionsData = $processExecutionService->getAllActivityExecutions($processInstance);
     //		var_dump($activityExecutionsData);
     $executionHistory = $processExecutionService->getExecutionHistory($processInstance);
     $this->assertEqual(count($executionHistory), $i);
     //one hidden activity
 }
 /**
  * Check the ACL of a user for a given activity.
  * It returns false if the user cannot access the activity.
  *
  * @access public
  * @author Somsack Sipasseuth, <*****@*****.**>
  * @param  Resource activityExecution
  * @param  Resource currentUser
  * @param  Resource processExecution
  * @return boolean
  */
 public function checkAcl(core_kernel_classes_Resource $activityExecution, core_kernel_classes_Resource $currentUser, core_kernel_classes_Resource $processExecution = null)
 {
     $returnValue = (bool) false;
     if (!is_null($activityExecution) && !is_null($currentUser)) {
         if (is_null($processExecution)) {
             $processExecution = $this->getRelatedProcessExecution($activityExecution);
         }
         //get cached value:
         $cachedValue = $this->getCache(__METHOD__, array($activityExecution, $currentUser, $processExecution));
         if (!is_null($cachedValue) && is_bool($cachedValue)) {
             //				var_dump('ACL results from cache '.$activityExecution->getUri().' '.$currentUser->getLabel());
             $returnValue = $cachedValue;
             return $returnValue;
         }
         //activity and current must be set to the activty execution otherwise a common Exception is thrown
         $modeUri = $activityExecution->getOnePropertyValue($this->ACLModeProperty);
         if (is_null($modeUri)) {
             $returnValue = true;
             //if no mode defined, the activity is allowed
         } else {
             switch ($modeUri->getUri()) {
                 //check if th current user is the restricted user
                 case INSTANCE_ACL_USER:
                     $activityUser = $this->getRestrictedUser($activityExecution);
                     if (!is_null($activityUser)) {
                         if ($activityUser->getUri() == $currentUser->getUri()) {
                             $returnValue = true;
                         }
                     }
                     break;
                     //check if the current user has the restricted role
                 //check if the current user has the restricted role
                 case INSTANCE_ACL_ROLE:
                     $userService = tao_models_classes_UserService::singleton();
                     $activityRole = $this->getRestrictedRole($activityExecution);
                     $returnValue = $userService->userHasRoles($currentUser, $activityRole);
                     break;
                     //check if the current user has the restricted role and is the restricted user
                 //check if the current user has the restricted role and is the restricted user
                 case INSTANCE_ACL_ROLE_RESTRICTED_USER:
                     //check if an activity execution already exists for the current activity or if there are several in parallel, check if there is one spot available. If so create the activity execution:
                     //need to know the current process execution, from it, get the process definition and the number of activity executions associated to it.
                     //from the process definition get the number of allowed activity executions for this activity definition (normally only 1 but can be more, for a parallel connector)
                     $userService = tao_models_classes_UserService::singleton();
                     $activityRole = $this->getRestrictedRole($activityExecution);
                     if (true === $userService->userHasRoles($currentUser, $activityRole)) {
                         $assignedUser = $this->getActivityExecutionUser($activityExecution);
                         if (is_null($assignedUser) || $assignedUser->getUri() == $currentUser->getUri()) {
                             $returnValue = true;
                         }
                     }
                     break;
                     //check if the current user has the restricted role and is the restricted user based on the previous activity with the given role
                 //check if the current user has the restricted role and is the restricted user based on the previous activity with the given role
                 case INSTANCE_ACL_ROLE_RESTRICTED_USER_INHERITED:
                     $userService = tao_models_classes_UserService::singleton();
                     $activityRole = $this->getRestrictedRole($activityExecution);
                     if (true === $userService->userHasRoles($currentUser, $activityRole)) {
                         $roleSearchPattern = array();
                         $roleSearchPattern[] = $activityRole->getUri();
                         $relatedProcessVariable = $this->getRestrictedRole($activityExecution, false);
                         if (!is_null($relatedProcessVariable) && $relatedProcessVariable->getUri() != $activityRole->getUri()) {
                             $roleSearchPattern[] = $relatedProcessVariable->getUri();
                         }
                         //search for a past activity execution that has the the right role:
                         $activityExecutionsClass = new core_kernel_classes_Class(CLASS_ACTIVITY_EXECUTION);
                         $pastActivityExecutions = $activityExecutionsClass->searchInstances(array(PROPERTY_ACTIVITY_EXECUTION_ACTIVITY => $this->getExecutionOf($activityExecution)->getUri(), PROPERTY_ACTIVITY_EXECUTION_PROCESSEXECUTION => $processExecution->getUri(), PROPERTY_ACTIVITY_EXECUTION_ACL_MODE => INSTANCE_ACL_ROLE_RESTRICTED_USER_INHERITED, PROPERTY_ACTIVITY_EXECUTION_RESTRICTED_ROLE => $roleSearchPattern), array('like' => false));
                         $count = count($pastActivityExecutions);
                         if ($count > 0) {
                             foreach ($pastActivityExecutions as $pastActivityExecution) {
                                 $pastUser = $this->getActivityExecutionUser($pastActivityExecution);
                                 if (!is_null($pastUser)) {
                                     if ($pastUser->getUri() == $currentUser->getUri()) {
                                         $returnValue = true;
                                         //user's activity execution
                                     }
                                     break 2;
                                 } else {
                                     continue;
                                 }
                             }
                             $returnValue = true;
                             //no user has taken it
                         } else {
                             //throw exception here, since there should be at least the current acitivty exec here
                             throw new wfEngine_models_classes_ProcessExecutionException('cannot even found a single activity execution that for the inherited role');
                         }
                         break;
                     }
                     break;
                     //special case for deliveries
                 //special case for deliveries
                 case INSTANCE_ACL_ROLE_RESTRICTED_USER_DELIVERY:
                     $userService = tao_models_classes_UserService::singleton();
                     $activity = $this->getExecutionOf($activityExecution);
                     if ($this->activityService->isInitial($activity)) {
                         $activityRole = $this->getRestrictedRole($activityExecution);
                         $returnValue = $userService->userHasRoles($currentUser, $activityRole);
                     } else {
                         $process = $processExecution->getOnePropertyValue(new core_kernel_classes_Property(PROPERTY_PROCESSINSTANCES_EXECUTIONOF));
                         if (!is_null($process)) {
                             $processDefinitionService = wfEngine_models_classes_ProcessDefinitionService::singleton();
                             foreach ($processDefinitionService->getRootActivities($process) as $initialActivity) {
                                 if (!is_null($this->getExecution($initialActivity, $currentUser, $processExecution))) {
                                     $returnValue = true;
                                 }
                                 break;
                             }
                         }
                     }
                     break;
             }
         }
         //set cached value:
         if (is_null($cachedValue) || !is_bool($cachedValue)) {
             $this->setCache(__METHOD__, array($activityExecution, $currentUser, $processExecution), $returnValue);
         }
     }
     return (bool) $returnValue;
 }