From 815de3bc2a3347b0393ba72dd45c91063e65038c Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Fri, 10 Sep 2010 11:20:23 +0000 Subject: [PATCH] - Enhancement (Trac#189) first version of a (simple) End-Users portal. - Fix for the appUserPreferences class SVN:trunk[807] --- portal/index.php | 837 ++++++++++++++++++++++++++++++++++++++++++++++ portal/portal.css | 114 +++++++ 2 files changed, 951 insertions(+) create mode 100644 portal/index.php create mode 100644 portal/portal.css diff --git a/portal/index.php b/portal/index.php new file mode 100644 index 0000000000..1070534b56 --- /dev/null +++ b/portal/index.php @@ -0,0 +1,837 @@ + + * @author Romain Quetiez + * @author Denis Flaven + * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL + */ +require_once('../application/application.inc.php'); +require_once('../application/nicewebpage.class.inc.php'); +require_once('../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($sMethod = 'get') +{ + $aParams = GetParamsList(); + $aValues = array(); + foreach($aParams as $sName) + { + $value = utils::ReadParam('attr_'.$sName, null, $sMethod); + 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"); + $oP->add("

".Dict::S('Portal:SelectService')."

\n"); + $oP->add("
\n"); + $oP->add("\n"); + while($oService = $oSet->Fetch()) + { + $id = $oService->GetKey(); + $sChecked = ""; + if ($id == $aParameters['service_id']) + { + $sChecked = "checked"; + } + $oP->p(""); DumpHiddenParams($oP, array('service_id'), $aParameters); + + } + $oP->add("

"); + $oP->p("

".htmlentities($oService->Get('description'))."

\n"); + DumpHiddenParams($oP, array('service_id'), $aParameters); + $oP->add(""); + $oP->add(""); + $oP->p(""); + $oP->add("
"); + $oP->add("
\n"); + $sMessage = Dict::S('Portal:PleaseSelectOneService'); + $oP->add_ready_script( +<< $iSvcId)); + $oService = MetaModel::GetObject('Service', $iSvcId, false); + if (is_object($oService)) + { + $oP->add("
\n"); + $oP->add("

".Dict::Format('Portal:SelectSubcategoryFrom_Service', htmlentities($oService->GetName()))."

\n"); + $oP->add("
\n"); + $oP->add("\n"); + while($oSubService = $oSet->Fetch()) + { + $id = $oSubService->GetKey(); + $sChecked = ""; + if ($id == $iDefaultSubSvcId) + { + $sChecked = "checked"; + } + $oP->p(""); + } + $sMessage = Dict::S('Portal:PleaseSelectAServiceSubCategory'); + $oP->add_ready_script( +<<add("

"); + $oP->p("

".htmlentities($oSubService->Get('description'))."

\n"); + DumpHiddenParams($oP, array('servicesubcategory_id'), $aParameters); + $oP->add(""); + $oP->add(""); + $oP->p(" "); + $oP->add("
"); + $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())); + $oAttDef = MetaModel::GetAttributeDef('UserRequest', 'servicesubcategory_id'); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => htmlentities($oSubService->GetName())); + $iFlags = 0; + foreach($aList as $sAttCode) + { + $value = ''; + if (isset($aParameters[$sAttCode])) + { + $value = $aParameters[$sAttCode]; + $oRequest->Set($sAttCode, $value); + } + } + 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); + + $sValue = $oRequest->GetFormElementForField($oP, get_class($oRequest), $sAttCode, $oAttDef, $value, '', 'attr_'.$sAttCode, '', $iFlags, $aArgs); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sValue); + } + $oP->add("
\n"); + $oP->add("

".Dict::S('Portal:DescriptionOfTheRequest')."

\n"); + $oP->add("
\n"); + $oP->add("\n"); + $oP->details($aDetails); + DumpHiddenParams($oP, $aList, $aParameters); + $oP->add(""); + $oP->add(""); + $oP->add("\n"); + $oP->p(" "); + $oP->add(""); + $oP->add("\n"); + $oP->add_ready_script( +<<\n"; + print_r($aParameters); + echo "\n"; + } +} + +/** + * 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()); + if (UserRights::IsImpersonated()) + { + $sUserString = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUser(), UserRights::GetUser()); + } + else + { + $sUserString = UserRights::GetUser(); + } + $oMyChange->Set("userinfo", $sUserString); + $iChangeId = $oMyChange->DBInsert(); + $oRequest->DBInsertTracked($oMyChange); + $oP->add("

".Dict::Format('UI:Title:Object_Of_Class_Created', $oRequest->GetName(), MetaModel::GetName(get_class($oRequest)))."

\n"); + 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); + } + else + { + $oP->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) +{ + $aList = array('ref', 'status', 'title', 'description', 'request_type','ticket_log', 'start_date', 'tto_escalation_deadline', 'ttr_escalation_deadline', 'caller_id', 'service_id', 'servicesubcategory_id', 'product', 'impact', 'urgency', 'priority', 'workgroup_id', 'agent_id', 'related_problem_id', 'related_change_id', 'close_date', 'last_update', 'assignment_date', 'closure_deadline', 'resolution_code', 'solution', 'user_satisfaction', 'user_commment', 'freeze_reason'); + $aDetails = array(); + foreach($aList as $sAttCode) + { + $iFlags = $oRequest->GetAttributeFlags($sAttCode); + $oAttDef = MetaModel::GetAttributeDef(get_class($oRequest), $sAttCode); + if ( (!$oAttDef->IsLinkSet()) && (($iFlags & OPT_ATT_HIDDEN) == 0) ) + { + // Don't display linked set and non-visible attributes (in this state) + $sDisplayValue = GetFieldAsHtml($oRequest, $sAttCode); + $aDetails[] = array('label' => ''.MetaModel::GetLabel('UserRequest', $sAttCode).'', 'value' => $sDisplayValue); + } + } + $oP->add('
'); + $oP->details($aDetails); + $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"); + $oP->add("
\n"); + $oP->add('
'); + $oP->add("

".Dict::Format('Portal:TitleRequestDetailsFor_Request', $oRequest->GetName())."

\n"); + DisplayRequestDetails($oP, $oRequest); + $oP->add('
'); + $aArgs = array('this' => $oRequest); + $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) == '')) ) + { + $aAttributesDef = MetaModel::ListAttributeDefs($sClass); + $oAttDef = $aAttributesDef[$sAttCode]; + $aArgs = array('this' => $oRequest); + $sHTMLValue = cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $oRequest->Get($sAttCode), $oRequest->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, $aArgs); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => "$sHTMLValue"); + $aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex; + $iFieldIndex++; + } + } + $aStimuli = MetaModel::EnumStimuli($sClass); + $oP->add("

".Dict::S('Portal:EnterYourCommentsOnTicket')."

"); + $oP->details($aDetails); + $oP->add(""); + $oP->add("\n"); + $oP->add(""); + $oP->p(""); + $oP->add('
'); + $oP->add(""); + $oP->add("
\n"); + $oP->add_ready_script( +<<add("

".Dict::S('UI:Error:ObjectAlreadyCreated')."

\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::ReadParam('attr_'.$sAttCode, null, 'post'); + if (!is_null($value)) + { + $oRequest->Set($sAttCode, $value); + } + } + } + if ($oRequest->ApplyStimulus('ev_close')) + { + $oMyChange = MetaModel::NewObject("CMDBChange"); + $oMyChange->Set("date", time()); + if (UserRights::IsImpersonated()) + { + $sUserString = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUser(), UserRights::GetUser()); + } + else + { + $sUserString = UserRights::GetUser(); + } + $oMyChange->Set("userinfo", $sUserString); + $iChangeId = $oMyChange->DBInsert(); + $oRequest->DBUpdateTracked($oMyChange); + $oP->p("

".Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oRequest)), $oRequest->GetName())."

\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)) + { + echo "Request not found ! count=".$oSet->Count(); + 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("

".$oRequest->GetIcon()." ".Dict::Format('Portal:TitleRequestDetailsFor_Request', $oRequest->GetName())."

\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; + } +} + +/** + * Get The organization of the current user (i.e. the organization of its contact) + * @param WebPage $oP The current page, for errors output + * @return Organization The user's org or null in case of problem... + */ +function GetUserOrg($oP) +{ + $oOrg = null; + $iContactId = UserRights::GetContactId(); + $oContact = MetaModel::GetObject('Contact', $iContactId, false); // false => Can fail + if (is_object($oContact)) + { + $oOrg = MetaModel::GetObject('Organization', $oContact->Get('org_id'), false); // false => can fail + } + else + { + $oP->add("

".Dict::S('Portal:ErrorNoContactForThisUser')."

"); + } + return $oOrg; +} + +try +{ + require_once('../application/startup.inc.php'); + require_once('../application/portalwebpage.class.inc.php'); + $oAppContext = new ApplicationContext(); + $sOperation = utils::ReadParam('operation', ''); + + require_once('../application/loginwebpage.class.inc.php'); + LoginWebPage::DoLogin(false /* bMustBeAdmin */, true /* IsAllowedToPortalUsers */); // Check user rights and prompt if needed + + $oP = new PortalWebPage(Dict::S('Portal:Title')); + $oUserOrg = GetUserOrg($oP); + + if (is_object($oUserOrg)) + { + switch($sOperation) + { + case 'create_request': + CreateRequest($oP, $oUserOrg); + break; + + case 'details': + $iRequestId = utils::ReadParam('id', 0); + RequestDetails($oP, $iRequestId); + break; + + case 'welcome': + default: + DisplayMainMenu($oP); + } + } + $oP->output(); +} +catch(CoreException $e) +{ + require_once('../setup/setuppage.class.inc.php'); + $oP = new SetupWebPage(Dict::S('UI:PageTitle:FatalError')); + $oP->add("

".Dict::S('UI:FatalErrorMessage')."

\n"); + $oP->error(Dict::Format('UI:Error_Details', $e->getHtmlDesc())); + $oP->output(); + + if (MetaModel::IsLogEnabledIssue()) + { + if (MetaModel::IsValidClass('EventIssue')) + { + try + { + $oLog = new EventIssue(); + + $oLog->Set('message', $e->getMessage()); + $oLog->Set('userinfo', ''); + $oLog->Set('issue', $e->GetIssue()); + $oLog->Set('impact', 'Page could not be displayed'); + $oLog->Set('callstack', $e->getTrace()); + $oLog->Set('data', $e->getContextData()); + $oLog->DBInsertNoReload(); + } + catch(Exception $e) + { + IssueLog::Error("Failed to log issue into the DB"); + } + } + + IssueLog::Error($e->getMessage()); + } + + // For debugging only + //throw $e; +} +catch(Exception $e) +{ + require_once('../setup/setuppage.class.inc.php'); + $oP = new SetupWebPage(Dict::S('UI:PageTitle:FatalError')); + $oP->add("

".Dict::S('UI:FatalErrorMessage')."

\n"); + $oP->error(Dict::Format('UI:Error_Details', $e->getMessage())); + $oP->output(); + + if (MetaModel::IsLogEnabledIssue()) + { + if (MetaModel::IsValidClass('EventIssue')) + { + try + { + $oLog = new EventIssue(); + + $oLog->Set('message', $e->getMessage()); + $oLog->Set('userinfo', ''); + $oLog->Set('issue', 'PHP Exception'); + $oLog->Set('impact', 'Page could not be displayed'); + $oLog->Set('callstack', $e->getTrace()); + $oLog->Set('data', array()); + $oLog->DBInsertNoReload(); + } + catch(Exception $e) + { + IssueLog::Error("Failed to log issue into the DB"); + } + } + + IssueLog::Error($e->getMessage()); + } +} +?> \ No newline at end of file diff --git a/portal/portal.css b/portal/portal.css new file mode 100644 index 0000000000..9bde162750 --- /dev/null +++ b/portal/portal.css @@ -0,0 +1,114 @@ +div#portal #banner { + width: 100%; + height: 60px; + display: inline-block; + vertical-align:middle; + background-color: #f6f6f1; +} + +div#portal #logo { + width: 126px; + background: url(../images/itop-logo.png) 0 0 no-repeat; + margin-left:20px; + margin-right:20px; + height: 60px; + border: 0; + vertical-align: middle; + text-align: center; + display: inline-block; + line-height: 48px; + padding-right:50px; +} + +#portal_menu { + height: 60px; +} + +div.button { + margin-left:20px; + margin-right:20px; + height: 60px; + border: 0; + vertical-align: middle; + text-align: center; + display: inline-block; + line-height: 48px; +} + +a.button , a.button:visited { + color: #1C94C4; + text-decoration: none; + vertical-align: middle; + height: 48px; + line-height: 48px; + display: inline-block; +} + +a.button span { + vertical-align:middle; + margin-right: 20px; + margin-left: 50px; +} + +#close_form_table { + width: 100%; + padding: 20px; +} + +#logoff { + float: right; + background: url(../images/logoff.png) right center no-repeat; +} + +#logoff span { + margin-right: 50px; + margin-left: 20px; +} + +#cancel { + background: url(../images/stop-mid.png) 0 0 no-repeat; +} + +#create { + background: url(../modules/itop-request-mgmt-1.0.0/images/user-request.png) 0 0 no-repeat; +} +#user_info { + background: url(../images/clean-mid.png) 0 0 no-repeat; +} + +#change_pwd { + background: url(../images/password.png) 0 0 no-repeat; +} +#back { + background: url(../images/back.png) 0 0 no-repeat; +} +#back span { + margin-left: 54px; +} +#refresh { + background: url(../images/refresh.png) 0 0 no-repeat; + margin-right: 40px; +} +#refresh span { + margin-left: 54px; + margin-right: 20px; +} + +#content { + margin: 10px; + padding: 10px; + text-align: center; +} +#request_details { + display: inline-block; +} +#request_details table { + border: #f1f1f6 2px solid; +} +#form_details { + display: inline-block; +} +.wizContainer table { + display: inline-block; + text-align: left; +}