Exemplo n.º 1
0
 /**
  * Enumerate services delivered by this class
  * @param string $sVersion The version (e.g. 1.0) supported by the services
  * @return RestResult The standardized result structure (at least a message)
  * @throws Exception in case of internal failure.	 
  */
 public function ExecOperation($sVersion, $sVerb, $aParams)
 {
     $oResult = new RestResultWithObjects();
     switch ($sVerb) {
         case 'core/create':
             RestUtils::InitTrackingComment($aParams);
             $sClass = RestUtils::GetClass($aParams, 'class');
             $aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $oObject = RestUtils::MakeObjectFromFields($sClass, $aFields);
             $oObject->DBInsert();
             $oResult->AddObject(0, 'created', $oObject, $aShowFields, $bExtendedOutput);
             break;
         case 'core/update':
             RestUtils::InitTrackingComment($aParams);
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $oObject = RestUtils::FindObjectFromKey($sClass, $key);
             RestUtils::UpdateObjectFromFields($oObject, $aFields);
             $oObject->DBUpdate();
             $oResult->AddObject(0, 'updated', $oObject, $aShowFields, $bExtendedOutput);
             break;
         case 'core/apply_stimulus':
             RestUtils::InitTrackingComment($aParams);
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $sStimulus = RestUtils::GetMandatoryParam($aParams, 'stimulus');
             $oObject = RestUtils::FindObjectFromKey($sClass, $key);
             RestUtils::UpdateObjectFromFields($oObject, $aFields);
             $aTransitions = $oObject->EnumTransitions();
             $aStimuli = MetaModel::EnumStimuli(get_class($oObject));
             if (!isset($aTransitions[$sStimulus])) {
                 // Invalid stimulus
                 $oResult->code = RestResult::INTERNAL_ERROR;
                 $oResult->message = "Invalid stimulus: '{$sStimulus}' on the object " . $oObject->GetName() . " in state '" . $oObject->GetState() . "'";
             } else {
                 $aTransition = $aTransitions[$sStimulus];
                 $sTargetState = $aTransition['target_state'];
                 $aStates = MetaModel::EnumStates($sClass);
                 $aTargetStateDef = $aStates[$sTargetState];
                 $aExpectedAttributes = $aTargetStateDef['attribute_list'];
                 $aMissingMandatory = array();
                 foreach ($aExpectedAttributes as $sAttCode => $iExpectCode) {
                     if ($iExpectCode & OPT_ATT_MANDATORY && $oObject->Get($sAttCode) == '') {
                         $aMissingMandatory[] = $sAttCode;
                     }
                 }
                 if (count($aMissingMandatory) == 0) {
                     // If all the mandatory fields are already present, just apply the transition silently...
                     if ($oObject->ApplyStimulus($sStimulus)) {
                         $oObject->DBUpdate();
                         $oResult->AddObject(0, 'updated', $oObject, $aShowFields, $bExtendedOutput);
                     }
                 } else {
                     // Missing mandatory attributes for the transition
                     $oResult->code = RestResult::INTERNAL_ERROR;
                     $oResult->message = 'Missing mandatory attribute(s) for applying the stimulus: ' . implode(', ', $aMissingMandatory) . '.';
                 }
             }
             break;
         case 'core/get':
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
             while ($oObject = $oObjectSet->Fetch()) {
                 $oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
             }
             $oResult->message = "Found: " . $oObjectSet->Count();
             break;
         case 'core/delete':
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $bSimulate = RestUtils::GetOptionalParam($aParams, 'simulate', false);
             $oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
             $aObjects = $oObjectSet->ToArray();
             $this->DeleteObjects($oResult, $aObjects, $bSimulate);
             break;
         case 'core/get_related':
             $oResult = new RestResultWithRelations();
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $sRelation = RestUtils::GetMandatoryParam($aParams, 'relation');
             $iMaxRecursionDepth = RestUtils::GetOptionalParam($aParams, 'depth', 20);
             $sDirection = RestUtils::GetOptionalParam($aParams, 'direction', null);
             $bEnableRedundancy = RestUtils::GetOptionalParam($aParams, 'redundancy', false);
             $bReverse = false;
             if (is_null($sDirection) && $sRelation == 'depends on') {
                 // Legacy behavior, consider "depends on" as a forward relation
                 $sRelation = 'impacts';
                 $sDirection = 'up';
                 $bReverse = true;
                 // emulate the legacy behavior by returning the edges
             } else {
                 if (is_null($sDirection)) {
                     $sDirection = 'down';
                 }
             }
             $oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
             if ($sDirection == 'down') {
                 $oRelationGraph = $oObjectSet->GetRelatedObjectsDown($sRelation, $iMaxRecursionDepth, $bEnableRedundancy);
             } else {
                 if ($sDirection == 'up') {
                     $oRelationGraph = $oObjectSet->GetRelatedObjectsUp($sRelation, $iMaxRecursionDepth, $bEnableRedundancy);
                 } else {
                     $oResult->code = RestResult::INTERNAL_ERROR;
                     $oResult->message = "Invalid value: '{$sDirection}' for the parameter 'direction'. Valid values are 'up' and 'down'";
                     return $oResult;
                 }
             }
             if ($bEnableRedundancy) {
                 // Remove the redundancy nodes from the output
                 $oIterator = new RelationTypeIterator($oRelationGraph, 'Node');
                 foreach ($oIterator as $oNode) {
                     if ($oNode instanceof RelationRedundancyNode) {
                         $oRelationGraph->FilterNode($oNode);
                     }
                 }
             }
             $aIndexByClass = array();
             $oIterator = new RelationTypeIterator($oRelationGraph);
             foreach ($oIterator as $oElement) {
                 if ($oElement instanceof RelationObjectNode) {
                     $oObject = $oElement->GetProperty('object');
                     if ($oObject) {
                         if ($bEnableRedundancy) {
                             // Add only the "reached" objects
                             if ($oElement->GetProperty('is_reached')) {
                                 $aIndexByClass[get_class($oObject)][$oObject->GetKey()] = null;
                                 $oResult->AddObject(0, '', $oObject);
                             }
                         } else {
                             $aIndexByClass[get_class($oObject)][$oObject->GetKey()] = null;
                             $oResult->AddObject(0, '', $oObject);
                         }
                     }
                 } else {
                     if ($oElement instanceof RelationEdge) {
                         $oSrcObj = $oElement->GetSourceNode()->GetProperty('object');
                         $oDestObj = $oElement->GetSinkNode()->GetProperty('object');
                         $sSrcKey = get_class($oSrcObj) . '::' . $oSrcObj->GetKey();
                         $sDestKey = get_class($oDestObj) . '::' . $oDestObj->GetKey();
                         if ($bEnableRedundancy) {
                             // Add only the edges where both source and destination are "reached"
                             if ($oElement->GetSourceNode()->GetProperty('is_reached') && $oElement->GetSinkNode()->GetProperty('is_reached')) {
                                 if ($bReverse) {
                                     $oResult->AddRelation($sDestKey, $sSrcKey);
                                 } else {
                                     $oResult->AddRelation($sSrcKey, $sDestKey);
                                 }
                             }
                         } else {
                             if ($bReverse) {
                                 $oResult->AddRelation($sDestKey, $sSrcKey);
                             } else {
                                 $oResult->AddRelation($sSrcKey, $sDestKey);
                             }
                         }
                     }
                 }
             }
             if (count($aIndexByClass) > 0) {
                 $aStats = array();
                 foreach ($aIndexByClass as $sClass => $aIds) {
                     $aStats[] = $sClass . '= ' . count($aIds);
                 }
                 $oResult->message = "Scope: " . $oObjectSet->Count() . "; Related objects: " . implode(', ', $aStats);
             } else {
                 $oResult->message = "Nothing found";
             }
             break;
         case 'core/check_credentials':
             $oResult = new RestResult();
             $sUser = RestUtils::GetMandatoryParam($aParams, 'user');
             $sPassword = RestUtils::GetMandatoryParam($aParams, 'password');
             if (UserRights::CheckCredentials($sUser, $sPassword) !== true) {
                 $oResult->authorized = false;
             } else {
                 $oResult->authorized = true;
             }
             break;
         default:
             // unknown operation: handled at a higher level
     }
     return $oResult;
 }
 /**
  * Enumerate services delivered by this class
  * @param string $sVersion The version (e.g. 1.0) supported by the services
  * @return RestResult The standardized result structure (at least a message)
  * @throws Exception in case of internal failure.	 
  */
 public function ExecOperation($sVersion, $sVerb, $aParams)
 {
     $oResult = new RestResultWithObjects();
     switch ($sVerb) {
         case 'core/create':
             RestUtils::InitTrackingComment($aParams);
             $sClass = RestUtils::GetClass($aParams, 'class');
             $aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $oObject = RestUtils::MakeObjectFromFields($sClass, $aFields);
             $oObject->DBInsert();
             $oResult->AddObject(0, 'created', $oObject, $aShowFields, $bExtendedOutput);
             break;
         case 'core/update':
             RestUtils::InitTrackingComment($aParams);
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $oObject = RestUtils::FindObjectFromKey($sClass, $key);
             RestUtils::UpdateObjectFromFields($oObject, $aFields);
             $oObject->DBUpdate();
             $oResult->AddObject(0, 'updated', $oObject, $aShowFields, $bExtendedOutput);
             break;
         case 'core/apply_stimulus':
             RestUtils::InitTrackingComment($aParams);
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $aFields = RestUtils::GetMandatoryParam($aParams, 'fields');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $sStimulus = RestUtils::GetMandatoryParam($aParams, 'stimulus');
             $oObject = RestUtils::FindObjectFromKey($sClass, $key);
             RestUtils::UpdateObjectFromFields($oObject, $aFields);
             $aTransitions = $oObject->EnumTransitions();
             $aStimuli = MetaModel::EnumStimuli(get_class($oObject));
             if (!isset($aTransitions[$sStimulus])) {
                 // Invalid stimulus
                 $oResult->code = RestResult::INTERNAL_ERROR;
                 $oResult->message = "Invalid stimulus: '{$sStimulus}' on the object " . $oObject->GetName() . " in state '" . $oObject->GetState() . "'";
             } else {
                 $aTransition = $aTransitions[$sStimulus];
                 $sTargetState = $aTransition['target_state'];
                 $aStates = MetaModel::EnumStates($sClass);
                 $aTargetStateDef = $aStates[$sTargetState];
                 $aExpectedAttributes = $aTargetStateDef['attribute_list'];
                 $aMissingMandatory = array();
                 foreach ($aExpectedAttributes as $sAttCode => $iExpectCode) {
                     if ($iExpectCode & OPT_ATT_MANDATORY && $oObject->Get($sAttCode) == '') {
                         $aMissingMandatory[] = $sAttCode;
                     }
                 }
                 if (count($aMissingMandatory) == 0) {
                     // If all the mandatory fields are already present, just apply the transition silently...
                     if ($oObject->ApplyStimulus($sStimulus)) {
                         $oObject->DBUpdate();
                         $oResult->AddObject(0, 'updated', $oObject, $aShowFields, $bExtendedOutput);
                     }
                 } else {
                     // Missing mandatory attributes for the transition
                     $oResult->code = RestResult::INTERNAL_ERROR;
                     $oResult->message = 'Missing mandatory attribute(s) for applying the stimulus: ' . implode(', ', $aMissingMandatory) . '.';
                 }
             }
             break;
         case 'core/get':
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $aShowFields = RestUtils::GetFieldList($sClass, $aParams, 'output_fields');
             $bExtendedOutput = RestUtils::GetOptionalParam($aParams, 'output_fields', '*') == '*+';
             $oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
             while ($oObject = $oObjectSet->Fetch()) {
                 $oResult->AddObject(0, '', $oObject, $aShowFields, $bExtendedOutput);
             }
             $oResult->message = "Found: " . $oObjectSet->Count();
             break;
         case 'core/delete':
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $bSimulate = RestUtils::GetOptionalParam($aParams, 'simulate', false);
             $oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
             $aObjects = $oObjectSet->ToArray();
             $this->DeleteObjects($oResult, $aObjects, $bSimulate);
             break;
         case 'core/get_related':
             $oResult = new RestResultWithRelations();
             $sClass = RestUtils::GetClass($aParams, 'class');
             $key = RestUtils::GetMandatoryParam($aParams, 'key');
             $sRelation = RestUtils::GetMandatoryParam($aParams, 'relation');
             $iMaxRecursionDepth = RestUtils::GetOptionalParam($aParams, 'depth', 20);
             $oObjectSet = RestUtils::GetObjectSetFromKey($sClass, $key);
             $aIndexByClass = array();
             while ($oObject = $oObjectSet->Fetch()) {
                 $aRelated = array();
                 $aGraph = array();
                 $aIndexByClass[get_class($oObject)][$oObject->GetKey()] = null;
                 $oResult->AddObject(0, '', $oObject);
                 $this->GetRelatedObjects($oObject, $sRelation, $iMaxRecursionDepth, $aRelated, $aGraph);
                 foreach ($aRelated as $sClass => $aObjects) {
                     foreach ($aObjects as $oRelatedObj) {
                         $aIndexByClass[get_class($oRelatedObj)][$oRelatedObj->GetKey()] = null;
                         $oResult->AddObject(0, '', $oRelatedObj);
                     }
                 }
                 foreach ($aGraph as $sSrcKey => $aDestinations) {
                     foreach ($aDestinations as $sDestKey) {
                         $oResult->AddRelation($sSrcKey, $sDestKey);
                     }
                 }
             }
             if (count($aIndexByClass) > 0) {
                 $aStats = array();
                 foreach ($aIndexByClass as $sClass => $aIds) {
                     $aStats[] = $sClass . '= ' . count($aIds);
                 }
                 $oResult->message = "Scope: " . $oObjectSet->Count() . "; Related objects: " . implode(', ', $aStats);
             } else {
                 $oResult->message = "Nothing found";
             }
             break;
         case 'core/check_credentials':
             $oResult = new RestResult();
             $sUser = RestUtils::GetMandatoryParam($aParams, 'user');
             $sPassword = RestUtils::GetMandatoryParam($aParams, 'password');
             if (UserRights::CheckCredentials($sUser, $sPassword) !== true) {
                 $oResult->authorized = false;
             } else {
                 $oResult->authorized = true;
             }
             break;
         default:
             // unknown operation: handled at a higher level
     }
     return $oResult;
 }