* @author Romain Quetiez
* @author Denis Flaven
* @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
*/
require_once('../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
require_once(APPROOT.'/application/nicewebpage.class.inc.php');
require_once(APPROOT.'/application/wizardhelper.class.inc.php');
/**
* Get the list of parameters (i.e. attribute codes) to be handled while creating a new UserRequest object
* @return Array The list of attribute codes
*/
function GetParamsList()
{
return array('org_id', 'caller_id', 'service_id', 'servicesubcategory_id', 'request_type', 'title', 'description', 'impact', 'urgency', 'workgroup_id');
}
/**
* Outputs a list of parameters as hidden field into the current page
* (must be called when inside a form)
* @param WebPage $oP The current web page
* @param Array $aInteractive The list of parameters that are handled intractively and thus should not be output as hidden fields
* @param Hash $aParameters Array name => value for the parameters
* @return void
*/
function DumpHiddenParams($oP, $aInteractive, $aParameters)
{
foreach($aParameters as $sAttCode => $value)
{
if (!in_array($sAttCode, $aInteractive))
{
$oP->Add("");
}
}
}
/**
* Read all the parameters of the page for building a UserRequest
* Parameters that were absent from the page's parameters are not set in the resulting hash array
* @input string $sMethod Either get or post
* @return Hash Array of name => value corresponding to the parameters that were passed to the page
*/
function ReadAllParams()
{
$aParams = GetParamsList();
$aValues = array();
foreach($aParams as $sName)
{
$value = utils::ReadParam('attr_'.$sName, null, false, 'raw_data');
if (!is_null($value))
{
$aValues[$sName] = $value;
}
}
return $aValues;
}
/**
* Displays the portal main menu
* @param WebPage $oP The current web page
* @return void
*/
function DisplayMainMenu(WebPage $oP)
{
$oP->AddMenuButton('refresh', 'Portal:Refresh', './index.php?operation=welcome');
$oP->AddMenuButton('create', 'Portal:CreateNewRequest', './index.php?operation=create_request');
$oP->AddMenuButton('change_pwd', 'Portal:ChangeMyPassword', './index.php?loginop=change_pwd');
$oP->add("
\n");
$oP->add("
".Dict::S('Portal:OpenRequests')."
\n");
ListOpenRequests($oP);
$oP->add("
\n");
$oP->add("
\n");
$oP->add("
".Dict::S('Portal:ResolvedRequests')."
\n");
ListResolvedRequests($oP);
$oP->add("
\n");
}
/**
* Displays the form to select a Service Id (among the valid ones for the specified user Organization)
* @param WebPage $oP Web page for the form output
* @param Organization $oUserOrg The organization of the current user
* @return void
*/
function SelectService($oP, $oUserOrg)
{
// Init forms parameters
$aParameters = ReadAllParams();
$oSearch = DBObjectSearch::FromOQL('SELECT Service AS s JOIN SLA AS sla ON sla.service_id=s.id JOIN lnkContractToSLA AS ln ON ln.sla_id=sla.id JOIN CustomerContract AS cc ON ln.contract_id=cc.id WHERE cc.org_id = :org_id');
$oSet = new CMDBObjectSet($oSearch, array(), array('org_id' => $oUserOrg->GetKey()));
$oP->add("
\n");
}
else
{
$oP->p("Error: Invalid Service: id = $iSvcId");
}
}
/**
* Displays the form for the final step of the UserRequest creation
* @param WebPage $oP The current web page for the form output
* @param Organization $oUserOrg The organization of the current user
* @return void
*/
function RequestCreationForm($oP, $oUserOrg)
{
$aList = array('request_type', 'title', 'description', 'impact', 'urgency', 'workgroup_id');
$aParameters = ReadAllParams();
$oService = MetaModel::GetObject('Service', $aParameters['service_id'], false);
$oSubService = MetaModel::GetObject('ServiceSubcategory', $aParameters['servicesubcategory_id'], false);
if (is_object($oService) && is_object($oSubService))
{
$oRequest = new UserRequest();
$oRequest->Set('org_id', $oUserOrg->GetKey());
$oRequest->Set('caller_id', UserRights::GetContactId());
$oRequest->Set('service_id', $aParameters['service_id']);
$oRequest->Set('servicesubcategory_id', $aParameters['servicesubcategory_id']);
$oAttDef = MetaModel::GetAttributeDef('UserRequest', 'service_id');
$aDetails[] = array('label' => ''.$oAttDef->GetLabel().'', 'value' => htmlentities($oService->GetName(), ENT_QUOTES, 'UTF-8'));
$oAttDef = MetaModel::GetAttributeDef('UserRequest', 'servicesubcategory_id');
$aDetails[] = array('label' => ''.$oAttDef->GetLabel().'', 'value' => htmlentities($oSubService->GetName(), ENT_QUOTES, 'UTF-8'));
$iFlags = 0;
foreach($aList as $sAttCode)
{
$value = '';
if (isset($aParameters[$sAttCode]))
{
$value = $aParameters[$sAttCode];
$oRequest->Set($sAttCode, $value);
}
}
$aFieldsMap = array();
foreach($aList as $sAttCode)
{
$value = '';
$oAttDef = MetaModel::GetAttributeDef(get_class($oRequest), $sAttCode);
$iFlags = $oRequest->GetAttributeFlags($sAttCode);
if (isset($aParameters[$sAttCode]))
{
$value = $aParameters[$sAttCode];
}
$aArgs = array('this' => $oRequest);
$aFieldsMap[$sAttCode] = 'attr_'.$sAttCode;
$sValue = $oRequest->GetFormElementForField($oP, get_class($oRequest), $sAttCode, $oAttDef, $value, '', 'attr_'.$sAttCode, '', $iFlags, $aArgs);
$aDetails[] = array('label' => ''.$oAttDef->GetLabel().'', 'value' => $sValue);
}
if (!class_exists('AttachmentPlugIn'))
{
// the Attachement plug-ins is not installed, do it the old way
$aDetails[] = array('label' => ''.Dict::S('Portal:Attachments').'', 'value' => ' ');
$aDetails[] = array('label' => ' ', 'value' => '');
}
$oP->add_linked_script("../js/json.js");
$oP->add_linked_script("../js/forms-json-utils.js");
$oP->add_linked_script("../js/wizardhelper.js");
$oP->add_linked_script("../js/wizard.utils.js");
$oP->add_linked_script("../js/linkswidget.js");
$oP->add_linked_script("../js/extkeywidget.js");
$oP->add_linked_script("../js/jquery.blockUI.js");
$oP->add("
\n");
$oP->add("
".Dict::S('Portal:DescriptionOfTheRequest')."
\n");
$oP->add("");
$oP->add("
\n");
$iFieldsCount = count($aFieldsMap);
$sJsonFieldsMap = json_encode($aFieldsMap);
$oP->add_ready_script(
<< new
var oWizardHelper = new WizardHelper('UserRequest', '');
oWizardHelper.SetFieldsMap($sJsonFieldsMap);
oWizardHelper.SetFieldsCount($iFieldsCount);
// Starts the validation when the page is ready
CheckFields('request_form', false);
$('#request_form').submit( function() {
return OnSubmit('request_form');
});
$(window).unload(function() { OnUnload('$sTransactionId') } );
EOF
);
$sBtnLabel = Dict::S('Portal:RemoveAttachment');
$oP->add_script(
<<
');
index++;
}
function RemoveAttachment(id_attachment)
{
$('#attachment_'+id_attachment).remove();
}
EOF
);
}
else
{
// User not authorized to use this service ?
DisplayMainMenu($oP);
}
}
/**
* Validate the parameters and create the UserRequest object (based on the page's POSTed parameters)
* @param WebPage $oP The current web page for the output
* @param Organization $oUserOrg The organization of the current user
* @return void
*/
function DoCreateRequest($oP, $oUserOrg)
{
$aParameters = ReadAllParams();
$sTransactionId = utils::ReadPostedParam('transaction_id', '');
if (!utils::IsTransactionValid($sTransactionId))
{
$oP->add("
".Dict::S('UI:Error:ObjectAlreadyCreated')."
\n");
DisplayMainMenu($oP);
return;
}
// Validate the parameters
// 1) Service
$oSearch = DBObjectSearch::FromOQL('SELECT Service AS s JOIN SLA AS sla ON sla.service_id=s.id JOIN lnkContractToSLA AS ln ON ln.sla_id=sla.id JOIN CustomerContract AS cc ON ln.contract_id=cc.id WHERE cc.org_id = :org_id AND s.id = :svc_id');
$oSet = new CMDBObjectSet($oSearch, array(), array('org_id' => $oUserOrg->GetKey(), 'svc_id' => $aParameters['service_id']));
if ($oSet->Count() != 1)
{
// Invalid service for the current user !
throw new Exception("Invalid Service: id={$aParameters['servicesubcategory_id']} for the current user (org_id=".$oUserOrg->GetKey().").");
}
$oService = $oSet->Fetch();
// 2) Service Subcategory
$oSearch = DBObjectSearch::FromOQL('SELECT ServiceSubcategory AS sc WHERE sc.id = :subcategory_id AND sc.service_id = :svc_id');
$oSet = new CMDBObjectSet($oSearch, array(), array('svc_id' => $aParameters['service_id'], 'subcategory_id' =>$aParameters['servicesubcategory_id'] ));
if ($oSet->Count() != 1)
{
// Invalid subcategory
throw new Exception("Invalid ServiceSubcategory: id={$aParameters['servicesubcategory_id']} for service ".$oService->GetName()."({$aParameters['service_id']})");
}
$oRequest = new UserRequest();
$oRequest->Set('org_id', $oUserOrg->GetKey());
$oRequest->Set('caller_id', UserRights::GetContactId());
$aList = array('service_id', 'servicesubcategory_id', 'request_type', 'title', 'description', 'impact', 'urgency', 'workgroup_id');
foreach($aList as $sAttCode)
{
$oRequest->Set($sAttCode, $aParameters[$sAttCode]);
}
list($bRes, $aIssues) = $oRequest->CheckToWrite();
if ($bRes)
{
$oMyChange = MetaModel::NewObject("CMDBChange");
$oMyChange->Set("date", time());
$sUserString = CMDBChange::GetCurrentUserName();
$oMyChange->Set("userinfo", $sUserString);
$iChangeId = $oMyChange->DBInsert();
$oRequest->DBInsertTracked($oMyChange);
$oP->add("
\n");
if (class_exists('AttachmentPlugIn'))
{
// New way: use the plug-in
$oAttPlugin = new AttachmentPlugIn();
$oAttPlugin->OnFormSubmit($oRequest);
}
else
{
// Old way: create linked documents
$index = 0;
foreach($_FILES as $sName => $void)
{
$oAttachment = utils::ReadPostedDocument($sName);
if (!$oAttachment->IsEmpty())
{
$index++;
// Create a document and attach it to the created ticket
$oDoc = new FileDoc();
$oDoc->Set('name', Dict::Format('Portal:Attachment_No_To_Ticket_Name', $index, $oRequest->GetName(), $oAttachment->GetFileName()));
$oDoc->Set('org_id', $oUserOrg->GetKey());
$oDoc->Set('description', $oAttachment->GetFileName());
$oDoc->Set('contents', $oAttachment);
$oDoc->DBInsertTracked($oMyChange);
// Link the document to the ticket
$oLink = new lnkTicketToDoc();
$oLink->Set('ticket_id', $oRequest->GetKey());
$oLink->Set('document_id', $oDoc->GetKey());
$oLink->DBInsertTracked($oMyChange);
}
}
}
DisplayMainMenu($oP);
}
else
{
RequestCreationForm($oP, $oUserOrg);
$sIssueDesc = Dict::Format('UI:ObjectCouldNotBeWritten', implode(', ', $aIssues));
$oP->add_ready_script("alert('".addslashes($sIssueDesc)."');");
}
}
/**
* Prompts the user for creating a new request
* @param WebPage $oP The current web page
* @return void
*/
function CreateRequest(WebPage $oP, Organization $oUserOrg)
{
$iStep = utils::ReadParam('step', 0);
switch($iStep)
{
case 0:
default:
$oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome');
SelectService($oP, $oUserOrg);
break;
case 1:
$oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome');
SelectSubService($oP, $oUserOrg);
break;
case 2:
$oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome');
RequestCreationForm($oP, $oUserOrg);
break;
case 3:
DoCreateRequest($oP, $oUserOrg);
break;
}
}
/**
* Displays the value of the given field, in HTML, without any hyperlink to other objects
* @param DBObject $oObj The object to use
* @param string $sAttCode Code of the attribute to display
* @return string HTML text representing the value of this field
*/
function GetFieldAsHtml($oObj, $sAttCode)
{
$sValue = '';
$oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode);
if ($oAttDef->IsExternalKey())
{
// Special processing for external keys: don't display any hyperlink
$oTargetObj = MetaModel::GetObject($oAttDef->GetTargetClass(), $oObj->Get($sAttCode), false);
if (is_object($oTargetObj))
{
$sValue = $oTargetObj->GetName();
}
else
{
$sValue = Dict::S('UI:UndefinedObject');
}
}
else
{
$sValue = $oObj->GetAsHTML($sAttCode);
}
return $sValue;
}
/**
* Displays a list of objects, without any hyperlink (except for the object's details)
* @param WebPage $oP The web page for the output
* @param DBObjectSet $oSet The set of objects to display
* @param Array $aZList The ZList (list of field codes) to use for the tabular display
* @return string The HTML text representing the list
*/
function DisplaySet($oP, $oSet, $aZList)
{
if ($oSet->Count() > 0)
{
$aAttribs = array();
$aValues = array();
$oAttDef = MetaModel::GetAttributeDef('UserRequest', 'ref');
$aAttribs['key'] = array('label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
foreach($aZList as $sAttCode)
{
$oAttDef = MetaModel::GetAttributeDef('UserRequest', $sAttCode);
$aAttribs[$sAttCode] = array('label' => $oAttDef->GetLabel(), 'description' => $oAttDef->GetDescription());
}
while($oRequest = $oSet->Fetch())
{
$aRow = array();
$aRow['key'] = ''.$oRequest->Get('ref').'';
$sHilightClass = $oRequest->GetHilightClass();
if ($sHilightClass != '')
{
$aRow['@class'] = $sHilightClass;
}
foreach($aZList as $sAttCode)
{
$aRow[$sAttCode] = GetFieldAsHtml($oRequest, $sAttCode);
}
$aValues[$oRequest->GetKey()] = $aRow;
}
$oP->Table($aAttribs, $aValues);
// Temprory until we merge re-use the paginated tables:
$oP->add_ready_script(
<<add(Dict::S('Portal:NoOpenRequest'));
}
}
/**
* Lists all the currently opened User Requests for the current user
* @param WebPage $oP The current web page
* @return void
*/
function ListOpenRequests(WebPage $oP)
{
$iContactId = UserRights::GetContactId();
$oContact = MetaModel::GetObject('Contact', $iContactId, false); // false => Can fail
if (is_object($oContact))
{
$sOQL = 'SELECT UserRequest WHERE caller_id = :contact_id AND status NOT IN ("resolved", "closed")';
$oSearch = DBObjectSearch::FromOQL($sOQL);
$oSet = new CMDBObjectSet($oSearch, array(), array('contact_id' => $iContactId));
$aZList = array('title', 'start_date', 'status', 'service_id', 'priority', 'workgroup_id', 'agent_id');
DisplaySet($oP, $oSet, $aZList);
}
}
/**
* Lists all the currently Resolved (not "Closed")User Requests for the current user
* @param WebPage $oP The current web page
* @return void
*/
function ListResolvedRequests(WebPage $oP)
{
$iContactId = UserRights::GetContactId();
$oContact = MetaModel::GetObject('Contact', $iContactId, false); // false => Can fail
if (is_object($oContact))
{
$sOQL = 'SELECT UserRequest WHERE caller_id = :contact_id AND status ="resolved"';
$oSearch = DBObjectSearch::FromOQL($sOQL);
$oSet = new CMDBObjectSet($oSearch, array(), array('contact_id' => $iContactId));
$aZList = array('title', 'start_date', 'status', 'service_id', 'priority', 'workgroup_id', 'agent_id');
DisplaySet($oP, $oSet, $aZList);
}
}
/**
* Displays the details of the specified UserRequest object
* @param WebPage $oP The current web page for the output
* @param UserRequest $oRequest The object to display
* @return void
*/
function DisplayRequestDetails($oP, UserRequest $oRequest, $bEditMode = true)
{
// Identical to the standard 'details' ZList of UserRequest, except that the field 'org_id' has been removed
$aList = array(
'col:col1' => array(
'fieldset:Ticket:baseinfo' => array('ref','title','request_type','status','priority','service_id','servicesubcategory_id','product' ),
'fieldset:Ticket:moreinfo' => array('impact','urgency','description','resolution_code', 'solution', 'user_satisfaction', 'user_commment','freeze_reason'),
),
'col:col2' => array(
'fieldset:Ticket:date' => array('start_date','last_update','assignment_date','tto_escalation_deadline', 'ttr_escalation_deadline', 'close_date', 'closure_deadline',),
'fieldset:Ticket:contact' => array('caller_id','workgroup_id','agent_id',),
'fieldset:Ticket:relation' => array('related_problem_id', 'related_change_id'),
)
);
// Similar to CMDBAbstractObject::GetBareProperties except that: multiple tabs are not supported and GetFieldAsHtml is customized
// in order to NOT display any hyperlink
$aDetails = array();
$oP->add('
');
$aDetailsStruct = CMDBAbstractObject::ProcessZlist($aList, array('UI:PropertiesTab' => array()), 'UI:PropertiesTab', 'col1', '');
// Compute the list of properties to display, first the attributes in the 'details' list, then
// all the remaining attributes that are not external fields
$aDetails = array();
$iInputId = 0;
foreach($aDetailsStruct as $sTab => $aCols )
{
$aDetails[$sTab] = array();
ksort($aCols);
$oP->add('
');
foreach($aCols as $sColIndex => $aFieldsets)
{
$oP->add('
');
//$aDetails[$sTab][$sColIndex] = array();
$sLabel = '';
$sPreviousLabel = '';
$aDetails[$sTab][$sColIndex] = array();
foreach($aFieldsets as $sFieldsetName => $aFields)
{
if (!empty($sFieldsetName) && ($sFieldsetName[0] != '_'))
{
$sLabel = $sFieldsetName;
}
else
{
$sLabel = '';
}
if ($sLabel != $sPreviousLabel)
{
if (!empty($sPreviousLabel))
{
$oP->add('');
}
$aDetails[$sTab][$sColIndex] = array();
$sPreviousLabel = $sLabel;
}
foreach($aFields as $sAttCode)
{
if (MetaModel::IsValidAttCode(get_class($oRequest), $sAttCode))
{
$iFlags = $oRequest->GetAttributeFlags($sAttCode);
if ( ($iFlags & OPT_ATT_HIDDEN) == 0)
{
// The field is visible, add it to the current column
$val = GetFieldAsHtml($oRequest, $sAttCode);
$aDetails[$sTab][$sColIndex][] = array( 'label' => ''.MetaModel::GetLabel('UserRequest', $sAttCode).'', 'value' => $val);
$iInputId++;
}
}
}
}
if (!empty($sPreviousLabel))
{
$oP->add('');
}
$oP->add('
');
}
$oP->add('
');
}
if (!class_exists('AttachmentPlugIn'))
{
// Attachments, the old way
$sOQL = 'SELECT FileDoc AS Doc JOIN lnkTicketToDoc AS L ON L.document_id = Doc.id WHERE L.ticket_id = :request_id';
$oSearch = DBObjectSearch::FromOQL($sOQL);
$oSet = new CMDBObjectSet($oSearch, array(), array('request_id' => $oRequest->GetKey()));
$aDetails = array();
if ($oSet->Count() > 0)
{
$sAttachements = '
';
$aDetails[] = array('label' => Dict::S('Portal:Attachments'), 'value' => $sAttachements);
}
$oP->Details($aDetails);
}
// Case log... editable so that users can post comments
if ($bEditMode)
{
$oP->add("');
$oP->add_ready_script(
<<add('');
if (class_exists('AttachmentPlugIn'))
{
$oAttPlugin = new AttachmentPlugIn();
// depending on the plug-in's configuration, the attachments are displayed either in the 'properties' or in the 'relations'
// in the portal, both are handled the same way... it does not matter
$oAttPlugin->OnDisplayProperties($oRequest, $oP, false /* edit */);
$oAttPlugin->OnDisplayRelations($oRequest, $oP, false /* edit */);
}
}
$oP->add('
');
}
/**
* Displays a form for the user to provide feedback about a 'resolved' UserRequest and then close the request
* @param WebPage $oP The current web page
* @param UserRequest $oRequest The object to display
* @return void
*/
function DisplayResolvedRequestForm($oP, UserRequest $oRequest)
{
$oP->add("
\n");
DisplayMainMenu($oP);
return;
}
$sClass = get_class($oRequest);
$aDetails = array();
$aTargetStates = MetaModel::EnumStates($sClass);
$aTargetState = $aTargetStates['closed'];
$aExpectedAttributes = $aTargetState['attribute_list'];
$iFieldIndex = 0;
foreach($aExpectedAttributes as $sAttCode => $iExpectCode)
{
// Prompt for an attribute if
// - the attribute must be changed or must be displayed to the user for confirmation
// - or the field is mandatory and currently empty
if ( ($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
(($iExpectCode & OPT_ATT_MANDATORY) && ($oRequest->Get($sAttCode) == '')) )
{
$value = utils::ReadPostedParam('attr_'.$sAttCode, null, 'raw_data');
if (!is_null($value))
{
$oRequest->Set($sAttCode, $value);
}
}
}
if ($oRequest->ApplyStimulus('ev_close'))
{
$oMyChange = MetaModel::NewObject("CMDBChange");
$oMyChange->Set("date", time());
$sUserString = CMDBChange::GetCurrentUserName();
$oMyChange->Set("userinfo", $sUserString);
$iChangeId = $oMyChange->DBInsert();
$oRequest->DBUpdateTracked($oMyChange);
$oP->p("
\n");
DisplayMainMenu($oP);
}
else
{
$oP->AddMenuButton('back', 'Portal:Back', './index.php?operation=welcome');
$oP->add('Error: cannot close the request - '.$oRequest->GetName());
}
}
/**
* Find the UserRequest object of the specified ID. Make sure that it the caller is the current user
* @param integer $id The ID of the request to find
* @return UserRequert The found object, or null in case of failure (object does not exist, user has no rights to see it...)
*/
function FindRequest($id)
{
$oRequest = null;
$iContactId = UserRights::GetContactId();
$oContact = MetaModel::GetObject('Contact', $iContactId, false); // false => Can fail
if (is_object($oContact))
{
$sOQL = "SELECT UserRequest WHERE caller_id = :contact_id AND id = :request_id";
$oSearch = DBObjectSearch::FromOQL($sOQL);
$oSet = new CMDBObjectSet($oSearch, array(), array('contact_id' => $iContactId, 'request_id' => $id));
if ($oSet->Count() > 0)
{
$oRequest = $oSet->Fetch();
}
}
else
{
$oP->AddMenuButton('back', 'Portal:Back', './index.php?operation=welcome');
$oP->add("
".Dict::S('Portal:ErrorNoContactForThisUser')."
");
}
return $oRequest;
}
/**
* Displays the details of a request
* @param WebPage $oP The current web page
* @return void
*/
function RequestDetails(WebPage $oP, $id)
{
$oRequest = FindRequest($id);
if (!is_object($oRequest))
{
DisplayMainMenu($oP);
return;
}
$iDefaultStep = 0;
if ($oRequest->GetState() == 'resolved')
{
// The current ticket is in 'resolved' state, prompt to close it
$iDefaultStep = 1;
}
$iStep = utils::ReadParam('step', $iDefaultStep);
switch($iStep)
{
case 0:
$oP->AddMenuButton('back', 'Portal:Back', './index.php?operation=welcome');
$oP->add("
\n");
DisplayRequestDetails($oP, $oRequest);
break;
case 1:
$oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome');
DisplayResolvedRequestForm($oP, $oRequest);
break;
case 2:
DoCloseRequest($oP, $oRequest);
break;
case 3:
AddComment($oP, $oRequest);
break;
default:
// Should never happen
DisplayMainMenu($oP);
}
}
/**
* Adds a comment to the specified UserRequest and displays the main menu
* @param WebPage $oP The current web page for the output
* @param $id ID of the object to update
* @return void
*/
function AddComment($oP, $id)
{
$oRequest = FindRequest($id);
if (!is_object($oRequest))
{
DisplayMainMenu($oP);
return;
}
$sTransactionId = utils::ReadPostedParam('transaction_id', '');
if (!utils::IsTransactionValid($sTransactionId))
{
$oP->add("
\n");
// If there is any trigger for the Portal Update, then activate them
$sOQL = "SELECT TriggerOnPortalUpdate WHERE target_class ='UserRequest'";
$oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL));
while($oTrigger = $oSet->Fetch())
{
$oTrigger->DoActivate($oRequest->ToArgs('this'));
}
}
else
{
$oP->p("