/** * Construccion del proceso * * @param $pMacroXpdlName Name xpdl del Paquete Macro * @param $pPackXpdlName Name xpdl del Paquete * @param $pDomXpdl Dom xpdl del paquete * @param $pTypeDeclarations Array con info de los tipos declarados del paquete * @param $pDataFields Array con info de los datafields del paquete * @param $pParticipants Array con info de participantes del paquete * @return unknown_type */ public function buildProcess($process, $datafields, $participants, $type_declarations) { // Obtengo datafiels, participantes y tipos de datos del paquete $datafields = $xpdl->getDataFields(); $participants = $xpdl->getParticipants(); $type_declarations = $xpdl->getTypeDeclarations(); // Obtengo datafields y participantes (concateno a los del paquete) $datafields = array_merge($datafields, $this->xpdl->getDataFields($process->getXpdlId())); $participants = array_merge($participants, $this->xpdl->getParticipants($process->getXpdlId())); // Parametros del proceso //$parameters = $this->xpdl->getParameters(); // Recorro sus actividades $activities = $this->xpdl->getActivities($process->getXpdlId()); foreach ($activities as $activity) { $scriptSetDF = ''; $ptnName = ''; $scriptPtnSetParams = ''; $scriptPtnUrlTemplate = ''; $scriptNA = ''; // Informacion a anexar a los errores $info = sprintf(' [Info (paquete.proceso): %s.%s]', $this->getNombre(), $process->getNombre()); if ($activity['type'] == 'StartEvent') { // PERSONALIZAR ACTIVIDAD INICIO // Genero script Inicializacion de datafields foreach ($datafields as $key => $datafield) { // $this->f->setDataField('datafield', 'value'); $scriptSetDF .= "%sthis->f->setDataField('%s', '%s');%s"; $scriptSetDF = sprintf($scriptSetDF, chr(36), $key, $datafield["initialValue"], chr(10)); } } elseif ($activity['type'] == 'EndEvent') { // PERSONALIZAR ACTIVIDAD FIN } elseif ($activity['type'] == 'TaskUser' or $activity['type'] == 'TaskManual' or $activity['type'] == 'TaskScript') { // PERSONALIZAR ACTIVIDADES DE TIPOS YA IMPLEMENTADOS // Tratamiento de patrones $patterns = $this->xpdl->getPsdfPatterns($process->getXpdlId(), $activity['id']); // Regla momentanea de un solo patron if (count($patterns) > 1) { throw new sfException(sprintf('Aun no implementado la ejecucion de mas de un patron asociado a la actividad %s' . $info, $activity['name'])); } foreach ($patterns as $key => $pattern) { // Valido exista el patron if (!UtilPattern::exists($key)) { throw new sfException(sprintf('No existe el patron "%s" asociado a la actividad %s' . $info, $key, $activity['name'])); } // Instancio clase del patron $cls = $key . 'Pattern'; $ptn = new $cls(); $ptnName = $ptn->getName(); // Genero script de lectura de parametros a pasar al patron foreach ($pattern['Params'] as $param => $value) { // Si es un array convierto a string vacio para omitir warnings $v = is_array($value) ? '' : $value; if (array_key_exists($v, $datafields)) { // Es un dataField: $ptn->setParameter( 'param', $this->f->getDataField('datafield') ); $scriptPtnSetParams .= "%sptn->setParameter( '%s', %sthis->f->getDataField('%s') );%s"; $scriptPtnSetParams = sprintf($scriptPtnSetParams, chr(36), $param, chr(36), $value, chr(10)); } elseif (strpos($v, '%') and strrpos($v, '%')) { // Es una variable de entorno: $ptn->setParameter( 'param', $this->f->getContextVar('var') ); $scriptPtnSetParams .= "%sptn->setParameter( '%s', %sthis->f->getContextVar('%s') );%s"; $scriptPtnSetParams = sprintf($scriptPtnSetParams, chr(36), $param, chr(36), $value, chr(10)); } elseif (is_array($value)) { // Es un array: $ptn->setParameter( 'param', 'valor' ); $scriptPtnSetParams .= "%sptn->setParameter( '%s', '%s' );%s"; $scriptPtnSetParams = sprintf($scriptPtnSetParams, chr(36), $param, sfYaml::dump($value), chr(10)); } else { // Es un numerico/alfanumerico: $ptn->setParameter( 'param', 'valor' ); $scriptPtnSetParams .= "%sptn->setParameter( '%s', '%s' );%s"; $scriptPtnSetParams = sprintf($scriptPtnSetParams, chr(36), $param, $value, chr(10)); } } // Si el patron tiene interfaz paso a la accion/template los parametros if ($ptn->hasTemplate()) { /* Omitido porque ahora los parametros se pasan con parseTemplateParams() en la accion foreach( $pattern['Params'] as $param => $value ) { // $this->param = $ptn->getParameter( 'param'); $scriptPtnSetTemplate.= "%sthis->%s = %sptn->getParameter( '%s' );%s"; $scriptPtnSetTemplate = sprintf($scriptPtnSetTemplate, chr(36), $param, chr(36), $param, chr(10)); } */ // Ej: $this->include = 'urlTemplate'; //$scriptPtnSetTemplate.= "%sthis->include = '%s';%s"; //$scriptPtnSetTemplate = sprintf($scriptPtnSetTemplate, chr(36), $ptn->getTemplate(), chr(10)); $scriptPtnUrlTemplate = $ptn->getTemplate(); } } // Genero script de actualizacion de datafields por retorno del patron // Hoy UN SOLO patron foreach ($patterns as $key => $pattern) { foreach ($pattern['Params'] as $param => $value) { // Si es un array convierto a string vacio para omitir warnings $v = is_array($value) ? '' : $value; if (array_key_exists($v, $datafields)) { // Es un dataField: $this->f->setDataField( 'datafield', $ptn->getParameter( 'param') ); $scriptSetDF .= "%sthis->f->setDataField( '%s', %sptn->getParameter( '%s') );%s"; $scriptSetDF = sprintf($scriptSetDF, chr(36), $value, chr(36), $param, chr(10)); } } } } else { throw new sfException(sprintf('La Tarea %s bpmn es del tipo %s aun no implementada' . $info, $activity['name'], $activity['type'])); } // Genero script de determinacion de siguiente actividad // Para eso recupero las posibles siguientes actividades $nextActivity = null; $nexts = $this->xpdl->getNextActivities($process->getXpdlId(), $activity['id']); if (count($nexts) > 1) { // Aqui debo determinar mediante reglas por cual lado seguir throw new sfException(sprintf('La Tarea %s tiene más de una transición, aún no implementada' . $info, $activity['name'])); } if (count($nexts) == 0) { if ($activity['type'] != 'EndEvent') { // Aqui debo determinar mediante reglas por cual lado seguir throw new sfException(sprintf('La Tarea %s debe tener por lo menos una transicion hacia otra actividad' . $info, $activity['name'])); } } if (count($nexts) == 1) { $nextActivity = $this->parseActivityImplementationName($process->getNombre(), $nexts[0]['name'], $nexts[0]['type']); // $next = 'nextActivity'; $scriptNA = "%snext = '%s';%s"; $scriptNA = sprintf($scriptNA, chr(36), $nextActivity, chr(10)); } $scripts = array('set_datafields' => $scriptSetDF, 'ptn_name' => $ptnName, 'ptn_set_params' => $scriptPtnSetParams, 'ptn_url_template' => $scriptPtnUrlTemplate, 'rules_next' => $scriptNA); $arguments = array('application' => $this->getMacro()->parseImplementationName(), 'module' => $this->parseImplementationName(), 'action' => $this->parseActivityImplementationName($process->getNombre(), $activity['name'], $activity['type']), 'process' => array('id' => $process->getId(), 'name' => $process->getNombre()), 'activity' => $activity, 'scripts' => $scripts); $this->implementActivity($arguments); } }
/** * Recupera lista definicion de patrones * * @param string $process_id Id xpdl del proceso * @param string $activity_id Id xpdl de la actividad * @return array Lista de patrones */ public function getPsdfPatterns($process_id, $activity_id) { $patterns = array(); // Hoy solo tomo el primero, si hay mas de uno será omitido $ymldef = $this->getExtendedAttributeBody('Patron', self::EXTENDED_ACTIVITY, array($process_id, $activity_id)); if (!$ymldef) { return $patterns; } try { $pattern = sfYaml::load($ymldef); } catch (Exception $e) { throw new sfException(sprintf('No se pudo leer yml de llamada a patron: %s', $e->getMessage())); } // Quito el raiz (Patron) asi el 2do subnodo (Nombre) pasa a ser el 1ro. if ($pattern) { $patterns[key($pattern)] = $pattern[key($pattern)]; } // Regla de un solo patron if (count($patterns) > 1) { throw new sfException(sprintf('La actividad debe tener asociado solamente un patron')); } // Regla que exista el patron if (count($patterns) == 1) { $key = array_keys($patterns); if (!UtilPattern::exists($key[0])) { throw new sfException(sprintf('No existe el patron "%s" asociado a la actividad', $key[0])); } } return $patterns; }