From 559de3d38f3556ae45e7853c3813a6383ba7e906 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 15 Sep 2011 10:06:46 +0000 Subject: [PATCH 01/23] Portal reworked (code factorization, allowing for paginated lists) + added the list of closed tickets (+search) SVN:trunk[1577] --- portal/index.php | 1111 ++++++++++++++++++--------------------------- portal/portal.css | 259 +++++++---- 2 files changed, 600 insertions(+), 770 deletions(-) diff --git a/portal/index.php b/portal/index.php index 7462dfaaa1..fa3326c719 100644 --- a/portal/index.php +++ b/portal/index.php @@ -27,54 +27,16 @@ 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; -} +define('SERVICECATEGORY_QUERY', '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'); +define('SERVICE_SUBCATEGORY_QUERY', 'SELECT ServiceSubcategory WHERE service_id = :svc_id'); + +define('VALIDATE_SERVICECATEGORY_QUERY', '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 = :id'); +define('VALIDATE_SERVICESUBCATEGORY_QUERY', 'SELECT ServiceSubcategory AS Sub JOIN Service AS Svc ON Sub.service_id = Svc.id WHERE Svc.org_id=:org_id AND Sub.id=:id'); + +define('ALL_PARAMS', 'from_service_id,org_id,caller_id,service_id,servicesubcategory_id,title,description,impact,urgency,workgroup_id,moreinfo,caller_id,start_date,end_date,duration,impact_duration'); + /** * Displays the portal main menu @@ -83,14 +45,24 @@ function ReadAllParams() */ 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('showongoing', 'Portal:ShowOngoing', './index.php?operation=show_ongoing'); + $oP->AddMenuButton('newrequest', 'Portal:CreateNewRequest', './index.php?operation=create_request'); + $oP->AddMenuButton('showclosed', 'Portal:ShowClosed', './index.php?operation=show_closed'); $oP->AddMenuButton('change_pwd', 'Portal:ChangeMyPassword', './index.php?loginop=change_pwd'); +} - $oP->add("
\n"); - $oP->add("

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

\n"); +/** + * Displays the current tickets + * @param WebPage $oP The current web page + * @return void + */ +function ShowOngoingTickets(WebPage $oP) +{ + $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); @@ -98,22 +70,35 @@ function DisplayMainMenu(WebPage $oP) } /** - * Displays the form to select a Service Id (among the valid ones for the specified user Organization) + * Displays the closed tickets + * @param WebPage $oP The current web page + * @return void + */ +function ShowClosedTickets(WebPage $oP) +{ + $oP->add("
\n"); + //$oP->add("

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

\n"); + ListClosedTickets($oP); + $oP->add("
\n"); +} + +/** + * Displays the form to select a Service Category 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) +function SelectServiceCategory($oP, $oUserOrg) { - // Init forms parameters - $aParameters = ReadAllParams(); + $aParameters = $oP->ReadAllParams(ALL_PARAMS); - $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->WizardFormStart('request_wizard', 1); + + $oP->add("

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

\n"); $oP->add("\n"); + $oSearch = DBObjectSearch::FromOQL(SERVICECATEGORY_QUERY); + $oSet = new CMDBObjectSet($oSearch, array(), array('org_id' => $oUserOrg->GetKey())); while($oService = $oSet->Fetch()) { $id = $oService->GetKey(); @@ -122,24 +107,17 @@ function SelectService($oP, $oUserOrg) { $sChecked = "checked"; } - $oP->p(""); + $oP->p(""); } $oP->add("

"); - $oP->p("

".htmlentities($oService->Get('description'), ENT_QUOTES, 'UTF-8')."

"); + $oP->p("

".$oService->GetAsHTML('description')."

\n"); - DumpHiddenParams($oP, array('service_id'), $aParameters); - $oP->add(""); + + $oP->DumpHiddenParams($aParameters, array('service_id')); $oP->add(""); - $oP->p(""); - $oP->add("
"); - $oP->add("
\n"); - $sMessage = Dict::S('Portal:PleaseSelectOneService'); - $oP->add_ready_script( -<<WizardFormButtons(BUTTON_BACK | BUTTON_NEXT | BUTTON_CANCEL); + $oP->WizardFormEnd(); + $oP->WizardCheckSelectionOnSubmit(Dict::S('Portal:PleaseSelectOneService')); + $oP->add("
\n"); } /** @@ -150,21 +128,23 @@ EOF * @return void */ -function SelectSubService($oP, $oUserOrg) +function SelectServiceSubCategory($oP, $oUserOrg) { - // Init forms parameters - $aParameters = ReadAllParams(); + $aParameters = $oP->ReadAllParams(ALL_PARAMS); + $iSvcId = $aParameters['service_id']; $iDefaultSubSvcId = isset($aParameters['servicesubcategory_id']) ? $aParameters['servicesubcategory_id'] : 0; - $oSearch = DBObjectSearch::FromOQL('SELECT ServiceSubcategory AS ss WHERE ss.service_id = :svc_id'); - $oSet = new CMDBObjectSet($oSearch, array(), array('svc_id' => $iSvcId)); - $oService = MetaModel::GetObject('Service', $iSvcId, false); - if (is_object($oService)) + $iDefaultWizNext = 2; + + $oSearch = DBObjectSearch::FromOQL(SERVICE_SUBCATEGORY_QUERY); + $oSet = new CMDBObjectSet($oSearch, array(), array('svc_id' => $iSvcId, 'org_id' => $oUserOrg->GetKey())); + $oServiceCategory = MetaModel::GetObject('Service', $iSvcId, false); + if (is_object($oServiceCategory)) { $oP->add("
\n"); - $oP->add("

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

\n"); - $oP->add("
\n"); + $oP->add("

".Dict::Format('Portal:SelectSubcategoryFrom_Service', htmlentities($oServiceCategory->GetName(), ENT_QUOTES, 'UTF-8'))."

\n"); + $oP->WizardFormStart('request_wizard', $iDefaultWizNext); $oP->add("\n"); while($oSubService = $oSet->Fetch()) { @@ -174,23 +154,25 @@ function SelectSubService($oP, $oUserOrg) { $sChecked = "checked"; } - $oP->p(""); + + $oP->add(""); + + $oP->add(""); + + $oP->add(""); + $oP->add(""); } - $sMessage = Dict::S('Portal:PleaseSelectAServiceSubCategory'); - $oP->add_ready_script( -<<add("

"); - $oP->p("

".htmlentities($oSubService->Get('description'), ENT_QUOTES, 'UTF-8')."

"); + $oP->add("

"); + $oP->add("
"); + $oP->add("

"); + $oP->add("

".$oSubService->GetAsHTML('description')."

"); + $oP->add("
\n"); - DumpHiddenParams($oP, array('servicesubcategory_id'), $aParameters); - $oP->add(""); + $oP->DumpHiddenParams($aParameters, array('servicesubcategory_id')); $oP->add(""); - $oP->p(" "); - $oP->add("
"); + $oP->WizardFormButtons(BUTTON_BACK | BUTTON_NEXT | BUTTON_CANCEL); + $oP->WizardFormEnd(); + $oP->WizardCheckSelectionOnSubmit(Dict::S('Portal:PleaseSelectAServiceSubCategory')); $oP->add("
\n"); } else @@ -198,6 +180,7 @@ EOF $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 @@ -206,12 +189,29 @@ EOF */ function RequestCreationForm($oP, $oUserOrg) { - $aList = array('request_type', 'title', 'description', 'impact', 'urgency', 'workgroup_id'); - $aParameters = ReadAllParams(); + $oP->add_ready_script( +<<ReadAllParams(ALL_PARAMS); - $oService = MetaModel::GetObject('Service', $aParameters['service_id'], false); - $oSubService = MetaModel::GetObject('ServiceSubcategory', $aParameters['servicesubcategory_id'], false); - if (is_object($oService) && is_object($oSubService)) + $aList = array('title', 'description', 'impact', 'urgency', 'workgroup_id'); + + $sDescription = ''; + if (isset($aParameters['template_id'])) + { + $oTemplate = MetaModel::GetObject('Template', $aParameters['template_id'], false); + if (is_object($oTemplate)) + { + $sDescription = htmlentities($oTemplate->Get('template'), ENT_QUOTES, 'UTF-8'); + } + } + + $oServiceCategory = MetaModel::GetObject('Service', $aParameters['service_id'], false); + $oServiceSubCategory = MetaModel::GetObject('ServiceSubcategory', $aParameters['servicesubcategory_id'], false); + if (is_object($oServiceCategory) && is_object($oServiceSubCategory)) { $oRequest = new UserRequest(); $oRequest->Set('org_id', $oUserOrg->GetKey()); @@ -220,9 +220,10 @@ function RequestCreationForm($oP, $oUserOrg) $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')); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => htmlentities($oServiceCategory->GetName(), ENT_QUOTES, 'UTF-8')); $oAttDef = MetaModel::GetAttributeDef('UserRequest', 'servicesubcategory_id'); - $aDetails[] = array('label' => ''.$oAttDef->GetLabel().'', 'value' => htmlentities($oSubService->GetName(), ENT_QUOTES, 'UTF-8')); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => htmlentities($oServiceSubCategory->GetName(), ENT_QUOTES, 'UTF-8')); + $iFlags = 0; foreach($aList as $sAttCode) { @@ -247,14 +248,10 @@ function RequestCreationForm($oP, $oUserOrg) $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' => '

'); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $sValue); } + $aDetails[] = array('label' => Dict::S('Class:Ticket/Attribute:ticket_log'), 'value' => ''); + $oP->add_linked_script("../js/json.js"); $oP->add_linked_script("../js/forms-json-utils.js"); $oP->add_linked_script("../js/wizardhelper.js"); @@ -264,35 +261,23 @@ function RequestCreationForm($oP, $oUserOrg) $oP->add_linked_script("../js/jquery.blockUI.js"); $oP->add("
\n"); $oP->add("

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

\n"); - $oP->add("
\n"); - $oP->add("
\n"); + $oP->WizardFormStart('request_form', 3); + //$oP->add("\n"); $oP->details($aDetails); - $sTransactionId = utils::GetNewTransactionId(); - $oP->SetTransactionId($sTransactionId); // Must be set before calling the plug-in - 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, true /* edit */); - $oAttPlugin->OnDisplayRelations($oRequest, $oP, true /* edit */); - } + $oAttPlugin = new AttachmentPlugIn(); + $oAttPlugin->OnDisplayRelations($oRequest, $oP, true /* edit */); - $oP->add("
\n"); - DumpHiddenParams($oP, $aList, $aParameters); - $oP->add(""); + $oP->DumpHiddenParams($aParameters, $aList); $oP->add(""); - $oP->add("\n"); - $oP->p(" "); - $oP->add(""); + $oP->WizardFormButtons(BUTTON_BACK | BUTTON_FINISH | BUTTON_CANCEL); + $oP->WizardFormEnd(); $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); @@ -301,29 +286,13 @@ function RequestCreationForm($oP, $oUserOrg) $('#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); + //ShowOngoingTickets($oP); } } @@ -335,43 +304,51 @@ EOF */ function DoCreateRequest($oP, $oUserOrg) { - $aParameters = ReadAllParams(); + $aParameters = $oP->ReadAllParams(ALL_PARAMS); $sTransactionId = utils::ReadPostedParam('transaction_id', ''); if (!utils::IsTransactionValid($sTransactionId)) { $oP->add("

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

\n"); - DisplayMainMenu($oP); + //ShowOngoingTickets($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'])); + // 1) ServiceCategory + $oSearch = DBObjectSearch::FromOQL(VALIDATE_SERVICECATEGORY_QUERY); + $oSet = new CMDBObjectSet($oSearch, array(), array('id' => $aParameters['service_id'], 'org_id' => $oUserOrg->GetKey())); 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().")."); + throw new Exception("Invalid Service Category: id={$aParameters['service_id']} - count: ".$oSet->Count()); } - $oService = $oSet->Fetch(); + $oServiceCategory = $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'] )); + $oSearch = DBObjectSearch::FromOQL(VALIDATE_SERVICESUBCATEGORY_QUERY); + $oSet = new CMDBObjectSet($oSearch, array(), array('service_id' => $aParameters['service_id'], 'id' =>$aParameters['servicesubcategory_id'],'org_id' => $oUserOrg->GetKey() )); if ($oSet->Count() != 1) { // Invalid subcategory - throw new Exception("Invalid ServiceSubcategory: id={$aParameters['servicesubcategory_id']} for service ".$oService->GetName()."({$aParameters['service_id']})"); + throw new Exception("Invalid ServiceSubcategory: id={$aParameters['servicesubcategory_id']} for service category ".$oServiceCategory->GetName()."({$aParameters['service_id']}) - count: ".$oSet->Count()); } - + $oServiceSubCategory = $oSet->Fetch(); + $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) + $aList = array('service_id', 'servicesubcategory_id', 'title', 'description', 'impact'); + $oRequest->UpdateObjectFromPostedForm(); + if (isset($aParameters['moreinfo'])) { - $oRequest->Set($sAttCode, $aParameters[$sAttCode]); + // There is a template, insert it into the description + $oRequest->Set('ticket_log', $aParameters['moreinfo']); } - + + /////$oP->DoUpdateObjectFromPostedForm($oObj); + $oAttPlugin = new AttachmentPlugIn(); + $oAttPlugin->OnFormSubmit($oRequest); + list($bRes, $aIssues) = $oRequest->CheckToWrite(); if ($bRes) { @@ -382,39 +359,9 @@ function DoCreateRequest($oP, $oUserOrg) $iChangeId = $oMyChange->DBInsert(); $oRequest->DBInsertTracked($oMyChange); $oP->add("

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

\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); + + //DisplayObject($oP, $oRequest, $oUserOrg); + ShowOngoingTickets($oP); } else { @@ -431,24 +378,19 @@ function DoCreateRequest($oP, $oUserOrg) */ function CreateRequest(WebPage $oP, Organization $oUserOrg) { - $iStep = utils::ReadParam('step', 0); - - switch($iStep) + switch($oP->GetWizardStep()) { case 0: default: - $oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome'); - SelectService($oP, $oUserOrg); + SelectServiceCategory($oP, $oUserOrg); break; case 1: - $oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome'); - SelectSubService($oP, $oUserOrg); + SelectServiceSubCategory($oP, $oUserOrg); break; case 2: - $oP->AddMenuButton('cancel', 'UI:Button:Cancel', './index.php?operation=welcome'); - RequestCreationForm($oP, $oUserOrg); + RequestCreationForm($oP, $oUserOrg); break; case 3: @@ -457,86 +399,6 @@ function CreateRequest(WebPage $oP, Organization $oUserOrg) } } -/** - * 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 @@ -544,453 +406,303 @@ EOF */ function ListOpenRequests(WebPage $oP) { - $iContactId = UserRights::GetContactId(); - $oContact = MetaModel::GetObject('Contact', $iContactId, false); // false => Can fail - if (is_object($oContact)) + $oUserOrg = GetUserOrg(); + + $sOQL = 'SELECT UserRequest WHERE org_id = :org_id AND status NOT IN ("closed")'; + $oSearch = DBObjectSearch::FromOQL($sOQL); + $iUser = UserRights::GetUserId(); + if ($iUser > 0) { - $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); - } + $oSearch->AddCondition('caller_id', $iUser); + } + $oSet = new CMDBObjectSet($oSearch, array(), array('org_id' => $oUserOrg->GetKey())); + $aZList = array('finalclass', 'title', 'start_date', 'status', 'servicesubcategory_id', 'priority', 'caller_id'); + $oP->DisplaySet($oSet, $aZList, Dict::S('Portal:NoOpenRequest')); } /** - * Lists all the currently Resolved (not "Closed")User Requests for the current user + * Lists all the currently resolved (not yet 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'), - ) + $oUserOrg = GetUserOrg(); - ); - - // 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 ) + $sOQL = 'SELECT UserRequest WHERE org_id = :org_id AND status = "resolved"'; + $oSearch = DBObjectSearch::FromOQL($sOQL); + $iUser = UserRights::GetUserId(); + if ($iUser > 0) { - $aDetails[$sTab] = array(); - ksort($aCols); - $oP->add(''); - foreach($aCols as $sColIndex => $aFieldsets) - { - $oP->add(''); - } - $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('
'); - $oP->add(''.Dict::S($sPreviousLabel).''); - } - $oP->Details($aDetails[$sTab][$sColIndex]); - 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(''.Dict::S($sFieldsetName).''); - } - $oP->Details($aDetails[$sTab][$sColIndex]); - if (!empty($sPreviousLabel)) - { - $oP->add('
'); - } - $oP->add('
'); + $oSearch->AddCondition('caller_id', $iUser); } - - 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 = ''; - while($oDoc = $oSet->Fetch()) - { - $sAttachements .= ''; - } - $sAttachements .= '
'.$oDoc->GetAsHtml('contents').'
'; - $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("
\n"); - $oP->add("GetKey()."\">"); - $oP->add(""); - $sTransactionId = utils::GetNewTransactionId(); - $oP->SetTransactionId($sTransactionId); - $oP->add("\n"); - $oP->add(""); - $oP->add('
'.MetaModel::GetLabel('UserRequest', 'ticket_log').''); - $oAttDef = MetaModel::GetAttributeDef(get_class($oRequest), 'ticket_log'); - $oValue = $oRequest->Get('ticket_log'); - $oP->add($oRequest->GetFormElementForField($oP, get_class($oRequest), 'ticket_log', $oAttDef, $oValue, $sDisplayValue = '', $iId = 'att_ticket_log')); - //$oP->add(GetFieldAsHtml($oRequest, 'ticket_log')); - $oP->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, true /* edit */); - $oAttPlugin->OnDisplayRelations($oRequest, $oP, true /* edit */); - } - $oP->p(''); - $oP->add('
'); - $oP->add_ready_script( -<<add('
'.MetaModel::GetLabel('UserRequest', 'ticket_log').''); - $oP->add(GetFieldAsHtml($oRequest, 'ticket_log')); - $oP->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('
'); + $oSet = new CMDBObjectSet($oSearch, array(), array('org_id' => $oUserOrg->GetKey())); + $aZList = array('finalclass', 'title', 'start_date', 'status', 'servicesubcategory_id', 'priority', 'caller_id'); + $oP->DisplaySet($oSet, $aZList, Dict::S('Portal:NoOpenRequest')); } /** - * Displays a form for the user to provide feedback about a 'resolved' UserRequest and then close the request + * Lists all the currently closed tickets * @param WebPage $oP The current web page - * @param UserRequest $oRequest The object to display * @return void */ -function DisplayResolvedRequestForm($oP, UserRequest $oRequest) +function ListClosedTickets(WebPage $oP) { - $oP->add("
\n"); - $oP->add("
\n"); - $aArgs = array('this' => $oRequest); - $sClass = get_class($oRequest); + $aAttSpecs = array('ref', 'start_date', 'close_date', 'service_id', 'caller_id'); + $aZList = array('title', 'start_date', 'close_date', 'servicesubcategory_id'); - $aDetails = array(); - $aTargetStates = MetaModel::EnumStates($sClass); - $aTargetState = $aTargetStates['closed']; - $aExpectedAttributes = $aTargetState['attribute_list']; - $iFieldIndex = 0; - - foreach($aExpectedAttributes as $sAttCode => $iExpectCode) + $oP->DisplaySearchForm('UserRequest', $aAttSpecs, array('operation' => 'show_closed'), 'search_', false /* => not closed */); + + $oUserOrg = GetUserOrg(); + + // UserRequest + $oSearch = $oP->PostedParamsToFilter('UserRequest', $aAttSpecs, 'search_'); + if(is_null($oSearch)) { - // 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++; - } + $oSearch = new DBObjectSearch('UserRequest'); } - $aStimuli = MetaModel::EnumStimuli($sClass); - $oP->add("

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

"); - $oP->details($aDetails); - $oP->add("GetKey()."\">"); - $oP->add(""); - $oP->add("\n"); - $oP->add(""); - $oP->p(""); - $oP->add("
"); - $oP->add("
\n"); - $oP->add("

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

\n"); - DisplayRequestDetails($oP, $oRequest, false /* bEditMode */); - - $oP->add_ready_script( -<<AddCondition('org_id', $oUserOrg->GetKey()); + $oSearch->AddCondition('status', 'closed'); + $iUser = UserRights::GetUserId(); + if ($iUser > 0) + { + $oSearch->AddCondition('caller_id', $iUser + 12345); + } + $oSet1 = new CMDBObjectSet($oSearch); + $oP->add("

\n"); + $oP->add("

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

\n"); + $oP->DisplaySet($oSet1, $aZList, Dict::S('Portal:NoClosedRequest')); + $oP->add("

\n"); } + /** - * Actually close the request and saves the user's feedback + * Display an object - to be customized * @param WebPage $oP The current web page - * @param UserRequest $oRequest The object to close + * @param Object $oObj Any kind of object + * @param Object $oUserOrg The organization of the logged in user * @return void */ -function DoCloseRequest($oP, UserRequest $oRequest) +function DisplayObject($oP, $oObj, $oUserOrg) { - $sTransactionId = utils::ReadPostedParam('transaction_id', ''); - if (!utils::IsTransactionValid($sTransactionId)) + switch(get_class($oObj)) { - $oP->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::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("

".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()); + case 'UserRequest': + ShowDetailsRequest($oP, $oObj); + break; + + default: + throw new Exception("The class ".get_class($oObj)." is not handled through the portal"); } } -/** - * 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 + * @param Object $oObj The target object * @return void */ -function RequestDetails(WebPage $oP, $id) +function ShowDetailsRequest(WebPage $oP, $oObj) { - $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; - } + $sClass = get_class($oObj); - $iStep = utils::ReadParam('step', $iDefaultStep); - - switch($iStep) + $bIsEscalateButton = false; + $bIsCloseButton = false; + $bEditAttachments = false; + switch($oObj->GetState()) { - 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); + case 'new': + case 'assigned': + case 'frozen': + $aEditAtt = array( + 'ticket_log' => '????' + ); + $bEditAttachments = true; + // disabled - $bIsEscalateButton = true; break; - case 3: - AddComment($oP, $oRequest); + case 'escalated_tto': + case 'escalated_ttr': + $aEditAtt = array( + 'ticket_log' => '????' + ); + $bEditAttachments = true; break; - + + case 'resolved': + $aEditAtt = array( + // non, read-only dans cet etat - 'ticket_log' => '????', + 'user_satisfaction' => '????', + 'user_commment' => '????', + ); + $bIsCloseButton = true; + break; + + case 'closed': + case 'closure_requested': default: - // Should never happen - DisplayMainMenu($oP); + $aEditAtt = array(); + break; } -} -/** - * 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)) +// REFACTORISER LA MISE EN FORME + $oP->add("

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

\n"); + + switch($sClass) { - DisplayMainMenu($oP); - return; + case 'UserIssue': + //$aAttList = array('ref', 'status', 'title', 'description', 'start_date', 'caller_id', 'servicesubcategory_id', 'impact', 'priority', 'agent_id', 'close_date', 'last_update', 'assignment_date', 'resolution_code', 'solution', 'origin', 'time_spent', 'respected_gtr', 'gtr_overdue', 'user_satisfaction', 'user_commment', 'freeze_reason', 'ticket_log'); + $aAttList = array('col:0'=> array('ref','caller_id','impact','perimeter','servicesubcategory_id','title'),'col:1'=> array('status','priority','start_date','resolution_date','last_update','agent_id')); + break; + + case 'UserRequest': + //$aAttList = array('ref', 'status', 'title', 'description', 'requesttype', 'start_date', 'caller_id', 'servicesubcategory_id', 'priority', 'agent_id', 'close_date', 'last_update', 'assignment_date', 'user_satisfaction', 'user_commment', 'freeze_reason', 'ticket_log'); + $aAttList = array('col:0'=> array('ref','caller_id','servicesubcategory_id','title'),'col:1'=> array('status','priority','start_date','resolution_date','last_update','agent_id')); + break; + + default: + //$aAttList = array('ref'); + array('col:0'=> array('ref','service_id','servicesubcategory_id','title'),'col:1'=> array('status','start_date')); + break; } - $sTransactionId = utils::ReadPostedParam('transaction_id', ''); - if (!utils::IsTransactionValid($sTransactionId)) + + // Remove the edited attribute from the shown attributes + // + foreach($aEditAtt as $sAttCode => $foo) { - $oP->add("

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

\n"); - DisplayMainMenu($oP); - return; - } - $sComment = trim(utils::ReadPostedParam('attr_ticket_log', '', 'raw_data')); - if (!empty($sComment)) - { - $oRequest->Set('ticket_log', $sComment); - } - if (class_exists('AttachmentPlugIn')) - { - $oAttPlugin = new AttachmentPlugIn(); - $oAttPlugin->OnFormSubmit($oRequest, ''); - } - if ($oRequest->IsModified()) - { - $oMyChange = MetaModel::NewObject("CMDBChange"); - $oMyChange->Set("date", time()); - $sUserString = CMDBChange::GetCurrentUserName(); - $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"); - - // If there is any trigger for the Portal Update, then activate them - $aClasses = MetaModel::EnumParentClasses(get_class($oRequest), ENUM_PARENT_CLASSES_ALL); - $aClasses = CMDBSource::Quote($aClasses); - $sOQL = "SELECT TriggerOnPortalUpdate WHERE target_class IN (".implode(',', $aClasses).")"; - $oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL)); - while($oTrigger = $oSet->Fetch()) + foreach($aAttList as $col => $aColumn) { - $oTrigger->DoActivate($oRequest->ToArgs('this')); + if (in_array($sAttCode, $aColumn)) + { + if(($index = array_search($sAttCode, $aColumn)) !== false) + { + unset($aAttList[$col][$index]); + } + } } } + + $oP->add("
\n"); + $oP->WizardFormStart('request_form', null); + + $oP->add('
'); + $oP->add(''); + + $oP->add(''); + $oP->add(''); + $oP->add(''); + $oP->add(''); + +// REFACTORISER + $oP->add(''); + $oP->add(''); + $oP->add(''); + + if (count($aEditAtt) > 0) + { + $oP->add(''); + $oP->add('"); } $oP->add("
'); + $oP->DisplayObjectDetails($oObj, $aAttList['col:0']); + $oP->add(''); + $oP->DisplayObjectDetails($oObj, $aAttList['col:1']); + $oP->add('
'); + $oAttPlugin = new AttachmentPlugIn(); + if ($bEditAttachments) + { + $oAttPlugin->EnableDelete(false); + $oAttPlugin->OnDisplayRelations($oObj, $oP, true /* edit */); + } else { - $oP->p("

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

\n"); + $oAttPlugin->OnDisplayRelations($oObj, $oP, false /* read */); } - DisplayMainMenu($oP); + $oP->add('
'); + + //$oP->add("
\n"); + //$oP->add(''); + $oP->add(''); + } + + $oP->add(''); + $oP->add(''); + $oP->add(''); + + $oP->add('
'); + //$oP->add("

".Dict::Format('Portal:CommentsFor_Request', $oObj->GetName())."

\n"); + $oP->add(""); + $oP->add("GetKey()."\">"); + $oP->add(""); + $oP->add("\n"); + $oP->add_script( +<< $foo) + { + $sValue = $oObj->Get($sAttCode); + $sDisplayValue = $oObj->GetEditValue($sAttCode); + $aArgs = array('this' => $oObj, 'formPrefix' => ''); + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + $sInputId = 'input_'.$sAttCode; + $sHTMLValue = "".cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', 0 /*$iFlags*/, $aArgs).''; + + $aEditFields[$sAttCode] = array( + 'label' => MetaModel::GetLabel($sClass, $sAttCode), + 'value' => $sHTMLValue + ); + } + foreach($aEditFields as $sAttCode => $aFieldSpec) + { + if ($sAttCode == 'ticket_log') + { + // Skip, the public log will be displayed below the buttons + continue; + } + $oP->add("
"); + $oP->add('

'.$aFieldSpec['label'].'

'); + $oP->add($aFieldSpec['value']); + $oP->add('
'); + } + // $oP->p(''); + if($bIsCloseButton) + { + $sStimulusCode = 'ev_close'; + $oP->p(''); + } + else + { + $oP->p(''); + } + + if ($bIsEscalateButton) + { + $sStimulusCode = 'ev_timeout'; + $oP->p(''); + } + + $oP->add('
'); + if (isset($aEditFields['ticket_log'])) + { + $oP->add("
"); + $oP->add('

'.$aEditFields['ticket_log']['label'].'

'); + $oP->add($aEditFields['ticket_log']['value']); + $oP->add('
'); + } + else + { + $oP->add('

'.MetaModel::GetLabel($sClass, 'ticket_log').'

'); + $oP->add($oObj->GetAsHTML('ticket_log')); + } + $oP->add('
'); + $oP->add(''); + + $oP->WizardFormEnd(); + $oP->add(''); } /** @@ -1014,6 +726,12 @@ function GetUserOrg() return $oOrg; } +/////////////////////////////////////////////////////////////////////////////// +// +// Main program +// +/////////////////////////////////////////////////////////////////////////////// + try { require_once(APPROOT.'/application/startup.inc.php'); @@ -1024,6 +742,8 @@ try require_once(APPROOT.'/application/loginwebpage.class.inc.php'); LoginWebPage::DoLogin(false /* bMustBeAdmin */, true /* IsAllowedToPortalUsers */); // Check user rights and prompt if needed + ApplicationContext::SetUrlMakerClass('PortalURLMaker'); + $oUserOrg = GetUserOrg(); $sCode = $oUserOrg->Get('code'); @@ -1034,24 +754,57 @@ try } $oP = new PortalWebPage(Dict::S('Portal:Title'), $sAlternateStylesheet); - $oP->add($sAlternateStylesheet); + + $oP->EnableDisconnectButton(true); + $oP->SetWelcomeMessage(Dict::Format('Portal:WelcomeUserOrg', UserRights::GetUserFriendlyName(), $oUserOrg->GetName())); if (is_object($oUserOrg)) { switch($sOperation) { + case 'show_closed': + DisplayMainMenu($oP); + ShowClosedTickets($oP); + break; + case 'create_request': + DisplayMainMenu($oP); CreateRequest($oP, $oUserOrg); break; case 'details': - $iRequestId = utils::ReadParam('id', 0); - RequestDetails($oP, $iRequestId); + DisplayMainMenu($oP); + $oObj = $oP->FindObjectFromArgs(array('UserRequest')); + DisplayObject($oP, $oObj, $oUserOrg); break; - case 'welcome': + case 'update_request': + DisplayMainMenu($oP); + $oObj = $oP->FindObjectFromArgs(array('UserRequest')); + switch(get_class($oObj)) + { + case 'UserRequest': + $aAttList = array('ticket_log', 'user_satisfaction', 'user_commment'); + break; + + default: + throw new Exception("Implementation issue: unexpected class '".get_class($oObj)."'"); + } + try + { + $oP->DoUpdateObjectFromPostedForm($oObj, $aAttList); + } + catch(TransactionException $e) + { + $oP->add("

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

\n"); + } + DisplayObject($oP, $oObj, $oUserOrg); + break; + + case 'show_ongoing': default: DisplayMainMenu($oP); + ShowOngoingTickets($oP); } } $oP->output(); diff --git a/portal/portal.css b/portal/portal.css index 922d85000c..d5b10b2702 100644 --- a/portal/portal.css +++ b/portal/portal.css @@ -7,72 +7,98 @@ html, body { height: 100%; } #content { - margin: 10px; + margin: auto; padding-left: 10px; padding-right: 10px; text-align: center; overflow-y: auto; + no.max-width: 90%; + min-width: 960px; + position: relative; display: block; + clear: both; +} +div#portal #welcome { + display: none; + background: url("./images/dockbar_bg.png") repeat-x scroll 0 0 #97A1AE; + border-bottom: 1px solid #636364; + font-size: 13px; + padding: 1px 5px; + position: relative; + z-index: 300; + text-align:right; + color: #2C2F34; + font-weight: bold; + text-shadow: 1px 1px #FFFFFF; } div#portal #banner { - width: 100%; - height: 60px; + background-color: #F6F6F1; display: block; - vertical-align:middle; - background-color: #f6f6f1; + height: 60px; + vertical-align: middle; + width: 100%; +} +div#portal #logo { + background: url("../images/itop-logo.png") no-repeat scroll 0 0 transparent; + border: 0 none; + display: inline-block; + height: 116px; + line-height: 48px; + margin-left: 20px; + margin-right: 20px; + padding-right: 50px; + text-align: center; + vertical-align: middle; + width: 240px; } -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; -} div#menu { display: block; - width: auto; - position: absolute; - top: 0; - left: 200px; - right: 0px; - line-height: 48px; height: 48px; + left: 200px; + line-height: 48px; + position: absolute; + right: 0; + top: 0; + width: auto; } + #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; +#change_pwd { + background: url("../images/password.png") no-repeat scroll 0 0 transparent; + display: block; + float: right; } -a.button , a.button:visited { +#logoff { + background: url("../images/logoff.png") no-repeat scroll 0 0 transparent; + display: block; + float: right; +} +#logoff span { +} + +div.button { + font-size: 1.1em; + font-weight: bold; + text-decoration: none; +} +a.button, a.button:visited { color: #1C94C4; - text-decoration: none; - vertical-align: middle; + display: inline-block; height: 48px; line-height: 48px; - display: inline-block; + text-decoration: none; + vertical-align: middle; } a.button span { - vertical-align:middle; - margin-right: 20px; margin-left: 50px; + margin-right: 20px; + vertical-align: middle; } #close_form_table { @@ -80,66 +106,117 @@ a.button span { padding: 20px; } -#logoff { - display: block; - float: right; - background: url(../images/logoff.png) right center no-repeat; +#request_details td { + text-align:left; } -#logoff span { - margin-right: 50px; - margin-left: 20px; +#request_details td fieldset{ + xxxheight:100%; } -#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; -} -#request_details { - display: inline-block; - width:800px; - text-align: left; -} -#form_close_request { - display: inline-block; - width:800px; - text-align: left; -} -#request_details_log { - width:774px; -} -#request_details table { - border: #f1f1f6 2px solid; - text-align: left; -} #form_details { display: inline-block; } + .wizContainer table { display: inline-block; text-align: left; } + +#user_request_comment { + width: 30em; + height: 20em; +} + +#buttons { + margin-top: 1em; +} +div#buttons #btn_cancel { + margin-right: 50px; +} + +div#buttons #btn_back { + margin-left: 50px; + margin-right: 5px; +} + +div#buttons #btn_next { + margin-left: 5px; +} + +div#buttons #btn_finish { + margin-left: 5px; +} +table.listContainer { + clear: both; + width: 100%; +} +h1 { + font-weight: bold; + font-weight: bold; + padding: 5px; + margin-top: 5px; +} + +div.DrawerHandle { + display:none; +} +div.HRDrawer { + background: transparent; + border: 0; + height: 0.5em; +} + +.SearchDrawer { + background-color: #F9EDBF; + border: 0; + -moz-border-radius: 4px 4px 4px 4px; +} +.SearchDrawer label { + background: transparent; +} +#open_incidents, #open_requests, #open_changes, #request_details { + margin-bottom: 1em; +} +legend { + background: url("./images/header_bg.png") repeat-x scroll 0 0 #D4D4D4; + border-color: #C8C9CA #9E9E9E #9E9E9E #C8C9CA; + border-style: solid; + border-width: 1px; + font-size: 1.1em; + font-weight: bold; + color: #222222; + font-weight: bold; + text-shadow: 1px 1px #FFFFFF; + padding: 5px; + -moz-border-radius: 4px 4px 4px 4px; + margin-top:0; +} +table.details > tbody > tr > td { + padding-bottom: 5px; + padding-top: 3px; + padding-right: 5px; + border: 0; +} +.label { + font-weight: bold; +} +.caselog { + display:block; + width: 100%; +} +.caselog textarea { + resize: none; +} +.edit_item { + margin-bottom: 1em; +} +div.edit_item span div table { + width: 100%; +} +div.edit_item span div table tbody tr td textarea{ + width: 99%; +} +div#ticket_shortcuts form { + display: inline-block; +} \ No newline at end of file From 7301cb93692303e8dc36fc88dae9167c4206951d Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 15 Sep 2011 10:26:50 +0000 Subject: [PATCH 02/23] Updated the dictionnaries for the latest changes into the portal SVN:trunk[1578] --- dictionaries/de.dictionary.itop.ui.php | 6 + dictionaries/dictionary.itop.ui.php | 8 +- dictionaries/fr.dictionary.itop.ui.php | 6 + dictionaries/hu.dictionary.itop.ui.php | 6 + dictionaries/it.dictionary.itop.ui.php | 1484 +++++++++++---------- dictionaries/ja.dictionary.itop.ui.php | 6 + dictionaries/pt_br.dictionary.itop.ui.php | 6 + dictionaries/ru.dictionary.itop.ui.php | 6 + dictionaries/tr.dictionary.itop.ui.php | 6 + dictionaries/zh.dictionary.itop.ui.php | 6 + 10 files changed, 800 insertions(+), 740 deletions(-) diff --git a/dictionaries/de.dictionary.itop.ui.php b/dictionaries/de.dictionary.itop.ui.php index f94ea4d1b6..7d8d3ed5ca 100644 --- a/dictionaries/de.dictionary.itop.ui.php +++ b/dictionaries/de.dictionary.itop.ui.php @@ -889,10 +889,14 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm 'Portal:Title' => 'iTop-Benutzerportal', 'Portal:Refresh' => 'Neu laden', 'Portal:Back' => 'Zurück', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => 'Einen neuen Request erstellen', 'Portal:ChangeMyPassword' => 'Mein Passwort ändern', 'Portal:Disconnect' => 'Disconnect', 'Portal:OpenRequests' => 'Meine offenen Requests', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => 'Meine gelösten Requests', 'Portal:SelectService' => 'Wählen Sie einen Service aus dem Katalog:', 'Portal:PleaseSelectOneService' => 'Bitte wählen Sie einen Service', @@ -901,7 +905,9 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm 'Portal:DescriptionOfTheRequest' => 'Geben Sie die Beschreibung Ihres Requests ein:', 'Portal:TitleRequestDetailsFor_Request' => 'Details für Request %1$s:', 'Portal:NoOpenRequest' => 'Keinen Request in dieser Kategorie', + 'Portal:NoClosedRequest' => 'Keinen Request in dieser Kategorie', 'Portal:Button:CloseTicket' => 'Dieses Ticket schließen', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Geben Sie einen Kommentar zur Lösung dieses Tickets ein:', 'Portal:ErrorNoContactForThisUser' => 'Fehler: der derzeitige Benutzer wurde nicht einem Kontakt oder einer Person zugewiesen. Bitte kontaktieren Sie Ihren Administrator.', diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php index 607ab56d3d..10a581b9f3 100644 --- a/dictionaries/dictionary.itop.ui.php +++ b/dictionaries/dictionary.itop.ui.php @@ -866,10 +866,14 @@ When associated with a trigger, each action is given an "order" number, specifyi 'Portal:Title' => 'iTop user portal', 'Portal:Refresh' => 'Refresh', 'Portal:Back' => 'Back', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => 'Create a new request', 'Portal:ChangeMyPassword' => 'Change my password', 'Portal:Disconnect' => 'Disconnect', 'Portal:OpenRequests' => 'My open requests', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => 'My resolved requests', 'Portal:SelectService' => 'Select a service from the catalog:', 'Portal:PleaseSelectOneService' => 'Please select one service', @@ -877,8 +881,10 @@ When associated with a trigger, each action is given an "order" number, specifyi 'Portal:PleaseSelectAServiceSubCategory' => 'Please select one sub-category', 'Portal:DescriptionOfTheRequest' => 'Enter the description of your request:', 'Portal:TitleRequestDetailsFor_Request' => 'Details for request %1$s:', - 'Portal:NoOpenRequest' => 'No request in this category.', + 'Portal:NoOpenRequest' => 'No request in this category', + 'Portal:NoClosedRequest' => 'No request in this category', 'Portal:Button:CloseTicket' => 'Close this ticket', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Enter your comments about the resolution of this ticket:', 'Portal:ErrorNoContactForThisUser' => 'Error: the current user is not associated with a Contact/Person. Please contact your administrator.', 'Portal:Attachments' => 'Attachments', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 1a98ec98ae..9cb77328ab 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -716,10 +716,14 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé 'Portal:Title' => 'Portail utilisateur iTop', 'Portal:Refresh' => 'Rafraîchir', 'Portal:Back' => 'Retour', + 'Portal:WelcomeUserOrg' => 'Bienvenue %1$s (%2$s)', + 'Portal:ShowOngoing' => 'Requêtes en cours', + 'Portal:ShowClosed' => 'Requêtes fermées', 'Portal:CreateNewRequest' => 'Créer une nouvelle requête', 'Portal:ChangeMyPassword' => 'Changer mon mot de passe', 'Portal:Disconnect' => 'Déconnexion', 'Portal:OpenRequests' => 'Mes requêtes en cours', + 'Portal:ClosedRequests' => 'Mes requêtes fermées', 'Portal:ResolvedRequests' => 'Mes requêtes résolues', 'Portal:SelectService' => 'Choisissez un service dans le catalogue:', 'Portal:PleaseSelectOneService' => 'Veuillez choisir un service', @@ -728,7 +732,9 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé 'Portal:DescriptionOfTheRequest' => 'Entrez la description de votre requête:', 'Portal:TitleRequestDetailsFor_Request' => 'Détails de votre requête %1$s:', 'Portal:NoOpenRequest' => 'Aucune requête.', + 'Portal:NoClosedRequest' => 'Aucune requête.', 'Portal:Button:CloseTicket' => 'Clôre cette requête', + 'Portal:Button:UpdateRequest' => 'Mettre à jour la requête', 'Portal:EnterYourCommentsOnTicket' => 'Vos commentaires à propos du traitement de cette requête:', 'Portal:ErrorNoContactForThisUser' => 'Erreur: l\'utilisateur courant n\'est pas associé à une Personne/Contact. Contactez votre administrateur.', 'Portal:Attachments' => 'Pièces jointes', diff --git a/dictionaries/hu.dictionary.itop.ui.php b/dictionaries/hu.dictionary.itop.ui.php index 3243ac3fd0..2c0681a7dc 100755 --- a/dictionaries/hu.dictionary.itop.ui.php +++ b/dictionaries/hu.dictionary.itop.ui.php @@ -715,10 +715,14 @@ Akció kiváltó okhoz rendelésekor kap egy sorszámot , amely meghatározza az 'Portal:Title' => 'iTop felhasználói portál', 'Portal:Refresh' => 'Frissítés', 'Portal:Back' => 'Vissza', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => 'Új kérés létrehozása', 'Portal:ChangeMyPassword' => 'Jelszó változtatás', 'Portal:Disconnect' => 'Kilépés', 'Portal:OpenRequests' => 'Nyitott kéréseim', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => 'Megoldott kéréseim', 'Portal:SelectService' => 'Válasszon szolgáltatást a katalógusból:', 'Portal:PleaseSelectOneService' => 'Kérem válasszon egy szolgáltatást', @@ -727,7 +731,9 @@ Akció kiváltó okhoz rendelésekor kap egy sorszámot , amely meghatározza az 'Portal:DescriptionOfTheRequest' => 'Adja meg a kérés leírásást:', 'Portal:TitleRequestDetailsFor_Request' => '%1$s kérés részletei:', 'Portal:NoOpenRequest' => 'A kategóriához nem tartozik nyitott kérés.', + 'Portal:NoClosedRequest' => 'No request in this category', 'Portal:Button:CloseTicket' => 'Hibajegy lezárása', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Adjon megjegyzést a megoldáshoz:', 'Portal:ErrorNoContactForThisUser' => 'Hiba: az aktuális felhasználó nem tartozik egyetlen Kapcsolattartóhoz / Szemályhez sem. Kérem vegye felk a kapcsolatot az adminisztrátorral.', 'Portal:Attachments' => 'Csatolmányok', diff --git a/dictionaries/it.dictionary.itop.ui.php b/dictionaries/it.dictionary.itop.ui.php index 5d338988f9..f1d2efbd52 100644 --- a/dictionaries/it.dictionary.itop.ui.php +++ b/dictionaries/it.dictionary.itop.ui.php @@ -1,191 +1,191 @@ - * @author Romain Quetiez * @author Denis Flaven - - * @licence http://www.opensource.org/licenses/gpl-3.0.html LGPL - */ - -Dict::Add('IT IT', 'Italian', 'Italiano', array( - 'Class:AuditRule' => 'Regola di Audit', - 'Class:AuditRule+' => '', - 'Class:AuditRule/Attribute:name' => 'Nome della regola', - 'Class:AuditRule/Attribute:name+' => '', - 'Class:AuditRule/Attribute:description' => 'Descrizione della regola di Audit', - 'Class:AuditRule/Attribute:description+' => '', - 'Class:AuditRule/Attribute:query' => 'Query da eseguire', - 'Class:AuditRule/Attribute:query+' => '', - 'Class:AuditRule/Attribute:valid_flag' => 'Oggetti validi?', - 'Class:AuditRule/Attribute:valid_flag+' => '', - 'Class:AuditRule/Attribute:valid_flag/Value:false' => 'falso', - 'Class:AuditRule/Attribute:valid_flag/Value:false+' => '', - 'Class:AuditRule/Attribute:valid_flag/Value:true' => 'vero', - 'Class:AuditRule/Attribute:valid_flag/Value:true+' => '', - 'Class:AuditRule/Attribute:category_id' => 'Categoria', - 'Class:AuditRule/Attribute:category_id+' => '', - 'Class:AuditCategory' => 'Categoria di Audit', - 'Class:AuditCategory+' => '', - 'Class:AuditCategory/Attribute:name' => 'Nome della Categoria', - 'Class:AuditCategory/Attribute:name+' => '', - 'Class:AuditCategory/Attribute:description' => 'Descrizione della Categoria di Audit', - 'Class:AuditCategory/Attribute:description+' => '', - 'Class:AuditCategory/Attribute:definition_set' => 'Insieme di definizione', - 'Class:AuditCategory/Attribute:definition_set+' => '', - 'Class:AuditCategory/Attribute:rules_list' => 'Regole di Audit', - 'Class:AuditCategory/Attribute:rules_list+' => '', - 'Class:URP_Profiles' => 'Profilo', - 'Class:URP_Profiles+' => '', - 'Class:URP_Profiles/Attribute:name' => 'Nome', - 'Class:URP_Profiles/Attribute:name+' => '', - 'Class:URP_Profiles/Attribute:description' => 'Descrizione', - 'Class:URP_Profiles/Attribute:description+' => '', - 'Class:URP_Profiles/Attribute:user_list' => 'Utenti', - 'Class:URP_Profiles/Attribute:user_list+' => '', - 'Class:URP_UserProfile' => 'Utente da Profilare', - 'Class:URP_UserProfile+' => '', - 'Class:URP_UserProfile/Attribute:userid' => 'Utente', - 'Class:URP_UserProfile/Attribute:userid+' => '', - 'Class:URP_UserProfile/Attribute:profileid' => 'Profilo', - 'Class:URP_UserProfile/Attribute:profileid+' => '', - 'Class:URP_UserProfile/Attribute:reason' => 'Motivo', - 'Class:URP_UserProfile/Attribute:reason+' => '', - 'Class:URP_UserOrg' => 'Organizzazione dell\'utente', - 'Class:URP_UserOrg+' => '', - 'Class:URP_UserOrg/Attribute:userid' => 'Utente', - 'Class:URP_UserOrg/Attribute:userid+' => '', - 'Class:URP_UserOrg/Attribute:allowed_org_id' => 'Organizazione', - 'Class:URP_UserOrg/Attribute:allowed_org_id+' => '', - 'Class:URP_UserOrg/Attribute:reason' => 'Motivo', - 'Class:URP_UserOrg/Attribute:reason+' => '', - 'Class:URP_ActionGrant' => 'azione_autorizzazione', - 'Class:URP_ActionGrant+' => '', - 'Class:URP_ActionGrant/Attribute:profileid' => 'Profilo', - 'Class:URP_ActionGrant/Attribute:profileid+' => '', - 'Class:URP_ActionGrant/Attribute:class' => 'Classe', - 'Class:URP_ActionGrant/Attribute:class+' => '', - 'Class:URP_ActionGrant/Attribute:permission' => 'Autorizzazione', - 'Class:URP_ActionGrant/Attribute:permission+' => '', - 'Class:URP_ActionGrant/Attribute:permission/Value:no' => 'no', - 'Class:URP_ActionGrant/Attribute:permission/Value:no+' => '', - 'Class:URP_ActionGrant/Attribute:permission/Value:yes' => 'yes', - 'Class:URP_ActionGrant/Attribute:permission/Value:yes+' => '', - 'Class:URP_ActionGrant/Attribute:action' => 'Azione', - 'Class:URP_ActionGrant/Attribute:action+' => '', - 'Class:URP_StimulusGrant' => 'stimulus_autorizzazione', - 'Class:URP_StimulusGrant+' => '', - 'Class:URP_StimulusGrant/Attribute:profileid' => 'Profilo', - 'Class:URP_StimulusGrant/Attribute:profileid+' => '', - 'Class:URP_StimulusGrant/Attribute:class' => 'Classe', - 'Class:URP_StimulusGrant/Attribute:class+' => '', - 'Class:URP_StimulusGrant/Attribute:permission' => 'Autorizzazione', - 'Class:URP_StimulusGrant/Attribute:permission+' => '', - 'Class:URP_StimulusGrant/Attribute:permission/Value:no' => 'no', - 'Class:URP_StimulusGrant/Attribute:permission/Value:no+' => '', - 'Class:URP_StimulusGrant/Attribute:permission/Value:yes' => 'yes', - 'Class:URP_StimulusGrant/Attribute:permission/Value:yes+' => '', - 'Class:URP_StimulusGrant/Attribute:stimulus' => 'Stimulus', - 'Class:URP_StimulusGrant/Attribute:stimulus+' => '', - 'Class:URP_AttributeGrant' => 'attributo_autorizzazione', - 'Class:URP_AttributeGrant+' => '', - 'Class:URP_AttributeGrant/Attribute:actiongrantid' => 'Azione di sovvenzione', - 'Class:URP_AttributeGrant/Attribute:actiongrantid+' => '', - 'Class:URP_AttributeGrant/Attribute:attcode' => 'Attributo', - 'Class:URP_AttributeGrant/Attribute:attcode+' => '', - 'Class:AuditRule/Attribute:category_name' => 'Categoria', - 'Class:AuditRule/Attribute:category_name+' => '', - 'Class:User' => 'User~~', - 'Class:User+' => '', - 'Class:User/Attribute:finalclass' => 'Tipo di account', - 'Class:User/Attribute:finalclass+' => '', - 'Class:User/Attribute:contactid' => 'Contatto (persona)', - 'Class:User/Attribute:contactid+' => '', - 'Class:User/Attribute:last_name' => 'Cognome', - 'Class:User/Attribute:last_name+' => '', - 'Class:User/Attribute:first_name' => 'Nome', - 'Class:User/Attribute:first_name+' => '', - 'Class:User/Attribute:email' => 'Email', - 'Class:User/Attribute:email+' => '', - 'Class:User/Attribute:login' => 'Login', - 'Class:User/Attribute:login+' => '', - 'Class:User/Attribute:language' => 'Lingua', - 'Class:User/Attribute:language+' => '', - 'Class:User/Attribute:language/Value:EN US' => 'Inglese', - 'Class:User/Attribute:language/Value:EN US+' => '', - 'Class:User/Attribute:language/Value:FR FR' => 'Francese', - 'Class:User/Attribute:language/Value:FR FR+' => '', - 'Class:User/Attribute:profile_list' => 'Profili', - 'Class:User/Attribute:profile_list+' => '', - 'Class:User/Attribute:allowed_org_list' => 'Organizzazioni autorizzate', - 'Class:User/Attribute:allowed_org_list+' => '', - 'Class:User/Error:LoginMustBeUnique' => 'Login deve essere unico - "%1s" è già utilizzato.~~', - 'Class:User/Error:AtLeastOneProfileIsNeeded' => 'Almeno un profilo deve essere assegnato a questo utente', - 'Class:URP_Dimensions' => 'dimensione', - 'Class:URP_Dimensions+' => '', - 'Class:URP_Dimensions/Attribute:name' => 'Nome', - 'Class:URP_Dimensions/Attribute:name+' => '', - 'Class:URP_Dimensions/Attribute:description' => 'Descrizione', - 'Class:URP_Dimensions/Attribute:description+' => '', - 'Class:URP_Dimensions/Attribute:type' => 'Tipo', - 'Class:URP_Dimensions/Attribute:type+' => '', - 'Class:URP_UserProfile/Attribute:userlogin' => 'Login', - 'Class:URP_UserProfile/Attribute:userlogin+' => '', - 'Class:URP_UserProfile/Attribute:profile' => 'Profilo', - 'Class:URP_UserProfile/Attribute:profile+' => '', - 'Class:URP_UserOrg/Attribute:userlogin' => 'Login', - 'Class:URP_UserOrg/Attribute:userlogin+' => '', - 'Class:URP_UserOrg/Attribute:allowed_org_name' => 'Organizazione', - 'Class:URP_UserOrg/Attribute:allowed_org_name+' => '', - 'Class:URP_ProfileProjection' => 'profilo_proiezione', - 'Class:URP_ProfileProjection+' => '', - 'Class:URP_ProfileProjection/Attribute:dimensionid' => 'Dimensione', - 'Class:URP_ProfileProjection/Attribute:dimensionid+' => '', - 'Class:URP_ProfileProjection/Attribute:dimension' => 'Dimensione', - 'Class:URP_ProfileProjection/Attribute:dimension+' => '', - 'Class:URP_ProfileProjection/Attribute:profileid' => 'Profilo', - 'Class:URP_ProfileProjection/Attribute:profileid+' => '', - 'Class:URP_ProfileProjection/Attribute:profile' => 'Profilo', - 'Class:URP_ProfileProjection/Attribute:profile+' => '', - 'Class:URP_ProfileProjection/Attribute:value' => 'Valore dell\'espressione', - 'Class:URP_ProfileProjection/Attribute:value+' => '', - 'Class:URP_ProfileProjection/Attribute:attribute' => 'Attributo', - 'Class:URP_ProfileProjection/Attribute:attribute+' => '', - 'Class:URP_ClassProjection' => 'classe_proiezione', - 'Class:URP_ClassProjection+' => '', - 'Class:URP_ClassProjection/Attribute:dimensionid' => 'Dimensione', - 'Class:URP_ClassProjection/Attribute:dimensionid+' => '', - 'Class:URP_ClassProjection/Attribute:dimension' => 'Dimensione', - 'Class:URP_ClassProjection/Attribute:dimension+' => '', - 'Class:URP_ClassProjection/Attribute:class' => 'Classe', - 'Class:URP_ClassProjection/Attribute:class+' => '', - 'Class:URP_ClassProjection/Attribute:value' => 'Valore dell\'espressione', - 'Class:URP_ClassProjection/Attribute:value+' => '', - 'Class:URP_ClassProjection/Attribute:attribute' => 'Attributo', - 'Class:URP_ClassProjection/Attribute:attribute+' => '', - 'Class:URP_ActionGrant/Attribute:profile' => 'Profilo', - 'Class:URP_ActionGrant/Attribute:profile+' => '', - 'Class:URP_StimulusGrant/Attribute:profile' => 'Profilo', - 'Class:URP_StimulusGrant/Attribute:profile+' => '', - 'Menu:WelcomeMenu' => 'Benveuto', - 'Menu:WelcomeMenu+' => '', - 'Menu:WelcomeMenuPage' => 'Benvenuto', - 'Menu:WelcomeMenuPage+' => '', - 'UI:WelcomeMenu:Title' => 'Benveuto su iTop', + + * @licence http://www.opensource.org/licenses/gpl-3.0.html LGPL + */ + +Dict::Add('IT IT', 'Italian', 'Italiano', array( + 'Class:AuditRule' => 'Regola di Audit', + 'Class:AuditRule+' => '', + 'Class:AuditRule/Attribute:name' => 'Nome della regola', + 'Class:AuditRule/Attribute:name+' => '', + 'Class:AuditRule/Attribute:description' => 'Descrizione della regola di Audit', + 'Class:AuditRule/Attribute:description+' => '', + 'Class:AuditRule/Attribute:query' => 'Query da eseguire', + 'Class:AuditRule/Attribute:query+' => '', + 'Class:AuditRule/Attribute:valid_flag' => 'Oggetti validi?', + 'Class:AuditRule/Attribute:valid_flag+' => '', + 'Class:AuditRule/Attribute:valid_flag/Value:false' => 'falso', + 'Class:AuditRule/Attribute:valid_flag/Value:false+' => '', + 'Class:AuditRule/Attribute:valid_flag/Value:true' => 'vero', + 'Class:AuditRule/Attribute:valid_flag/Value:true+' => '', + 'Class:AuditRule/Attribute:category_id' => 'Categoria', + 'Class:AuditRule/Attribute:category_id+' => '', + 'Class:AuditCategory' => 'Categoria di Audit', + 'Class:AuditCategory+' => '', + 'Class:AuditCategory/Attribute:name' => 'Nome della Categoria', + 'Class:AuditCategory/Attribute:name+' => '', + 'Class:AuditCategory/Attribute:description' => 'Descrizione della Categoria di Audit', + 'Class:AuditCategory/Attribute:description+' => '', + 'Class:AuditCategory/Attribute:definition_set' => 'Insieme di definizione', + 'Class:AuditCategory/Attribute:definition_set+' => '', + 'Class:AuditCategory/Attribute:rules_list' => 'Regole di Audit', + 'Class:AuditCategory/Attribute:rules_list+' => '', + 'Class:URP_Profiles' => 'Profilo', + 'Class:URP_Profiles+' => '', + 'Class:URP_Profiles/Attribute:name' => 'Nome', + 'Class:URP_Profiles/Attribute:name+' => '', + 'Class:URP_Profiles/Attribute:description' => 'Descrizione', + 'Class:URP_Profiles/Attribute:description+' => '', + 'Class:URP_Profiles/Attribute:user_list' => 'Utenti', + 'Class:URP_Profiles/Attribute:user_list+' => '', + 'Class:URP_UserProfile' => 'Utente da Profilare', + 'Class:URP_UserProfile+' => '', + 'Class:URP_UserProfile/Attribute:userid' => 'Utente', + 'Class:URP_UserProfile/Attribute:userid+' => '', + 'Class:URP_UserProfile/Attribute:profileid' => 'Profilo', + 'Class:URP_UserProfile/Attribute:profileid+' => '', + 'Class:URP_UserProfile/Attribute:reason' => 'Motivo', + 'Class:URP_UserProfile/Attribute:reason+' => '', + 'Class:URP_UserOrg' => 'Organizzazione dell\'utente', + 'Class:URP_UserOrg+' => '', + 'Class:URP_UserOrg/Attribute:userid' => 'Utente', + 'Class:URP_UserOrg/Attribute:userid+' => '', + 'Class:URP_UserOrg/Attribute:allowed_org_id' => 'Organizazione', + 'Class:URP_UserOrg/Attribute:allowed_org_id+' => '', + 'Class:URP_UserOrg/Attribute:reason' => 'Motivo', + 'Class:URP_UserOrg/Attribute:reason+' => '', + 'Class:URP_ActionGrant' => 'azione_autorizzazione', + 'Class:URP_ActionGrant+' => '', + 'Class:URP_ActionGrant/Attribute:profileid' => 'Profilo', + 'Class:URP_ActionGrant/Attribute:profileid+' => '', + 'Class:URP_ActionGrant/Attribute:class' => 'Classe', + 'Class:URP_ActionGrant/Attribute:class+' => '', + 'Class:URP_ActionGrant/Attribute:permission' => 'Autorizzazione', + 'Class:URP_ActionGrant/Attribute:permission+' => '', + 'Class:URP_ActionGrant/Attribute:permission/Value:no' => 'no', + 'Class:URP_ActionGrant/Attribute:permission/Value:no+' => '', + 'Class:URP_ActionGrant/Attribute:permission/Value:yes' => 'yes', + 'Class:URP_ActionGrant/Attribute:permission/Value:yes+' => '', + 'Class:URP_ActionGrant/Attribute:action' => 'Azione', + 'Class:URP_ActionGrant/Attribute:action+' => '', + 'Class:URP_StimulusGrant' => 'stimulus_autorizzazione', + 'Class:URP_StimulusGrant+' => '', + 'Class:URP_StimulusGrant/Attribute:profileid' => 'Profilo', + 'Class:URP_StimulusGrant/Attribute:profileid+' => '', + 'Class:URP_StimulusGrant/Attribute:class' => 'Classe', + 'Class:URP_StimulusGrant/Attribute:class+' => '', + 'Class:URP_StimulusGrant/Attribute:permission' => 'Autorizzazione', + 'Class:URP_StimulusGrant/Attribute:permission+' => '', + 'Class:URP_StimulusGrant/Attribute:permission/Value:no' => 'no', + 'Class:URP_StimulusGrant/Attribute:permission/Value:no+' => '', + 'Class:URP_StimulusGrant/Attribute:permission/Value:yes' => 'yes', + 'Class:URP_StimulusGrant/Attribute:permission/Value:yes+' => '', + 'Class:URP_StimulusGrant/Attribute:stimulus' => 'Stimulus', + 'Class:URP_StimulusGrant/Attribute:stimulus+' => '', + 'Class:URP_AttributeGrant' => 'attributo_autorizzazione', + 'Class:URP_AttributeGrant+' => '', + 'Class:URP_AttributeGrant/Attribute:actiongrantid' => 'Azione di sovvenzione', + 'Class:URP_AttributeGrant/Attribute:actiongrantid+' => '', + 'Class:URP_AttributeGrant/Attribute:attcode' => 'Attributo', + 'Class:URP_AttributeGrant/Attribute:attcode+' => '', + 'Class:AuditRule/Attribute:category_name' => 'Categoria', + 'Class:AuditRule/Attribute:category_name+' => '', + 'Class:User' => 'User~~', + 'Class:User+' => '', + 'Class:User/Attribute:finalclass' => 'Tipo di account', + 'Class:User/Attribute:finalclass+' => '', + 'Class:User/Attribute:contactid' => 'Contatto (persona)', + 'Class:User/Attribute:contactid+' => '', + 'Class:User/Attribute:last_name' => 'Cognome', + 'Class:User/Attribute:last_name+' => '', + 'Class:User/Attribute:first_name' => 'Nome', + 'Class:User/Attribute:first_name+' => '', + 'Class:User/Attribute:email' => 'Email', + 'Class:User/Attribute:email+' => '', + 'Class:User/Attribute:login' => 'Login', + 'Class:User/Attribute:login+' => '', + 'Class:User/Attribute:language' => 'Lingua', + 'Class:User/Attribute:language+' => '', + 'Class:User/Attribute:language/Value:EN US' => 'Inglese', + 'Class:User/Attribute:language/Value:EN US+' => '', + 'Class:User/Attribute:language/Value:FR FR' => 'Francese', + 'Class:User/Attribute:language/Value:FR FR+' => '', + 'Class:User/Attribute:profile_list' => 'Profili', + 'Class:User/Attribute:profile_list+' => '', + 'Class:User/Attribute:allowed_org_list' => 'Organizzazioni autorizzate', + 'Class:User/Attribute:allowed_org_list+' => '', + 'Class:User/Error:LoginMustBeUnique' => 'Login deve essere unico - "%1s" è già utilizzato.~~', + 'Class:User/Error:AtLeastOneProfileIsNeeded' => 'Almeno un profilo deve essere assegnato a questo utente', + 'Class:URP_Dimensions' => 'dimensione', + 'Class:URP_Dimensions+' => '', + 'Class:URP_Dimensions/Attribute:name' => 'Nome', + 'Class:URP_Dimensions/Attribute:name+' => '', + 'Class:URP_Dimensions/Attribute:description' => 'Descrizione', + 'Class:URP_Dimensions/Attribute:description+' => '', + 'Class:URP_Dimensions/Attribute:type' => 'Tipo', + 'Class:URP_Dimensions/Attribute:type+' => '', + 'Class:URP_UserProfile/Attribute:userlogin' => 'Login', + 'Class:URP_UserProfile/Attribute:userlogin+' => '', + 'Class:URP_UserProfile/Attribute:profile' => 'Profilo', + 'Class:URP_UserProfile/Attribute:profile+' => '', + 'Class:URP_UserOrg/Attribute:userlogin' => 'Login', + 'Class:URP_UserOrg/Attribute:userlogin+' => '', + 'Class:URP_UserOrg/Attribute:allowed_org_name' => 'Organizazione', + 'Class:URP_UserOrg/Attribute:allowed_org_name+' => '', + 'Class:URP_ProfileProjection' => 'profilo_proiezione', + 'Class:URP_ProfileProjection+' => '', + 'Class:URP_ProfileProjection/Attribute:dimensionid' => 'Dimensione', + 'Class:URP_ProfileProjection/Attribute:dimensionid+' => '', + 'Class:URP_ProfileProjection/Attribute:dimension' => 'Dimensione', + 'Class:URP_ProfileProjection/Attribute:dimension+' => '', + 'Class:URP_ProfileProjection/Attribute:profileid' => 'Profilo', + 'Class:URP_ProfileProjection/Attribute:profileid+' => '', + 'Class:URP_ProfileProjection/Attribute:profile' => 'Profilo', + 'Class:URP_ProfileProjection/Attribute:profile+' => '', + 'Class:URP_ProfileProjection/Attribute:value' => 'Valore dell\'espressione', + 'Class:URP_ProfileProjection/Attribute:value+' => '', + 'Class:URP_ProfileProjection/Attribute:attribute' => 'Attributo', + 'Class:URP_ProfileProjection/Attribute:attribute+' => '', + 'Class:URP_ClassProjection' => 'classe_proiezione', + 'Class:URP_ClassProjection+' => '', + 'Class:URP_ClassProjection/Attribute:dimensionid' => 'Dimensione', + 'Class:URP_ClassProjection/Attribute:dimensionid+' => '', + 'Class:URP_ClassProjection/Attribute:dimension' => 'Dimensione', + 'Class:URP_ClassProjection/Attribute:dimension+' => '', + 'Class:URP_ClassProjection/Attribute:class' => 'Classe', + 'Class:URP_ClassProjection/Attribute:class+' => '', + 'Class:URP_ClassProjection/Attribute:value' => 'Valore dell\'espressione', + 'Class:URP_ClassProjection/Attribute:value+' => '', + 'Class:URP_ClassProjection/Attribute:attribute' => 'Attributo', + 'Class:URP_ClassProjection/Attribute:attribute+' => '', + 'Class:URP_ActionGrant/Attribute:profile' => 'Profilo', + 'Class:URP_ActionGrant/Attribute:profile+' => '', + 'Class:URP_StimulusGrant/Attribute:profile' => 'Profilo', + 'Class:URP_StimulusGrant/Attribute:profile+' => '', + 'Menu:WelcomeMenu' => 'Benveuto', + 'Menu:WelcomeMenu+' => '', + 'Menu:WelcomeMenuPage' => 'Benvenuto', + 'Menu:WelcomeMenuPage+' => '', + 'UI:WelcomeMenu:Title' => 'Benveuto su iTop', 'UI:WelcomeMenu:LeftBlock' => '

iTop è un completo Portale Funzionale IT, Open Source.

    Esso include:
  • Un completo CMDB (Configuration management database) per documentare e gestire l\'IT di inventario.
  • @@ -195,7 +195,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(
  • Un modulo di interruzione per documentare tutte le interruzioni pianificate e notificare gli opportuni contatti.
  • Un cruscotto per ottenere rapidamente una panoramica del sistema IT.
-

Tutti i moduli possono essere installati, passo dopo passo, indipendentemente l\'uno dall\'altro.

', +

Tutti i moduli possono essere installati, passo dopo passo, indipendentemente l\'uno dall\'altro.

', 'UI:WelcomeMenu:RightBlock' => '

iTop è fornitore di servizi di orientamento, che consente ai progettisti di gestire più o organizzazioni o clienti con facilità.

    >iTop, offre un set ricco di funzionalità dei processi di business che:
  • Migliora l\'efficacia di gestione IT
  • @@ -206,463 +206,463 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array(

    iTop è completamente aperto per essere integrato all\'interno della vostra infrastruttura di gestione dell\'IT.

      L\'adozione di questa nuova generazione di portale funzionale IT vi aiuterà a: -
    • Meglio gestire un ambiente IT sempre più complesso.
    • -
    • Implementare i processi ITIL al proprio ritmo.
    • -
    • Gestire la risorsa più importante della tua IT: Documentazione.
    • +
    • Meglio gestire un ambiente IT sempre più complesso.
    • +
    • Implementare i processi ITIL al proprio ritmo.
    • +
    • Gestire la risorsa più importante della tua IT: Documentazione.
    -

    ', - 'UI:WelcomeMenu:AllOpenRequests' => 'Apri le richieste: %1$d', - 'UI:WelcomeMenu:MyCalls' => 'Le mie richieste', - 'UI:WelcomeMenu:OpenIncidents' => 'Apri gli incidenti: %1$d', - 'UI:WelcomeMenu:AllConfigItems' => 'Elementi di Configurazione (CI): %1$d', - 'UI:WelcomeMenu:MyIncidents' => 'Incidenti assegnati a me', - 'UI:AllOrganizations' => ' Tutte le Organizzazioni ', - 'UI:YourSearch' => 'La tua Cerca', - 'UI:LoggedAsMessage' => 'Logged come %1$s', - 'UI:LoggedAsMessage+Admin' => 'Logged come %1$s (Amministratore)', - 'UI:Button:Logoff' => 'Log off', - 'UI:Button:GlobalSearch' => 'Cerca', - 'UI:Button:Search' => ' Cerca', - 'UI:Button:Query' => ' Domanda', - 'UI:Button:Ok' => 'Ok', - 'UI:Button:Cancel' => 'Cancella', - 'UI:Button:Apply' => 'Applica', - 'UI:Button:Back' => ' << Indietro', - 'UI:Button:Restart' => ' |<< Riavvia', - 'UI:Button:Next' => ' Prossimo >> ', - 'UI:Button:Finish' => ' Fine', - 'UI:Button:DoImport' => ' Esegui le Imporazioni ! ~~', - 'UI:Button:Done' => ' Fatto', - 'UI:Button:SimulateImport' => ' Simula l\'Importazione ~~', - 'UI:Button:Test' => 'Testa!', - 'UI:Button:Evaluate' => ' Valuta', - 'UI:Button:AddObject' => ' Aggiungi... ~~', - 'UI:Button:BrowseObjects' => ' Sfoglia... ~~', - 'UI:Button:Add' => ' Aggiungi ~~', - 'UI:Button:AddToList' => ' << Aggiungi ~~', - 'UI:Button:RemoveFromList' => ' Rimuovi >> ~~', - 'UI:Button:FilterList' => ' Filtra... ~~', - 'UI:Button:Create' => ' Crea ~~', - 'UI:Button:Delete' => ' Cancella ! ~~', - 'UI:Button:ChangePassword' => ' Cambia Password ~~', - 'UI:Button:ResetPassword' => ' Resetta Password ~~', - 'UI:SearchToggle' => 'Cerca', - 'UI:ClickToCreateNew' => 'Crea un nuovo %1$s~~', - 'UI:SearchFor_Class' => 'Cerca l\'oggetto %1$s', - 'UI:NoObjectToDisplay' => 'Nessun oggetto da mostrare.', - 'UI:Error:MandatoryTemplateParameter_object_id' => 'Object_id parametro è obbligatorio quando link_attr è specificato. Verificare la definizione del modello di display.', - 'UI:Error:MandatoryTemplateParameter_target_attr' => 'Target_attr parametro è obbligatorio quando link_attr è specificato. Verificare la definizione del modello di display.', - 'UI:Error:MandatoryTemplateParameter_group_by' => 'Il parametro è group_by obbligatoria. Verificare la definizione del modello di display.', - 'UI:Error:InvalidGroupByFields' => 'Elenco di campi non valido per il raggruppamento: "%1$s".', - 'UI:Error:UnsupportedStyleOfBlock' => 'Errore: Stile non supportato di blocco: "%1$s".', - 'UI:Error:IncorrectLinkDefinition_LinkedClass_Class' => 'Errata definizione di link: la classe di oggetti da gestire: %1$s non è stato trovato come chiave esterna nella classe %2$s', - 'UI:Error:Object_Class_Id_NotFound' => 'Oggetto: %1$s:%2$d non trovato.', - 'UI:Error:WizardCircularReferenceInDependencies' => 'Errore: Riferimento circolare nelle dipendenze tra i campi, controllare il modello di dati.', - 'UI:Error:UploadedFileTooBig' => 'Il file caricato è troppo grande. (dimensione massima consentita è di %1$s). Verificare di configurazione di PHP per upload_max_filesize e post_max_size.', - 'UI:Error:UploadedFileTruncated.' => 'Il file caricato è stata troncato !', - 'UI:Error:NoTmpDir' => 'La directory temporanea non è definita.', - 'UI:Error:CannotWriteToTmp_Dir' => 'Impossibile scrivere il file temporaneo sul disco. upload_tmp_dir = "%1$s".', - 'UI:Error:UploadStoppedByExtension_FileName' => 'Caricamento fermato per estensione. (Nome del file originale = "%1$s").', - 'UI:Error:UploadFailedUnknownCause_Code' => 'Il caricamento del file non riuscito, causa sconosciuta. (Codice errore = "%1$s").', - 'UI:Error:1ParametersMissing' => 'Errore: il seguente parametro deve essere specificato per questa operazione: %1$s.', - 'UI:Error:2ParametersMissing' => 'Errore: i seguenti parametri devono essere specificati per questa operazione: %1$s e %2$s.', - 'UI:Error:3ParametersMissing' => 'Errore: i seguenti parametri devono essere specificati per questa operazione: %1$s, %2$s e %3$s.', - 'UI:Error:4ParametersMissing' => 'Errore: i seguenti parametri devono essere specificati per questa operazione: %1$s, %2$s, %3$s e %4$s.', - 'UI:Error:IncorrectOQLQuery_Message' => 'Errore: errata OQL query: %1$s', - 'UI:Error:AnErrorOccuredWhileRunningTheQuery_Message' => 'Si è verificato un errore durante l\'esecuzione della query: %1$s', - 'UI:Error:ObjectAlreadyUpdated' => 'Errore: l\'oggetto è già stato aggiornato.', - 'UI:Error:ObjectCannotBeUpdated' => 'Errore: oggetto non può essere aggiornato.', - 'UI:Error:ObjectsAlreadyDeleted' => 'Errore: gli oggetti sono già stati eliminati!', - 'UI:Error:BulkDeleteNotAllowedOn_Class' => 'Non hai i permessi per eseguire una eliminazione collettiva degli oggetti della classe %1$s', - 'UI:Error:DeleteNotAllowedOn_Class' => 'Non ti è permesso di eliminare gli oggetti della classe %1$s', - 'UI:Error:BulkModifyNotAllowedOn_Class' => 'Non hai i permessi per eseguire un aggiornamento collettivo degli oggetti della classe %1$s', - 'UI:Error:ObjectAlreadyCloned' => 'Errore: l\'oggetto è già stato clonato!', - 'UI:Error:ObjectAlreadyCreated' => 'Errore: l\'oggetto è già stato creato!', - 'UI:Error:Invalid_Stimulus_On_Object_In_State' => 'Errore: stimolo non valido "%1$s" su un oggetto %2$s nello stato "%3$s".', - - 'UI:GroupBy:Count' => 'Conteggio', - 'UI:GroupBy:Count+' => '', - 'UI:CountOfObjects' => '%1$d oggetti corrispondenti ai criteri.', - 'UI_CountOfObjectsShort' => '%1$d oggetti.', - 'UI:NoObject_Class_ToDisplay' => 'No %1$s da visualizzare', - 'UI:History:LastModified_On_By' => 'Ultima modifica %1$s da %2$s.', - 'UI:HistoryTab' => 'Storia', - 'UI:NotificationsTab' => 'Notifiche', - 'UI:History:BulkImports' => 'Storia', - 'UI:History:BulkImports+' => 'Elenco delle importazioni CSV (primo ultimo)', - 'UI:History:BulkImportDetails' => 'Modifiche derivanti dai importazione CSV eseguita su %1$s (da %2$s)', - 'UI:History:Date' => 'Data', - 'UI:History:Date+' => '', - 'UI:History:User' => 'Utente', - 'UI:History:User+' => '', - 'UI:History:Changes' => 'Modifiche', - 'UI:History:Changes+' => '', - 'UI:History:StatsCreations' => 'Creato', - 'UI:History:StatsCreations+' => '', - 'UI:History:StatsModifs' => 'Modificato', - 'UI:History:StatsModifs+' => '', - 'UI:History:StatsDeletes' => 'Cancellato', - 'UI:History:StatsDeletes+' => '', - 'UI:Loading' => 'Caricamento...', - 'UI:Menu:Actions' => 'Azioni', - 'UI:Menu:OtherActions' => 'Altre Azioni', - 'UI:Menu:New' => 'Nuovo...', - 'UI:Menu:Add' => 'Aggiungi...', - 'UI:Menu:Manage' => 'Gestischi...', - 'UI:Menu:EMail' => 'eMail', - 'UI:Menu:CSVExport' => 'CSV Export', - 'UI:Menu:Modify' => 'Modifica...', - 'UI:Menu:Delete' => 'Cancella...', - 'UI:Menu:BulkDelete' => 'Cancella...', - 'UI:UndefinedObject' => 'non definito', - 'UI:Document:OpenInNewWindow:Download' => 'Apri in una nuova finestra: %1$s, Scarica: %2$s', - 'UI:SelectAllToggle+' => '', - 'UI:TruncatedResults' => '%1$d oggetti visualizzati su %2$d', - 'UI:DisplayAll' => 'Mostra tutto', - 'UI:CollapseList' => 'Collassa', - 'UI:CountOfResults' => '%1$d oggetto(i)', - 'UI:ChangesLogTitle' => 'Log delle modifiche (%1$d):', - 'UI:EmptyChangesLogTitle' => 'Log delle modifiche è vuoto', - 'UI:SearchFor_Class_Objects' => 'Cerca per %1$s Oggetti', - 'UI:OQLQueryBuilderTitle' => 'OQL Query Builder', - 'UI:OQLQueryTab' => 'OQL Query', - 'UI:SimpleSearchTab' => 'Ricerca semplice', - 'UI:Details+' => '', - 'UI:SearchValue:Any' => '* Qualsiasi *', - 'UI:SearchValue:Mixed' => '* misti *', - 'UI:SelectOne' => '-- selezionare uno --', - 'UI:Login:Welcome' => 'Benvenuti su iTop!', - 'UI:Login:IncorrectLoginPassword' => 'Errato login/password, si prega di riprovare.', - 'UI:Login:IdentifyYourself' => 'Identifica te stesso prima di continuare', - 'UI:Login:UserNamePrompt' => 'Nome Utente', - 'UI:Login:PasswordPrompt' => 'Password', - 'UI:Login:ChangeYourPassword' => 'Cambia la tua password', - 'UI:Login:OldPasswordPrompt' => 'Vecchia password', - 'UI:Login:NewPasswordPrompt' => 'Nuova password', - 'UI:Login:RetypeNewPasswordPrompt' => 'Riscrivi la nuova password', - 'UI:Login:IncorrectOldPassword' => 'Errore: la vecchia password non è corretta', - 'UI:LogOffMenu' => 'Log off', - 'UI:LogOff:ThankYou' => 'Grazie per aver scelto iTop', - 'UI:LogOff:ClickHereToLoginAgain' => 'Clicca qui per effettuare il login di nuovo...', - 'UI:ChangePwdMenu' => 'Cambia Password...', - 'UI:AccessRO-All' => 'iTop è di sola lettura', - 'UI:AccessRO-Users' => 'iTop è di sola lettura per gli utenti finali', - 'UI:Login:RetypePwdDoesNotMatch' => 'Nuova password e la nuova password digitata nuovamente non corrispondono !', - 'UI:Button:Login' => 'Entra in iTop', - - 'UI:Login:Error:AccessRestricted' => 'L\'accesso a iTop è limitato. Si prega di contattare un amministratore iTop.', - 'UI:Login:Error:AccessAdmin' => 'Accesso limitato alle persone che hanno privilegi di amministratore. Si prega di contattare un amministratore iTop.', - 'UI:CSVImport:MappingSelectOne' => '-- seleziona uno --', - 'UI:CSVImport:MappingNotApplicable' => '-- ignora questo campo --', - 'UI:CSVImport:NoData' => 'Insieme di dati vuoto ..., si prega di fornire alcuni dati!', - 'UI:Title:DataPreview' => 'Anteprima dati', - 'UI:CSVImport:ErrorOnlyOneColumn' => 'Errore: I dati contengono solo una colonna. Avete selezionato il carattere separatore appropriato?', - 'UI:CSVImport:FieldName' => 'Campo %1$d', - 'UI:CSVImport:DataLine1' => 'Dati Linea 1', - 'UI:CSVImport:DataLine2' => 'Dati Linea 2', - 'UI:CSVImport:idField' => 'id (Chiave Primaria)', - 'UI:Title:BulkImport' => 'iTop - importazione collettiva', - 'UI:Title:BulkImport+' => '', - 'UI:Title:BulkSynchro_nbItem_ofClass_class' => 'Sincronizzazione di %1$d oggetti della classe %2$s', - 'UI:CSVImport:ClassesSelectOne' => '-- seleziona uno --', - 'UI:CSVImport:ErrorExtendedAttCode' => 'Errore interno: "%1$s" è un codice errato, perché "%2$s" NON è una chiave esterna della classe "%3$s"', - 'UI:CSVImport:ObjectsWillStayUnchanged' => '%1$d oggetto(i) rimarrà invariato.', - 'UI:CSVImport:ObjectsWillBeModified' => '%1$d oggetto(i) sarà modificato.', - 'UI:CSVImport:ObjectsWillBeAdded' => '%1$d oggetto(i) sarà aggiunto.', - 'UI:CSVImport:ObjectsWillHaveErrors' => '%1$d oggetto(i) avranno i errori.', - 'UI:CSVImport:ObjectsRemainedUnchanged' => '%1$d oggetto(i) è rimasto invariato.', - 'UI:CSVImport:ObjectsWereModified' => '%1$d oggetto(i) sono stati modificati.', - 'UI:CSVImport:ObjectsWereAdded' => '%1$d oggetto(i) sono stati aggiunti.', - 'UI:CSVImport:ObjectsHadErrors' => '%1$d oggetto(i) hanno avuto errori.', - 'UI:Title:CSVImportStep2' => 'Step 2 of 5: opzioni dati CVS', - 'UI:Title:CSVImportStep3' => 'Step 3 of 5: Mappatura dei dati', - 'UI:Title:CSVImportStep4' => 'Step 4 of 5: Importa simulazione', - 'UI:Title:CSVImportStep5' => 'Step 5 of 5: Importazione completata', - 'UI:CSVImport:LinesNotImported' => 'Linee che non possono essere caricate:', - 'UI:CSVImport:LinesNotImported+' => '', - 'UI:CSVImport:SeparatorComma+' => '', - 'UI:CSVImport:SeparatorSemicolon+' => '', - 'UI:CSVImport:SeparatorTab+' => '', - 'UI:CSVImport:SeparatorOther' => 'altri:', - 'UI:CSVImport:QualifierDoubleQuote+' => '', - 'UI:CSVImport:QualifierSimpleQuote+' => '', - 'UI:CSVImport:QualifierOther' => 'other:~~', - 'UI:CSVImport:TreatFirstLineAsHeader' => 'Tratta la prima riga come intestazione (nomi di colonna)', - 'UI:CSVImport:Skip_N_LinesAtTheBeginning' => 'Salta le linee %1$s all\'inzio del file', - 'UI:CSVImport:CSVDataPreview' => 'CSV Anteprima dei dati', - 'UI:CSVImport:SelectFile' => 'Selezionare il file da importare:', - 'UI:CSVImport:Tab:LoadFromFile' => 'Carica da un file', - 'UI:CSVImport:Tab:CopyPaste' => 'Copia e incolla i dati', - 'UI:CSVImport:Tab:Templates' => 'Modelli', - 'UI:CSVImport:PasteData' => 'Incolla i dati da importare:', - 'UI:CSVImport:PickClassForTemplate' => 'Scegli il modello da scaricare: ', - 'UI:CSVImport:SeparatorCharacter' => 'Separatore di carattere:', - 'UI:CSVImport:TextQualifierCharacter' => 'Testo di qualificazione carattere', - 'UI:CSVImport:CommentsAndHeader' => 'Commenti e intestazione', - 'UI:CSVImport:SelectClass' => 'Selezionare la classe da importare:', - 'UI:CSVImport:AdvancedMode' => 'Modalità avanzata', - 'UI:CSVImport:AdvancedMode+' => '', - 'UI:CSVImport:SelectAClassFirst' => 'Per configurare il mapping, selezionare prima una classe.', - 'UI:CSVImport:HeaderFields' => 'Campi', - 'UI:CSVImport:HeaderMappings' => 'Mappings', - 'UI:CSVImport:HeaderSearch' => 'Cerca?', - 'UI:CSVImport:AlertIncompleteMapping' => 'Per favore seleziona una mappatura per ogni campo.', - 'UI:CSVImport:AlertNoSearchCriteria' => 'Per favore seleziona almeno un criterio di ricerca', - 'UI:CSVImport:Encoding' => 'Codifica dei caratteri', - 'UI:UniversalSearchTitle' => 'iTop - Ricerca Universale', - 'UI:UniversalSearch:Error' => 'Errore: %1$s~~', - 'UI:UniversalSearch:LabelSelectTheClass' => 'Seleziona la classe per la ricerca: ', - 'UI:Audit:Title' => 'iTop - CMDB Audit~~', - 'UI:Audit:InteractiveAudit' => 'Audit Interattivo', - 'UI:Audit:HeaderAuditRule' => 'Regole di Audit', - 'UI:Audit:HeaderNbObjects' => '# Oggetti', - 'UI:Audit:HeaderNbErrors' => '# Errori', - 'UI:Audit:PercentageOk' => '% Ok', - 'UI:RunQuery:Title' => 'iTop - Valutazione Query OQL', - 'UI:RunQuery:QueryExamples' => 'Esempi di Query', - 'UI:RunQuery:HeaderPurpose' => 'Scopo', - 'UI:RunQuery:HeaderPurpose+' => '', - 'UI:RunQuery:HeaderOQLExpression' => 'Espressioni OQL', - 'UI:RunQuery:HeaderOQLExpression+' => '', - 'UI:RunQuery:ExpressionToEvaluate' => 'Espressione da valutare: ', - 'UI:RunQuery:MoreInfo' => 'Maggiori informazioni sulla query: ', - 'UI:RunQuery:DevelopedQuery' => 'Espressione della query riqualificata:', - 'UI:RunQuery:SerializedFilter' => 'Filtro pubblicato: ', - 'UI:RunQuery:Error' => 'Si è verificato un errore durante l\'esecuzione della query: %1$s', - 'UI:Schema:Title' => 'iTop schema degli oggetti', - 'UI:Schema:CategoryMenuItem' => 'Categoria %1$s', - 'UI:Schema:Relationships' => 'Relazioni', - 'UI:Schema:AbstractClass' => 'Classe astratta: nessun oggetto da questa classe può essere istanziato.', - 'UI:Schema:NonAbstractClass' => 'Classe non-astratta: oggetti da questa classe possono essere istanziati.', - 'UI:Schema:ClassHierarchyTitle' => 'Gerarchia delle classi', - 'UI:Schema:AllClasses' => 'Tutte le classi', - 'UI:Schema:ExternalKey_To' => 'Chiave esterna %1$s', - 'UI:Schema:Columns_Description' => 'Colonne: %1$s', - 'UI:Schema:Default_Description' => 'Default: "%1$s"', - 'UI:Schema:NullAllowed' => 'Null consentito', - 'UI:Schema:NullNotAllowed' => 'Null NON consentito', - 'UI:Schema:Attributes' => 'Attributi', - 'UI:Schema:AttributeCode' => 'Codice attributo', - 'UI:Schema:AttributeCode+' => '', - 'UI:Schema:Label' => 'Etichetta', - 'UI:Schema:Label+' => '', - 'UI:Schema:Type' => 'Tipo', - 'UI:Schema:Type+' => '', - 'UI:Schema:Origin' => 'Origine', - 'UI:Schema:Origin+' => '', - 'UI:Schema:Description' => 'Descrizione', - 'UI:Schema:Description+' => '', - 'UI:Schema:AllowedValues' => 'Valori consentiti', - 'UI:Schema:AllowedValues+' => '', - 'UI:Schema:MoreInfo' => 'Maggiori informazioni', - 'UI:Schema:MoreInfo+' => '', - 'UI:Schema:SearchCriteria' => 'Criteri di ricerca', - 'UI:Schema:FilterCode' => 'Codice di filtro', - 'UI:Schema:FilterCode+' => '', - 'UI:Schema:FilterDescription' => 'Descrizione', - 'UI:Schema:FilterDescription+' => '', - 'UI:Schema:AvailOperators' => 'Operatori disponibili', - 'UI:Schema:AvailOperators+' => '', - 'UI:Schema:ChildClasses' => 'Classi figlio', - 'UI:Schema:ReferencingClasses' => 'Classi di rifermento', - 'UI:Schema:RelatedClasses' => 'Classi correlate', - 'UI:Schema:LifeCycle' => 'Ciclo di vita', - 'UI:Schema:Triggers' => 'Triggers', - 'UI:Schema:Relation_Code_Description' => 'Relazione %1$s (%2$s)', - 'UI:Schema:RelationDown_Description' => 'Giù: %1$s', - 'UI:Schema:RelationUp_Description' => 'Su: %1$s', - 'UI:Schema:RelationPropagates' => '%1$s: propagato al livello %2$d, query: %3$s', - 'UI:Schema:RelationDoesNotPropagate' => '%1$s: non si propaga a (%2$d livelli), query: %3$s', - 'UI:Schema:Class_ReferencingClasses_From_By' => '%1$s fa riferimento la classe %2$s tramite il campo %3$s', - 'UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute' => '%1$s è legata alla %2$s via %3$s::%4$s', - 'UI:Schema:Links:1-n' => 'Classi che puntano a %1$s (1:n links):', - 'UI:Schema:Links:n-n' => 'Classi legati alla %1$s (n:n links):', - 'UI:Schema:Links:All' => 'Grafico di tutte le classi correlate', - 'UI:Schema:NoLifeCyle' => 'Non vi è alcun ciclo di vita definito per questa classe.', - 'UI:Schema:LifeCycleTransitions' => 'Transizioni', - 'UI:Schema:LifeCyleAttributeOptions' => 'Opzioni per l\'attributo', - 'UI:Schema:LifeCycleHiddenAttribute' => 'Nascosto', - 'UI:Schema:LifeCycleReadOnlyAttribute' => 'Di sola lettura', - 'UI:Schema:LifeCycleMandatoryAttribute' => 'Obbigatorio', - 'UI:Schema:LifeCycleAttributeMustChange' => 'Deve cambiare', - 'UI:Schema:LifeCycleAttributeMustPrompt' => 'All\'utente verrà richiesto di modificare il valore', - 'UI:Schema:LifeCycleEmptyList' => 'lista vuota', - 'UI:LinksWidget:Autocomplete+' => '', - 'UI:Combo:SelectValue' => '--- seleziona un valore ---', - 'UI:Label:SelectedObjects' => 'oggetti selezionati: ', - 'UI:Label:AvailableObjects' => 'Oggetti disponibili: ', - 'UI:Link_Class_Attributes' => '%1$s attributi', - 'UI:AddObjectsOf_Class_LinkedWith_Class_Instance' => 'Aggiungi l\'oggeto %1$s collegato con %2$s: %3$s', - 'UI:AddObjectsOf_Class_LinkedWith_Class' => 'Aggiungi l\'oggeto %1$s al collegamento con %2$s', - 'UI:ManageObjectsOf_Class_LinkedWith_Class_Instance' => 'Gestisci l\'oggetto %1$s collegato con %2$s: %3$s', - 'UI:AddLinkedObjectsOf_Class' => 'Aggiungi %1$s...', - 'UI:RemoveLinkedObjectsOf_Class' => 'Rimuovi gli oggetti selezionati', - 'UI:Message:EmptyList:UseAdd' => 'La lista è vuota, utilizzare il pulsante "Aggiungi ..." per aggiungere elementi.', - 'UI:Message:EmptyList:UseSearchForm' => 'Utilizza il modulo di ricerca qui sopra per cercare oggetti da aggiungere.', - 'UI:Wizard:FinalStepTitle' => 'Passo finale: la conferma', - 'UI:Title:DeletionOf_Object' => 'Soppressione di %1$s', - 'UI:Title:BulkDeletionOf_Count_ObjectsOf_Class' => 'Cancellazione collettiva di %1$d oggetti della classe %2$s', - 'UI:Delete:NotAllowedToDelete' => 'Non ti è permesso di eliminare l\'oggetto', - 'UI:Delete:NotAllowedToUpdate_Fields' => 'Non hai i permessi per aggiornare il seguente campo(i): %1$s', - 'UI:Error:NotEnoughRightsToDelete' => 'Questo oggetto non può essere cancellato perché l\'utente corrente non dispone dei diritti necessari', - 'UI:Error:CannotDeleteBecause' => 'Questo oggetto non può essere cancellato perchè: %1$s~~', - 'UI:Error:CannotDeleteBecauseOfDepencies' => 'Questo oggetto non può essere cancellato perché alcune operazioni manuali devono essere effettuate prima di questo', - 'UI:Error:CannotDeleteBecauseManualOpNeeded' => 'Questo oggetto non può essere cancellato perché alcune operazioni manuali devono essere effettuate prima di questo', - 'UI:Archive_User_OnBehalfOf_User' => '%1$s a nome di %2$s', - 'UI:Delete:Deleted' => 'deleted~~', - 'UI:Delete:AutomaticallyDeleted' => 'automaticamente eliminato', - 'UI:Delete:AutomaticResetOf_Fields' => 'ripristino automatico del campo(i): %1$s', - 'UI:Delete:CleaningUpRefencesTo_Object' => 'Pulizia di tutti i riferimenti a %1$s...', - 'UI:Delete:CleaningUpRefencesTo_Several_ObjectsOf_Class' => 'Pulizia di tutti i riferimenti a %1$d oggetti di classe %2$s...', - 'UI:Delete:Done+' => '', - 'UI:Delete:_Name_Class_Deleted' => '%1$s - %2$s cancellato.', - 'UI:Delete:ConfirmDeletionOf_Name' => 'Soppressione di %1$s', - 'UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class' => 'Soppressione di %1$d oggetti di classe %2$s', - 'UI:Delete:CannotDeleteBecause' => 'Non può essere cancellato: %1$s~~', - 'UI:Delete:ShouldBeDeletedAtomaticallyButNotPossible' => 'Dovrebbe essere eliminato automaticamente, ma questo non è fattibile: %1$s~~', - 'UI:Delete:MustBeDeletedManuallyButNotPossible' => 'Deve essere cancellato manualmente, ma questo non è fattibile: %1$s~~', - 'UI:Delete:WillBeDeletedAutomatically' => 'Sarà cancellato automaticamente', - 'UI:Delete:MustBeDeletedManually' => 'Deve essere cancellato manualmente', - 'UI:Delete:CannotUpdateBecause_Issue' => 'Dovrebbero essere automaticamente aggiornati, ma: %1$s~~', - 'UI:Delete:WillAutomaticallyUpdate_Fields' => 'Sarà automaticamente aggiornato (reset: %1$s)~~', - 'UI:Delete:Count_Objects/LinksReferencing_Object' => '%1$d oggetti/link fanno riferimento %2$s', - 'UI:Delete:Count_Objects/LinksReferencingTheObjects' => '%1$d oggetti / link fanno riferimento alcuni degli oggetti da eliminare', - 'UI:Delete:ReferencesMustBeDeletedToEnsureIntegrity' => 'Per garantire l\'integrità del database, ogni riferimento dovrebbe essere ulteriormente eliminato', - 'UI:Delete:Consequence+' => '', - 'UI:Delete:SorryDeletionNotAllowed' => 'Spiacenti, non sei autorizzato a cancellare questo oggetto, vedere le spiegazioni di cui sopra', - 'UI:Delete:PleaseDoTheManualOperations' => 'Si prega di eseguire le operazioni manuali di cui sopra prima di richiedere la cancellazione di questo oggetto', - 'UI:Delect:Confirm_Object' => 'Si prega di confermare che si desidera eliminare %1$s.', - 'UI:Delect:Confirm_Count_ObjectsOf_Class' => 'Si prega di confermare che si desidera eliminare i seguenti oggetti %1$d della classe %2$s.', - 'UI:WelcomeToITop' => 'Benvenuto su iTop', - 'UI:DetailsPageTitle' => 'iTop - %1$s - %2$s dettagli', - 'UI:ErrorPageTitle' => 'iTop - Errore', - 'UI:ObjectDoesNotExist' => 'Spiacenti, questo oggetto non esiste (o non si è autorizzati per vederlo).', - 'UI:SearchResultsPageTitle' => 'iTop - Risultati della ricerca', - 'UI:Search:NoSearch' => 'Niente da ricercare', - 'UI:FullTextSearchTitle_Text' => 'Risultati per "%1$s":', - 'UI:Search:Count_ObjectsOf_Class_Found' => 'Trovato l\'oggetto(i) %1$d della classe %2$s.', - 'UI:Search:NoObjectFound' => 'Nessun oggetto trovato.', - 'UI:ModificationPageTitle_Object_Class' => 'iTop - %1$s - %2$s modifica', - 'UI:ModificationTitle_Class_Object' => 'Modifica di %1$s: %2$s', - 'UI:ClonePageTitle_Object_Class' => 'iTop - Clone %1$s - %2$s modifica', - 'UI:CloneTitle_Class_Object' => 'Clone di %1$s: %2$s', - 'UI:CreationPageTitle_Class' => 'iTop - Creazione di un nuovo %1$s ', - 'UI:CreationTitle_Class' => 'Creazione di un nuovo %1$s', - 'UI:SelectTheTypeOf_Class_ToCreate' => 'Seleziona il tipo di %1$s da creare:', - 'UI:Class_Object_NotUpdated' => 'Nessun cambiamento rilevato, %1$s (%2$s) non è stato modificato.', - 'UI:Class_Object_Updated' => '%1$s (%2$s) aggiornato.', - 'UI:BulkDeletePageTitle' => 'iTop - Eliminazione collettiva', - 'UI:BulkDeleteTitle' => 'Seleziona gli oggetti che si desidera eliminare:', - 'UI:PageTitle:ObjectCreated' => 'iTop Oggetto Creato.', - 'UI:Title:Object_Of_Class_Created' => '%1$s - %2$s creato.', - 'UI:Apply_Stimulus_On_Object_In_State_ToTarget_State' => 'Applicazione %1$s all\'oggetto: %2$s nello stato %3$s allo stato target: %4$s.', - 'UI:ObjectCouldNotBeWritten' => 'L\'oggetto non può essere scritto: %1$s~~', - 'UI:PageTitle:FatalError' => 'iTop - Fatal Error', - 'UI:SystemIntrusion' => 'Accesso negato. Hai cercato di eseguire un\'operazione che non ti è consentita.', - 'UI:FatalErrorMessage' => 'Fatal error, iTop non può continuare.', - 'UI:Error_Details' => 'Errore: %1$s.', - 'UI:PageTitle:ClassProjections' => 'iTop gestione degli utenti - proiezioni classe', - 'UI:PageTitle:ProfileProjections' => 'iTop gestione degli utenti - proiezioni profilo', - 'UI:UserManagement:Class' => 'Classe', - 'UI:UserManagement:Class+' => '', - 'UI:UserManagement:ProjectedObject' => 'Oggetto', - 'UI:UserManagement:ProjectedObject+' => '', - 'UI:UserManagement:AnyObject' => '* qualsiasi *', - 'UI:UserManagement:User' => 'Utente', - 'UI:UserManagement:User+' => '', - 'UI:UserManagement:Profile' => 'Profilo', - 'UI:UserManagement:Profile+' => '', - 'UI:UserManagement:Action:Read' => 'Leggi', - 'UI:UserManagement:Action:Read+' => '', - 'UI:UserManagement:Action:Modify' => 'Modifica', - 'UI:UserManagement:Action:Modify+' => '', - 'UI:UserManagement:Action:Delete' => 'Cancella', - 'UI:UserManagement:Action:Delete+' => '', - 'UI:UserManagement:Action:BulkRead' => 'Leggi Bulk (Export)', - 'UI:UserManagement:Action:BulkRead+' => '', - 'UI:UserManagement:Action:BulkModify' => 'Modifica Bulk', - 'UI:UserManagement:Action:BulkModify+' => '', - 'UI:UserManagement:Action:BulkDelete' => 'Cancella Bulk ', - 'UI:UserManagement:Action:BulkDelete+' => '', - 'UI:UserManagement:Action:Stimuli' => 'Stimoli', - 'UI:UserManagement:Action:Stimuli+' => '', - 'UI:UserManagement:Action' => 'Azione', - 'UI:UserManagement:Action+' => '', - 'UI:UserManagement:TitleActions' => 'Azioni', - 'UI:UserManagement:Permission' => 'Autorizzazione', - 'UI:UserManagement:Permission+' => '', - 'UI:UserManagement:Attributes' => 'Attributi', - 'UI:UserManagement:ActionAllowed:Yes' => 'Si', - 'UI:UserManagement:ActionAllowed:No' => 'No', - 'UI:UserManagement:AdminProfile+' => '', - 'UI:UserManagement:NoLifeCycleApplicable' => 'N/A', - 'UI:UserManagement:NoLifeCycleApplicable+' => '', - 'UI:UserManagement:GrantMatrix' => 'Grant Matrix', - 'UI:UserManagement:LinkBetween_User_And_Profile' => 'Collegamento tra %1$s e %2$s', - 'UI:UserManagement:LinkBetween_User_And_Org' => 'Collegamento tra %1$s e %2$s', - 'Menu:AdminTools' => 'Strumenti di amministrazione', - 'Menu:AdminTools+' => '', - 'Menu:AdminTools?' => 'Strumenti accessibile solo agli utenti con il profilo di amministratore', - 'UI:ChangeManagementMenu' => 'Gestione Cambi', - 'UI:ChangeManagementMenu+' => '', - 'UI:ChangeManagementMenu:Title' => 'Panoramica dei cambi', - 'UI-ChangeManagementMenu-ChangesByType' => 'Cambi per tipo', - 'UI-ChangeManagementMenu-ChangesByStatus' => 'Cambi per stato', - 'UI-ChangeManagementMenu-ChangesByWorkgroup' => 'Cambi per gruppi di lavoro', - 'UI-ChangeManagementMenu-ChangesNotYetAssigned' => 'Cambi non ancora assegnati', - 'UI:ConfigurationItemsMenu' => 'Configuration Items', - 'UI:ConfigurationItemsMenu+' => '', - 'UI:ConfigurationItemsMenu:Title' => 'Configuration Items Panoramica', - 'UI-ConfigurationItemsMenu-ServersByCriticity' => 'Server per criticità', - 'UI-ConfigurationItemsMenu-PCsByCriticity' => 'PCs per criticità', - 'UI-ConfigurationItemsMenu-NWDevicesByCriticity' => 'Dispositivi di rete per criticità', - 'UI-ConfigurationItemsMenu-ApplicationsByCriticity' => 'Applicazioni per criticità', - 'UI:ConfigurationManagementMenu' => 'Gestione Configurazione', - 'UI:ConfigurationManagementMenu+' => '', - 'UI:ConfigurationManagementMenu:Title' => 'Panoramica delle infrastrutture', - 'UI-ConfigurationManagementMenu-InfraByType' => 'Oggetti infrastruttutura per tipo', - 'UI-ConfigurationManagementMenu-InfraByStatus' => 'Oggetti infrastruttutura per stato', - 'UI:ConfigMgmtMenuOverview:Title' => 'Cruscotto per Gestione configurazione', - 'UI-ConfigMgmtMenuOverview-FunctionalCIbyStatus' => 'Configuration Items per stato', - 'UI-ConfigMgmtMenuOverview-FunctionalCIByType' => 'Configuration Items per tipo', - 'UI:RequestMgmtMenuOverview:Title' => 'Cruscotto per Gestione Richieste', - 'UI-RequestManagementOverview-RequestByService' => 'Richieste degli utenti per servizio', - 'UI-RequestManagementOverview-RequestByPriority' => 'Richieste degli utenti per priorità', - 'UI-RequestManagementOverview-RequestUnassigned' => 'Richieste degli utenti non ancora assegnate ad un agente', - 'UI:IncidentMgmtMenuOverview:Title' => 'Cruscotto Gestione degli Incidenti', - 'UI-IncidentManagementOverview-IncidentByService' => 'Incidenti per servizio', - 'UI-IncidentManagementOverview-IncidentByPriority' => 'Incidenti per priorità', - 'UI-IncidentManagementOverview-IncidentUnassigned' => 'Incidenti non ancora assegnati ad un agente', - 'UI:ChangeMgmtMenuOverview:Title' => 'Cruscotto per Gestione dei Cambi', - 'UI-ChangeManagementOverview-ChangeByType' => 'Cambi per tipo', - 'UI-ChangeManagementOverview-ChangeUnassigned' => 'Cambi non ancora assegnati ad un agente', - 'UI-ChangeManagementOverview-ChangeWithOutage' => 'Interruzioni dovute ai cambi', - 'UI:ServiceMgmtMenuOverview:Title' => 'Cruscotto per Gestione dei Cambi', - 'UI-ServiceManagementOverview-CustomerContractToRenew' => 'Contratti con i clienti da rinnovarsi in 30 giorni', - 'UI-ServiceManagementOverview-ProviderContractToRenew' => 'Contratti con i fornitori da rinnovarsi in 30 giorni', - 'UI:ContactsMenu' => 'Contatti', - 'UI:ContactsMenu+' => '', - 'UI:ContactsMenu:Title' => 'Contatti Panoramica', - 'UI-ContactsMenu-ContactsByLocation' => 'Contatti per localizzazione', - 'UI-ContactsMenu-ContactsByType' => 'Contatti per tipo', - 'UI-ContactsMenu-ContactsByStatus' => 'Contatti per stato', - 'Menu:CSVImportMenu' => 'Importazione CSV', - 'Menu:CSVImportMenu+' => '', - 'Menu:DataModelMenu' => 'Modello Dati', - 'Menu:DataModelMenu+' => '', - 'Menu:ExportMenu' => 'Esporta', - 'Menu:ExportMenu+' => '', - 'Menu:NotificationsMenu' => 'Notifiche', - 'Menu:NotificationsMenu+' => '', - 'UI:NotificationsMenu:Title' => 'Configurazione delle Notifiche', - 'UI:NotificationsMenu:Help' => 'Aiuto', +

    ', + 'UI:WelcomeMenu:AllOpenRequests' => 'Apri le richieste: %1$d', + 'UI:WelcomeMenu:MyCalls' => 'Le mie richieste', + 'UI:WelcomeMenu:OpenIncidents' => 'Apri gli incidenti: %1$d', + 'UI:WelcomeMenu:AllConfigItems' => 'Elementi di Configurazione (CI): %1$d', + 'UI:WelcomeMenu:MyIncidents' => 'Incidenti assegnati a me', + 'UI:AllOrganizations' => ' Tutte le Organizzazioni ', + 'UI:YourSearch' => 'La tua Cerca', + 'UI:LoggedAsMessage' => 'Logged come %1$s', + 'UI:LoggedAsMessage+Admin' => 'Logged come %1$s (Amministratore)', + 'UI:Button:Logoff' => 'Log off', + 'UI:Button:GlobalSearch' => 'Cerca', + 'UI:Button:Search' => ' Cerca', + 'UI:Button:Query' => ' Domanda', + 'UI:Button:Ok' => 'Ok', + 'UI:Button:Cancel' => 'Cancella', + 'UI:Button:Apply' => 'Applica', + 'UI:Button:Back' => ' << Indietro', + 'UI:Button:Restart' => ' |<< Riavvia', + 'UI:Button:Next' => ' Prossimo >> ', + 'UI:Button:Finish' => ' Fine', + 'UI:Button:DoImport' => ' Esegui le Imporazioni ! ~~', + 'UI:Button:Done' => ' Fatto', + 'UI:Button:SimulateImport' => ' Simula l\'Importazione ~~', + 'UI:Button:Test' => 'Testa!', + 'UI:Button:Evaluate' => ' Valuta', + 'UI:Button:AddObject' => ' Aggiungi... ~~', + 'UI:Button:BrowseObjects' => ' Sfoglia... ~~', + 'UI:Button:Add' => ' Aggiungi ~~', + 'UI:Button:AddToList' => ' << Aggiungi ~~', + 'UI:Button:RemoveFromList' => ' Rimuovi >> ~~', + 'UI:Button:FilterList' => ' Filtra... ~~', + 'UI:Button:Create' => ' Crea ~~', + 'UI:Button:Delete' => ' Cancella ! ~~', + 'UI:Button:ChangePassword' => ' Cambia Password ~~', + 'UI:Button:ResetPassword' => ' Resetta Password ~~', + 'UI:SearchToggle' => 'Cerca', + 'UI:ClickToCreateNew' => 'Crea un nuovo %1$s~~', + 'UI:SearchFor_Class' => 'Cerca l\'oggetto %1$s', + 'UI:NoObjectToDisplay' => 'Nessun oggetto da mostrare.', + 'UI:Error:MandatoryTemplateParameter_object_id' => 'Object_id parametro è obbligatorio quando link_attr è specificato. Verificare la definizione del modello di display.', + 'UI:Error:MandatoryTemplateParameter_target_attr' => 'Target_attr parametro è obbligatorio quando link_attr è specificato. Verificare la definizione del modello di display.', + 'UI:Error:MandatoryTemplateParameter_group_by' => 'Il parametro è group_by obbligatoria. Verificare la definizione del modello di display.', + 'UI:Error:InvalidGroupByFields' => 'Elenco di campi non valido per il raggruppamento: "%1$s".', + 'UI:Error:UnsupportedStyleOfBlock' => 'Errore: Stile non supportato di blocco: "%1$s".', + 'UI:Error:IncorrectLinkDefinition_LinkedClass_Class' => 'Errata definizione di link: la classe di oggetti da gestire: %1$s non è stato trovato come chiave esterna nella classe %2$s', + 'UI:Error:Object_Class_Id_NotFound' => 'Oggetto: %1$s:%2$d non trovato.', + 'UI:Error:WizardCircularReferenceInDependencies' => 'Errore: Riferimento circolare nelle dipendenze tra i campi, controllare il modello di dati.', + 'UI:Error:UploadedFileTooBig' => 'Il file caricato è troppo grande. (dimensione massima consentita è di %1$s). Verificare di configurazione di PHP per upload_max_filesize e post_max_size.', + 'UI:Error:UploadedFileTruncated.' => 'Il file caricato è stata troncato !', + 'UI:Error:NoTmpDir' => 'La directory temporanea non è definita.', + 'UI:Error:CannotWriteToTmp_Dir' => 'Impossibile scrivere il file temporaneo sul disco. upload_tmp_dir = "%1$s".', + 'UI:Error:UploadStoppedByExtension_FileName' => 'Caricamento fermato per estensione. (Nome del file originale = "%1$s").', + 'UI:Error:UploadFailedUnknownCause_Code' => 'Il caricamento del file non riuscito, causa sconosciuta. (Codice errore = "%1$s").', + 'UI:Error:1ParametersMissing' => 'Errore: il seguente parametro deve essere specificato per questa operazione: %1$s.', + 'UI:Error:2ParametersMissing' => 'Errore: i seguenti parametri devono essere specificati per questa operazione: %1$s e %2$s.', + 'UI:Error:3ParametersMissing' => 'Errore: i seguenti parametri devono essere specificati per questa operazione: %1$s, %2$s e %3$s.', + 'UI:Error:4ParametersMissing' => 'Errore: i seguenti parametri devono essere specificati per questa operazione: %1$s, %2$s, %3$s e %4$s.', + 'UI:Error:IncorrectOQLQuery_Message' => 'Errore: errata OQL query: %1$s', + 'UI:Error:AnErrorOccuredWhileRunningTheQuery_Message' => 'Si è verificato un errore durante l\'esecuzione della query: %1$s', + 'UI:Error:ObjectAlreadyUpdated' => 'Errore: l\'oggetto è già stato aggiornato.', + 'UI:Error:ObjectCannotBeUpdated' => 'Errore: oggetto non può essere aggiornato.', + 'UI:Error:ObjectsAlreadyDeleted' => 'Errore: gli oggetti sono già stati eliminati!', + 'UI:Error:BulkDeleteNotAllowedOn_Class' => 'Non hai i permessi per eseguire una eliminazione collettiva degli oggetti della classe %1$s', + 'UI:Error:DeleteNotAllowedOn_Class' => 'Non ti è permesso di eliminare gli oggetti della classe %1$s', + 'UI:Error:BulkModifyNotAllowedOn_Class' => 'Non hai i permessi per eseguire un aggiornamento collettivo degli oggetti della classe %1$s', + 'UI:Error:ObjectAlreadyCloned' => 'Errore: l\'oggetto è già stato clonato!', + 'UI:Error:ObjectAlreadyCreated' => 'Errore: l\'oggetto è già stato creato!', + 'UI:Error:Invalid_Stimulus_On_Object_In_State' => 'Errore: stimolo non valido "%1$s" su un oggetto %2$s nello stato "%3$s".', + + 'UI:GroupBy:Count' => 'Conteggio', + 'UI:GroupBy:Count+' => '', + 'UI:CountOfObjects' => '%1$d oggetti corrispondenti ai criteri.', + 'UI_CountOfObjectsShort' => '%1$d oggetti.', + 'UI:NoObject_Class_ToDisplay' => 'No %1$s da visualizzare', + 'UI:History:LastModified_On_By' => 'Ultima modifica %1$s da %2$s.', + 'UI:HistoryTab' => 'Storia', + 'UI:NotificationsTab' => 'Notifiche', + 'UI:History:BulkImports' => 'Storia', + 'UI:History:BulkImports+' => 'Elenco delle importazioni CSV (primo ultimo)', + 'UI:History:BulkImportDetails' => 'Modifiche derivanti dai importazione CSV eseguita su %1$s (da %2$s)', + 'UI:History:Date' => 'Data', + 'UI:History:Date+' => '', + 'UI:History:User' => 'Utente', + 'UI:History:User+' => '', + 'UI:History:Changes' => 'Modifiche', + 'UI:History:Changes+' => '', + 'UI:History:StatsCreations' => 'Creato', + 'UI:History:StatsCreations+' => '', + 'UI:History:StatsModifs' => 'Modificato', + 'UI:History:StatsModifs+' => '', + 'UI:History:StatsDeletes' => 'Cancellato', + 'UI:History:StatsDeletes+' => '', + 'UI:Loading' => 'Caricamento...', + 'UI:Menu:Actions' => 'Azioni', + 'UI:Menu:OtherActions' => 'Altre Azioni', + 'UI:Menu:New' => 'Nuovo...', + 'UI:Menu:Add' => 'Aggiungi...', + 'UI:Menu:Manage' => 'Gestischi...', + 'UI:Menu:EMail' => 'eMail', + 'UI:Menu:CSVExport' => 'CSV Export', + 'UI:Menu:Modify' => 'Modifica...', + 'UI:Menu:Delete' => 'Cancella...', + 'UI:Menu:BulkDelete' => 'Cancella...', + 'UI:UndefinedObject' => 'non definito', + 'UI:Document:OpenInNewWindow:Download' => 'Apri in una nuova finestra: %1$s, Scarica: %2$s', + 'UI:SelectAllToggle+' => '', + 'UI:TruncatedResults' => '%1$d oggetti visualizzati su %2$d', + 'UI:DisplayAll' => 'Mostra tutto', + 'UI:CollapseList' => 'Collassa', + 'UI:CountOfResults' => '%1$d oggetto(i)', + 'UI:ChangesLogTitle' => 'Log delle modifiche (%1$d):', + 'UI:EmptyChangesLogTitle' => 'Log delle modifiche è vuoto', + 'UI:SearchFor_Class_Objects' => 'Cerca per %1$s Oggetti', + 'UI:OQLQueryBuilderTitle' => 'OQL Query Builder', + 'UI:OQLQueryTab' => 'OQL Query', + 'UI:SimpleSearchTab' => 'Ricerca semplice', + 'UI:Details+' => '', + 'UI:SearchValue:Any' => '* Qualsiasi *', + 'UI:SearchValue:Mixed' => '* misti *', + 'UI:SelectOne' => '-- selezionare uno --', + 'UI:Login:Welcome' => 'Benvenuti su iTop!', + 'UI:Login:IncorrectLoginPassword' => 'Errato login/password, si prega di riprovare.', + 'UI:Login:IdentifyYourself' => 'Identifica te stesso prima di continuare', + 'UI:Login:UserNamePrompt' => 'Nome Utente', + 'UI:Login:PasswordPrompt' => 'Password', + 'UI:Login:ChangeYourPassword' => 'Cambia la tua password', + 'UI:Login:OldPasswordPrompt' => 'Vecchia password', + 'UI:Login:NewPasswordPrompt' => 'Nuova password', + 'UI:Login:RetypeNewPasswordPrompt' => 'Riscrivi la nuova password', + 'UI:Login:IncorrectOldPassword' => 'Errore: la vecchia password non è corretta', + 'UI:LogOffMenu' => 'Log off', + 'UI:LogOff:ThankYou' => 'Grazie per aver scelto iTop', + 'UI:LogOff:ClickHereToLoginAgain' => 'Clicca qui per effettuare il login di nuovo...', + 'UI:ChangePwdMenu' => 'Cambia Password...', + 'UI:AccessRO-All' => 'iTop è di sola lettura', + 'UI:AccessRO-Users' => 'iTop è di sola lettura per gli utenti finali', + 'UI:Login:RetypePwdDoesNotMatch' => 'Nuova password e la nuova password digitata nuovamente non corrispondono !', + 'UI:Button:Login' => 'Entra in iTop', + + 'UI:Login:Error:AccessRestricted' => 'L\'accesso a iTop è limitato. Si prega di contattare un amministratore iTop.', + 'UI:Login:Error:AccessAdmin' => 'Accesso limitato alle persone che hanno privilegi di amministratore. Si prega di contattare un amministratore iTop.', + 'UI:CSVImport:MappingSelectOne' => '-- seleziona uno --', + 'UI:CSVImport:MappingNotApplicable' => '-- ignora questo campo --', + 'UI:CSVImport:NoData' => 'Insieme di dati vuoto ..., si prega di fornire alcuni dati!', + 'UI:Title:DataPreview' => 'Anteprima dati', + 'UI:CSVImport:ErrorOnlyOneColumn' => 'Errore: I dati contengono solo una colonna. Avete selezionato il carattere separatore appropriato?', + 'UI:CSVImport:FieldName' => 'Campo %1$d', + 'UI:CSVImport:DataLine1' => 'Dati Linea 1', + 'UI:CSVImport:DataLine2' => 'Dati Linea 2', + 'UI:CSVImport:idField' => 'id (Chiave Primaria)', + 'UI:Title:BulkImport' => 'iTop - importazione collettiva', + 'UI:Title:BulkImport+' => '', + 'UI:Title:BulkSynchro_nbItem_ofClass_class' => 'Sincronizzazione di %1$d oggetti della classe %2$s', + 'UI:CSVImport:ClassesSelectOne' => '-- seleziona uno --', + 'UI:CSVImport:ErrorExtendedAttCode' => 'Errore interno: "%1$s" è un codice errato, perché "%2$s" NON è una chiave esterna della classe "%3$s"', + 'UI:CSVImport:ObjectsWillStayUnchanged' => '%1$d oggetto(i) rimarrà invariato.', + 'UI:CSVImport:ObjectsWillBeModified' => '%1$d oggetto(i) sarà modificato.', + 'UI:CSVImport:ObjectsWillBeAdded' => '%1$d oggetto(i) sarà aggiunto.', + 'UI:CSVImport:ObjectsWillHaveErrors' => '%1$d oggetto(i) avranno i errori.', + 'UI:CSVImport:ObjectsRemainedUnchanged' => '%1$d oggetto(i) è rimasto invariato.', + 'UI:CSVImport:ObjectsWereModified' => '%1$d oggetto(i) sono stati modificati.', + 'UI:CSVImport:ObjectsWereAdded' => '%1$d oggetto(i) sono stati aggiunti.', + 'UI:CSVImport:ObjectsHadErrors' => '%1$d oggetto(i) hanno avuto errori.', + 'UI:Title:CSVImportStep2' => 'Step 2 of 5: opzioni dati CVS', + 'UI:Title:CSVImportStep3' => 'Step 3 of 5: Mappatura dei dati', + 'UI:Title:CSVImportStep4' => 'Step 4 of 5: Importa simulazione', + 'UI:Title:CSVImportStep5' => 'Step 5 of 5: Importazione completata', + 'UI:CSVImport:LinesNotImported' => 'Linee che non possono essere caricate:', + 'UI:CSVImport:LinesNotImported+' => '', + 'UI:CSVImport:SeparatorComma+' => '', + 'UI:CSVImport:SeparatorSemicolon+' => '', + 'UI:CSVImport:SeparatorTab+' => '', + 'UI:CSVImport:SeparatorOther' => 'altri:', + 'UI:CSVImport:QualifierDoubleQuote+' => '', + 'UI:CSVImport:QualifierSimpleQuote+' => '', + 'UI:CSVImport:QualifierOther' => 'other:~~', + 'UI:CSVImport:TreatFirstLineAsHeader' => 'Tratta la prima riga come intestazione (nomi di colonna)', + 'UI:CSVImport:Skip_N_LinesAtTheBeginning' => 'Salta le linee %1$s all\'inzio del file', + 'UI:CSVImport:CSVDataPreview' => 'CSV Anteprima dei dati', + 'UI:CSVImport:SelectFile' => 'Selezionare il file da importare:', + 'UI:CSVImport:Tab:LoadFromFile' => 'Carica da un file', + 'UI:CSVImport:Tab:CopyPaste' => 'Copia e incolla i dati', + 'UI:CSVImport:Tab:Templates' => 'Modelli', + 'UI:CSVImport:PasteData' => 'Incolla i dati da importare:', + 'UI:CSVImport:PickClassForTemplate' => 'Scegli il modello da scaricare: ', + 'UI:CSVImport:SeparatorCharacter' => 'Separatore di carattere:', + 'UI:CSVImport:TextQualifierCharacter' => 'Testo di qualificazione carattere', + 'UI:CSVImport:CommentsAndHeader' => 'Commenti e intestazione', + 'UI:CSVImport:SelectClass' => 'Selezionare la classe da importare:', + 'UI:CSVImport:AdvancedMode' => 'Modalità avanzata', + 'UI:CSVImport:AdvancedMode+' => '', + 'UI:CSVImport:SelectAClassFirst' => 'Per configurare il mapping, selezionare prima una classe.', + 'UI:CSVImport:HeaderFields' => 'Campi', + 'UI:CSVImport:HeaderMappings' => 'Mappings', + 'UI:CSVImport:HeaderSearch' => 'Cerca?', + 'UI:CSVImport:AlertIncompleteMapping' => 'Per favore seleziona una mappatura per ogni campo.', + 'UI:CSVImport:AlertNoSearchCriteria' => 'Per favore seleziona almeno un criterio di ricerca', + 'UI:CSVImport:Encoding' => 'Codifica dei caratteri', + 'UI:UniversalSearchTitle' => 'iTop - Ricerca Universale', + 'UI:UniversalSearch:Error' => 'Errore: %1$s~~', + 'UI:UniversalSearch:LabelSelectTheClass' => 'Seleziona la classe per la ricerca: ', + 'UI:Audit:Title' => 'iTop - CMDB Audit~~', + 'UI:Audit:InteractiveAudit' => 'Audit Interattivo', + 'UI:Audit:HeaderAuditRule' => 'Regole di Audit', + 'UI:Audit:HeaderNbObjects' => '# Oggetti', + 'UI:Audit:HeaderNbErrors' => '# Errori', + 'UI:Audit:PercentageOk' => '% Ok', + 'UI:RunQuery:Title' => 'iTop - Valutazione Query OQL', + 'UI:RunQuery:QueryExamples' => 'Esempi di Query', + 'UI:RunQuery:HeaderPurpose' => 'Scopo', + 'UI:RunQuery:HeaderPurpose+' => '', + 'UI:RunQuery:HeaderOQLExpression' => 'Espressioni OQL', + 'UI:RunQuery:HeaderOQLExpression+' => '', + 'UI:RunQuery:ExpressionToEvaluate' => 'Espressione da valutare: ', + 'UI:RunQuery:MoreInfo' => 'Maggiori informazioni sulla query: ', + 'UI:RunQuery:DevelopedQuery' => 'Espressione della query riqualificata:', + 'UI:RunQuery:SerializedFilter' => 'Filtro pubblicato: ', + 'UI:RunQuery:Error' => 'Si è verificato un errore durante l\'esecuzione della query: %1$s', + 'UI:Schema:Title' => 'iTop schema degli oggetti', + 'UI:Schema:CategoryMenuItem' => 'Categoria %1$s', + 'UI:Schema:Relationships' => 'Relazioni', + 'UI:Schema:AbstractClass' => 'Classe astratta: nessun oggetto da questa classe può essere istanziato.', + 'UI:Schema:NonAbstractClass' => 'Classe non-astratta: oggetti da questa classe possono essere istanziati.', + 'UI:Schema:ClassHierarchyTitle' => 'Gerarchia delle classi', + 'UI:Schema:AllClasses' => 'Tutte le classi', + 'UI:Schema:ExternalKey_To' => 'Chiave esterna %1$s', + 'UI:Schema:Columns_Description' => 'Colonne: %1$s', + 'UI:Schema:Default_Description' => 'Default: "%1$s"', + 'UI:Schema:NullAllowed' => 'Null consentito', + 'UI:Schema:NullNotAllowed' => 'Null NON consentito', + 'UI:Schema:Attributes' => 'Attributi', + 'UI:Schema:AttributeCode' => 'Codice attributo', + 'UI:Schema:AttributeCode+' => '', + 'UI:Schema:Label' => 'Etichetta', + 'UI:Schema:Label+' => '', + 'UI:Schema:Type' => 'Tipo', + 'UI:Schema:Type+' => '', + 'UI:Schema:Origin' => 'Origine', + 'UI:Schema:Origin+' => '', + 'UI:Schema:Description' => 'Descrizione', + 'UI:Schema:Description+' => '', + 'UI:Schema:AllowedValues' => 'Valori consentiti', + 'UI:Schema:AllowedValues+' => '', + 'UI:Schema:MoreInfo' => 'Maggiori informazioni', + 'UI:Schema:MoreInfo+' => '', + 'UI:Schema:SearchCriteria' => 'Criteri di ricerca', + 'UI:Schema:FilterCode' => 'Codice di filtro', + 'UI:Schema:FilterCode+' => '', + 'UI:Schema:FilterDescription' => 'Descrizione', + 'UI:Schema:FilterDescription+' => '', + 'UI:Schema:AvailOperators' => 'Operatori disponibili', + 'UI:Schema:AvailOperators+' => '', + 'UI:Schema:ChildClasses' => 'Classi figlio', + 'UI:Schema:ReferencingClasses' => 'Classi di rifermento', + 'UI:Schema:RelatedClasses' => 'Classi correlate', + 'UI:Schema:LifeCycle' => 'Ciclo di vita', + 'UI:Schema:Triggers' => 'Triggers', + 'UI:Schema:Relation_Code_Description' => 'Relazione %1$s (%2$s)', + 'UI:Schema:RelationDown_Description' => 'Giù: %1$s', + 'UI:Schema:RelationUp_Description' => 'Su: %1$s', + 'UI:Schema:RelationPropagates' => '%1$s: propagato al livello %2$d, query: %3$s', + 'UI:Schema:RelationDoesNotPropagate' => '%1$s: non si propaga a (%2$d livelli), query: %3$s', + 'UI:Schema:Class_ReferencingClasses_From_By' => '%1$s fa riferimento la classe %2$s tramite il campo %3$s', + 'UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute' => '%1$s è legata alla %2$s via %3$s::%4$s', + 'UI:Schema:Links:1-n' => 'Classi che puntano a %1$s (1:n links):', + 'UI:Schema:Links:n-n' => 'Classi legati alla %1$s (n:n links):', + 'UI:Schema:Links:All' => 'Grafico di tutte le classi correlate', + 'UI:Schema:NoLifeCyle' => 'Non vi è alcun ciclo di vita definito per questa classe.', + 'UI:Schema:LifeCycleTransitions' => 'Transizioni', + 'UI:Schema:LifeCyleAttributeOptions' => 'Opzioni per l\'attributo', + 'UI:Schema:LifeCycleHiddenAttribute' => 'Nascosto', + 'UI:Schema:LifeCycleReadOnlyAttribute' => 'Di sola lettura', + 'UI:Schema:LifeCycleMandatoryAttribute' => 'Obbigatorio', + 'UI:Schema:LifeCycleAttributeMustChange' => 'Deve cambiare', + 'UI:Schema:LifeCycleAttributeMustPrompt' => 'All\'utente verrà richiesto di modificare il valore', + 'UI:Schema:LifeCycleEmptyList' => 'lista vuota', + 'UI:LinksWidget:Autocomplete+' => '', + 'UI:Combo:SelectValue' => '--- seleziona un valore ---', + 'UI:Label:SelectedObjects' => 'oggetti selezionati: ', + 'UI:Label:AvailableObjects' => 'Oggetti disponibili: ', + 'UI:Link_Class_Attributes' => '%1$s attributi', + 'UI:AddObjectsOf_Class_LinkedWith_Class_Instance' => 'Aggiungi l\'oggeto %1$s collegato con %2$s: %3$s', + 'UI:AddObjectsOf_Class_LinkedWith_Class' => 'Aggiungi l\'oggeto %1$s al collegamento con %2$s', + 'UI:ManageObjectsOf_Class_LinkedWith_Class_Instance' => 'Gestisci l\'oggetto %1$s collegato con %2$s: %3$s', + 'UI:AddLinkedObjectsOf_Class' => 'Aggiungi %1$s...', + 'UI:RemoveLinkedObjectsOf_Class' => 'Rimuovi gli oggetti selezionati', + 'UI:Message:EmptyList:UseAdd' => 'La lista è vuota, utilizzare il pulsante "Aggiungi ..." per aggiungere elementi.', + 'UI:Message:EmptyList:UseSearchForm' => 'Utilizza il modulo di ricerca qui sopra per cercare oggetti da aggiungere.', + 'UI:Wizard:FinalStepTitle' => 'Passo finale: la conferma', + 'UI:Title:DeletionOf_Object' => 'Soppressione di %1$s', + 'UI:Title:BulkDeletionOf_Count_ObjectsOf_Class' => 'Cancellazione collettiva di %1$d oggetti della classe %2$s', + 'UI:Delete:NotAllowedToDelete' => 'Non ti è permesso di eliminare l\'oggetto', + 'UI:Delete:NotAllowedToUpdate_Fields' => 'Non hai i permessi per aggiornare il seguente campo(i): %1$s', + 'UI:Error:NotEnoughRightsToDelete' => 'Questo oggetto non può essere cancellato perché l\'utente corrente non dispone dei diritti necessari', + 'UI:Error:CannotDeleteBecause' => 'Questo oggetto non può essere cancellato perchè: %1$s~~', + 'UI:Error:CannotDeleteBecauseOfDepencies' => 'Questo oggetto non può essere cancellato perché alcune operazioni manuali devono essere effettuate prima di questo', + 'UI:Error:CannotDeleteBecauseManualOpNeeded' => 'Questo oggetto non può essere cancellato perché alcune operazioni manuali devono essere effettuate prima di questo', + 'UI:Archive_User_OnBehalfOf_User' => '%1$s a nome di %2$s', + 'UI:Delete:Deleted' => 'deleted~~', + 'UI:Delete:AutomaticallyDeleted' => 'automaticamente eliminato', + 'UI:Delete:AutomaticResetOf_Fields' => 'ripristino automatico del campo(i): %1$s', + 'UI:Delete:CleaningUpRefencesTo_Object' => 'Pulizia di tutti i riferimenti a %1$s...', + 'UI:Delete:CleaningUpRefencesTo_Several_ObjectsOf_Class' => 'Pulizia di tutti i riferimenti a %1$d oggetti di classe %2$s...', + 'UI:Delete:Done+' => '', + 'UI:Delete:_Name_Class_Deleted' => '%1$s - %2$s cancellato.', + 'UI:Delete:ConfirmDeletionOf_Name' => 'Soppressione di %1$s', + 'UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class' => 'Soppressione di %1$d oggetti di classe %2$s', + 'UI:Delete:CannotDeleteBecause' => 'Non può essere cancellato: %1$s~~', + 'UI:Delete:ShouldBeDeletedAtomaticallyButNotPossible' => 'Dovrebbe essere eliminato automaticamente, ma questo non è fattibile: %1$s~~', + 'UI:Delete:MustBeDeletedManuallyButNotPossible' => 'Deve essere cancellato manualmente, ma questo non è fattibile: %1$s~~', + 'UI:Delete:WillBeDeletedAutomatically' => 'Sarà cancellato automaticamente', + 'UI:Delete:MustBeDeletedManually' => 'Deve essere cancellato manualmente', + 'UI:Delete:CannotUpdateBecause_Issue' => 'Dovrebbero essere automaticamente aggiornati, ma: %1$s~~', + 'UI:Delete:WillAutomaticallyUpdate_Fields' => 'Sarà automaticamente aggiornato (reset: %1$s)~~', + 'UI:Delete:Count_Objects/LinksReferencing_Object' => '%1$d oggetti/link fanno riferimento %2$s', + 'UI:Delete:Count_Objects/LinksReferencingTheObjects' => '%1$d oggetti / link fanno riferimento alcuni degli oggetti da eliminare', + 'UI:Delete:ReferencesMustBeDeletedToEnsureIntegrity' => 'Per garantire l\'integrità del database, ogni riferimento dovrebbe essere ulteriormente eliminato', + 'UI:Delete:Consequence+' => '', + 'UI:Delete:SorryDeletionNotAllowed' => 'Spiacenti, non sei autorizzato a cancellare questo oggetto, vedere le spiegazioni di cui sopra', + 'UI:Delete:PleaseDoTheManualOperations' => 'Si prega di eseguire le operazioni manuali di cui sopra prima di richiedere la cancellazione di questo oggetto', + 'UI:Delect:Confirm_Object' => 'Si prega di confermare che si desidera eliminare %1$s.', + 'UI:Delect:Confirm_Count_ObjectsOf_Class' => 'Si prega di confermare che si desidera eliminare i seguenti oggetti %1$d della classe %2$s.', + 'UI:WelcomeToITop' => 'Benvenuto su iTop', + 'UI:DetailsPageTitle' => 'iTop - %1$s - %2$s dettagli', + 'UI:ErrorPageTitle' => 'iTop - Errore', + 'UI:ObjectDoesNotExist' => 'Spiacenti, questo oggetto non esiste (o non si è autorizzati per vederlo).', + 'UI:SearchResultsPageTitle' => 'iTop - Risultati della ricerca', + 'UI:Search:NoSearch' => 'Niente da ricercare', + 'UI:FullTextSearchTitle_Text' => 'Risultati per "%1$s":', + 'UI:Search:Count_ObjectsOf_Class_Found' => 'Trovato l\'oggetto(i) %1$d della classe %2$s.', + 'UI:Search:NoObjectFound' => 'Nessun oggetto trovato.', + 'UI:ModificationPageTitle_Object_Class' => 'iTop - %1$s - %2$s modifica', + 'UI:ModificationTitle_Class_Object' => 'Modifica di %1$s: %2$s', + 'UI:ClonePageTitle_Object_Class' => 'iTop - Clone %1$s - %2$s modifica', + 'UI:CloneTitle_Class_Object' => 'Clone di %1$s: %2$s', + 'UI:CreationPageTitle_Class' => 'iTop - Creazione di un nuovo %1$s ', + 'UI:CreationTitle_Class' => 'Creazione di un nuovo %1$s', + 'UI:SelectTheTypeOf_Class_ToCreate' => 'Seleziona il tipo di %1$s da creare:', + 'UI:Class_Object_NotUpdated' => 'Nessun cambiamento rilevato, %1$s (%2$s) non è stato modificato.', + 'UI:Class_Object_Updated' => '%1$s (%2$s) aggiornato.', + 'UI:BulkDeletePageTitle' => 'iTop - Eliminazione collettiva', + 'UI:BulkDeleteTitle' => 'Seleziona gli oggetti che si desidera eliminare:', + 'UI:PageTitle:ObjectCreated' => 'iTop Oggetto Creato.', + 'UI:Title:Object_Of_Class_Created' => '%1$s - %2$s creato.', + 'UI:Apply_Stimulus_On_Object_In_State_ToTarget_State' => 'Applicazione %1$s all\'oggetto: %2$s nello stato %3$s allo stato target: %4$s.', + 'UI:ObjectCouldNotBeWritten' => 'L\'oggetto non può essere scritto: %1$s~~', + 'UI:PageTitle:FatalError' => 'iTop - Fatal Error', + 'UI:SystemIntrusion' => 'Accesso negato. Hai cercato di eseguire un\'operazione che non ti è consentita.', + 'UI:FatalErrorMessage' => 'Fatal error, iTop non può continuare.', + 'UI:Error_Details' => 'Errore: %1$s.', + 'UI:PageTitle:ClassProjections' => 'iTop gestione degli utenti - proiezioni classe', + 'UI:PageTitle:ProfileProjections' => 'iTop gestione degli utenti - proiezioni profilo', + 'UI:UserManagement:Class' => 'Classe', + 'UI:UserManagement:Class+' => '', + 'UI:UserManagement:ProjectedObject' => 'Oggetto', + 'UI:UserManagement:ProjectedObject+' => '', + 'UI:UserManagement:AnyObject' => '* qualsiasi *', + 'UI:UserManagement:User' => 'Utente', + 'UI:UserManagement:User+' => '', + 'UI:UserManagement:Profile' => 'Profilo', + 'UI:UserManagement:Profile+' => '', + 'UI:UserManagement:Action:Read' => 'Leggi', + 'UI:UserManagement:Action:Read+' => '', + 'UI:UserManagement:Action:Modify' => 'Modifica', + 'UI:UserManagement:Action:Modify+' => '', + 'UI:UserManagement:Action:Delete' => 'Cancella', + 'UI:UserManagement:Action:Delete+' => '', + 'UI:UserManagement:Action:BulkRead' => 'Leggi Bulk (Export)', + 'UI:UserManagement:Action:BulkRead+' => '', + 'UI:UserManagement:Action:BulkModify' => 'Modifica Bulk', + 'UI:UserManagement:Action:BulkModify+' => '', + 'UI:UserManagement:Action:BulkDelete' => 'Cancella Bulk ', + 'UI:UserManagement:Action:BulkDelete+' => '', + 'UI:UserManagement:Action:Stimuli' => 'Stimoli', + 'UI:UserManagement:Action:Stimuli+' => '', + 'UI:UserManagement:Action' => 'Azione', + 'UI:UserManagement:Action+' => '', + 'UI:UserManagement:TitleActions' => 'Azioni', + 'UI:UserManagement:Permission' => 'Autorizzazione', + 'UI:UserManagement:Permission+' => '', + 'UI:UserManagement:Attributes' => 'Attributi', + 'UI:UserManagement:ActionAllowed:Yes' => 'Si', + 'UI:UserManagement:ActionAllowed:No' => 'No', + 'UI:UserManagement:AdminProfile+' => '', + 'UI:UserManagement:NoLifeCycleApplicable' => 'N/A', + 'UI:UserManagement:NoLifeCycleApplicable+' => '', + 'UI:UserManagement:GrantMatrix' => 'Grant Matrix', + 'UI:UserManagement:LinkBetween_User_And_Profile' => 'Collegamento tra %1$s e %2$s', + 'UI:UserManagement:LinkBetween_User_And_Org' => 'Collegamento tra %1$s e %2$s', + 'Menu:AdminTools' => 'Strumenti di amministrazione', + 'Menu:AdminTools+' => '', + 'Menu:AdminTools?' => 'Strumenti accessibile solo agli utenti con il profilo di amministratore', + 'UI:ChangeManagementMenu' => 'Gestione Cambi', + 'UI:ChangeManagementMenu+' => '', + 'UI:ChangeManagementMenu:Title' => 'Panoramica dei cambi', + 'UI-ChangeManagementMenu-ChangesByType' => 'Cambi per tipo', + 'UI-ChangeManagementMenu-ChangesByStatus' => 'Cambi per stato', + 'UI-ChangeManagementMenu-ChangesByWorkgroup' => 'Cambi per gruppi di lavoro', + 'UI-ChangeManagementMenu-ChangesNotYetAssigned' => 'Cambi non ancora assegnati', + 'UI:ConfigurationItemsMenu' => 'Configuration Items', + 'UI:ConfigurationItemsMenu+' => '', + 'UI:ConfigurationItemsMenu:Title' => 'Configuration Items Panoramica', + 'UI-ConfigurationItemsMenu-ServersByCriticity' => 'Server per criticità', + 'UI-ConfigurationItemsMenu-PCsByCriticity' => 'PCs per criticità', + 'UI-ConfigurationItemsMenu-NWDevicesByCriticity' => 'Dispositivi di rete per criticità', + 'UI-ConfigurationItemsMenu-ApplicationsByCriticity' => 'Applicazioni per criticità', + 'UI:ConfigurationManagementMenu' => 'Gestione Configurazione', + 'UI:ConfigurationManagementMenu+' => '', + 'UI:ConfigurationManagementMenu:Title' => 'Panoramica delle infrastrutture', + 'UI-ConfigurationManagementMenu-InfraByType' => 'Oggetti infrastruttutura per tipo', + 'UI-ConfigurationManagementMenu-InfraByStatus' => 'Oggetti infrastruttutura per stato', + 'UI:ConfigMgmtMenuOverview:Title' => 'Cruscotto per Gestione configurazione', + 'UI-ConfigMgmtMenuOverview-FunctionalCIbyStatus' => 'Configuration Items per stato', + 'UI-ConfigMgmtMenuOverview-FunctionalCIByType' => 'Configuration Items per tipo', + 'UI:RequestMgmtMenuOverview:Title' => 'Cruscotto per Gestione Richieste', + 'UI-RequestManagementOverview-RequestByService' => 'Richieste degli utenti per servizio', + 'UI-RequestManagementOverview-RequestByPriority' => 'Richieste degli utenti per priorità', + 'UI-RequestManagementOverview-RequestUnassigned' => 'Richieste degli utenti non ancora assegnate ad un agente', + 'UI:IncidentMgmtMenuOverview:Title' => 'Cruscotto Gestione degli Incidenti', + 'UI-IncidentManagementOverview-IncidentByService' => 'Incidenti per servizio', + 'UI-IncidentManagementOverview-IncidentByPriority' => 'Incidenti per priorità', + 'UI-IncidentManagementOverview-IncidentUnassigned' => 'Incidenti non ancora assegnati ad un agente', + 'UI:ChangeMgmtMenuOverview:Title' => 'Cruscotto per Gestione dei Cambi', + 'UI-ChangeManagementOverview-ChangeByType' => 'Cambi per tipo', + 'UI-ChangeManagementOverview-ChangeUnassigned' => 'Cambi non ancora assegnati ad un agente', + 'UI-ChangeManagementOverview-ChangeWithOutage' => 'Interruzioni dovute ai cambi', + 'UI:ServiceMgmtMenuOverview:Title' => 'Cruscotto per Gestione dei Cambi', + 'UI-ServiceManagementOverview-CustomerContractToRenew' => 'Contratti con i clienti da rinnovarsi in 30 giorni', + 'UI-ServiceManagementOverview-ProviderContractToRenew' => 'Contratti con i fornitori da rinnovarsi in 30 giorni', + 'UI:ContactsMenu' => 'Contatti', + 'UI:ContactsMenu+' => '', + 'UI:ContactsMenu:Title' => 'Contatti Panoramica', + 'UI-ContactsMenu-ContactsByLocation' => 'Contatti per localizzazione', + 'UI-ContactsMenu-ContactsByType' => 'Contatti per tipo', + 'UI-ContactsMenu-ContactsByStatus' => 'Contatti per stato', + 'Menu:CSVImportMenu' => 'Importazione CSV', + 'Menu:CSVImportMenu+' => '', + 'Menu:DataModelMenu' => 'Modello Dati', + 'Menu:DataModelMenu+' => '', + 'Menu:ExportMenu' => 'Esporta', + 'Menu:ExportMenu+' => '', + 'Menu:NotificationsMenu' => 'Notifiche', + 'Menu:NotificationsMenu+' => '', + 'UI:NotificationsMenu:Title' => 'Configurazione delle Notifiche', + 'UI:NotificationsMenu:Help' => 'Aiuto', 'UI:NotificationsMenu:HelpContent' => '

    In iTop le notifiche sono completamente personalizzabili. Essi si basano su due serie di oggetti: trigger e azioni.

    Triggers per definire quando una notifica verrà eseguita. Ci sono 3 tipi di trigger per la copertura di 3 fasi differenti del ciclo di vita di un oggetto:

    1. the "OnCreate" trigger vengono eseguiti quando un oggetto della classe specificata viene creata
    2. the "OnStateEnter" trigger vengono eseguiti prima che un oggetto della classe data entra in uno stato specifico (provenienti da un altro Stato)
    3. -
    4. the "OnStateLeave" trigger vengono eseguiti quando un oggetto della classe lascia uno stato specificato
    5. -
    +
  • the "OnStateLeave" trigger vengono eseguiti quando un oggetto della classe lascia uno stato specificato
  • +

    @@ -670,105 +670,111 @@ Dict::Add('IT IT', 'Italian', 'Italiano', array( Inoltre, tali azioni definiscono il modello da utilizzare per l\'invio della e-mail così come gli altri parametri del messaggio come, l\'importanza dei destinatari, etc

    Una Pagina speciale: email.test.php è disponibile per il testing e la risoluzione dei problemi di configurazione PHP mail.

    -

    Per essere eseguite, le azioni devono essere associate ai trigger. -Quando è associata a un trigger, ad ogni azione è assegnato un numero "ordine", che specifica in quale ordine le azioni devono essere eseguite.

    ', - 'UI:NotificationsMenu:Triggers' => 'Triggers', - 'UI:NotificationsMenu:AvailableTriggers' => 'Triggers Disponibili', - 'UI:NotificationsMenu:OnCreate' => 'When an object is created~~', - 'UI:NotificationsMenu:OnStateEnter' => 'Quando un oggetto viene creato', - 'UI:NotificationsMenu:OnStateLeave' => 'Quando un oggetto lascia un determinato stato', - 'UI:NotificationsMenu:Actions' => 'Azioni', - 'UI:NotificationsMenu:AvailableActions' => 'Azioni disponibili', - 'Menu:AuditCategories' => 'Categorie di Audit', - 'Menu:AuditCategories+' => '', - 'Menu:Notifications:Title' => 'Categorie di Audit', - 'Menu:RunQueriesMenu' => 'Esegui query', - 'Menu:RunQueriesMenu+' => '', - 'Menu:DataAdministration' => 'Dati di amministrazione', - 'Menu:DataAdministration+' => '', - 'Menu:UniversalSearchMenu' => 'Ricerca universale', - 'Menu:UniversalSearchMenu+' => '', - 'Menu:ApplicationLogMenu' => 'Log dell\'applicazione', - 'Menu:ApplicationLogMenu+' => '', - 'Menu:ApplicationLogMenu:Title' => 'Log dell\'applicazione', - 'Menu:UserManagementMenu' => 'Gestione degli utenti', - 'Menu:UserManagementMenu+' => '', - 'Menu:ProfilesMenu' => 'Profili', - 'Menu:ProfilesMenu+' => '', - 'Menu:ProfilesMenu:Title' => 'Profili', - 'Menu:UserAccountsMenu' => 'Account utente', - 'Menu:UserAccountsMenu+' => '', - 'Menu:UserAccountsMenu:Title' => 'Account utente', - 'UI:iTopVersion:Short' => 'Versione iTop %1$s', - 'UI:iTopVersion:Long' => 'Versione iTop %1$s-%2$s costruita il %3$s', - 'UI:PropertiesTab' => 'Proprietà', - 'UI:OpenDocumentInNewWindow_' => 'Apri questo documento in una nuova finestra: %1$s', - 'UI:DownloadDocument_' => 'Scarica questo documento: %1$s', - 'UI:Document:NoPreview' => 'Non è disponibile un\'anteprima per questo tipo di documento', - 'UI:DeadlineMissedBy_duration' => 'Mancati %1$s', - 'UI:Deadline_LessThan1Min' => '< 1 min', - 'UI:Deadline_Minutes' => '%1$d min', - 'UI:Deadline_Hours_Minutes' => '%1$dh %2$dmin', - 'UI:Deadline_Days_Hours_Minutes' => '%1$dg %2$dh %3$dmin', - 'UI:Help' => 'Aiuto', - 'UI:PasswordConfirm' => '(Conferma)', - 'UI:BeforeAdding_Class_ObjectsSaveThisObject' => 'Prima di aggiungere più %1$s oggetti, salva questo oggetto.', - 'UI:DisplayThisMessageAtStartup' => 'Visualizza questo messaggio in fase di avvio', - 'UI:RelationshipGraph' => 'Visualizzazione grafica', - 'UI:RelationshipList' => 'Lista', - 'UI:OperationCancelled' => 'Operazione Annullata', - 'Portal:Title' => 'Portale Utente iTop', - 'Portal:Refresh' => 'Ricarica', - 'Portal:Back' => 'Indietro', - 'Portal:CreateNewRequest' => 'Crea una nuova richiesta', - 'Portal:ChangeMyPassword' => 'Cambia la mia password', - 'Portal:Disconnect' => 'Disconnetti', - 'Portal:OpenRequests' => 'Le mie richieste aperte', - 'Portal:ResolvedRequests' => 'Le mie richieste risolte', - 'Portal:SelectService' => 'Seleziona un servizio dal catalogo:', - 'Portal:PleaseSelectOneService' => 'Si prega di selezionare un servizio', - 'Portal:SelectSubcategoryFrom_Service' => 'Seleziona una sotto-categoria per il servizio %1$s:', - 'Portal:PleaseSelectAServiceSubCategory' => 'Si prega di selezionare una delle sottocategorie', - 'Portal:DescriptionOfTheRequest' => 'Inserisci la descrizione della tua richiesta:', - 'Portal:TitleRequestDetailsFor_Request' => 'Dettagli per la richiesta %1$s:', - 'Portal:NoOpenRequest' => 'Nessuna richiesta in questa categoria.', - 'Portal:Button:CloseTicket' => 'Chiudi questo ticket', - 'Portal:EnterYourCommentsOnTicket' => 'Inserisci il tuo commento sulla risoluzione di questo ticket:', - 'Portal:ErrorNoContactForThisUser' => 'Errore: l\'utente corrente non è associato ad un Contatto/Persona. Si prega di contattare l\'amministratore.', - 'Portal:Attachments' => 'Allegati', - 'Portal:AddAttachment' => ' Aggiungi allegati ', - 'Portal:RemoveAttachment' => ' Rimuovi allegati ', - 'Portal:Attachment_No_To_Ticket_Name' => 'Allegato #%1$d a %2$s (%3$s)', - 'Enum:Undefined' => 'Non definito', - 'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s Giorni %2$s Ore %3$s Minuti %4$s Secondi', - 'UI:ModifyAllPageTitle' => 'Modifica Tutto', - 'UI:Modify_N_ObjectsOf_Class' => 'Modifica %1$d oggetto della classe %2$s', - 'UI:Modify_M_ObjectsOf_Class_OutOf_N' => 'Modifica %1$d oggetto della classe %2$s fuori da %3$d~~', - 'UI:Menu:ModifyAll' => 'Modifica...', - 'UI:Button:ModifyAll' => 'Modifica tutto', - 'UI:Button:PreviewModifications' => 'Anteprima Modifiche >>~~', - 'UI:ModifiedObject' => 'Oggetto Modificato', - 'UI:BulkModifyStatus' => 'Operazioni', - 'UI:BulkModifyStatus+' => '', - 'UI:BulkModifyErrors' => 'Errori (eventuali)', - 'UI:BulkModifyErrors+' => '', - 'UI:BulkModifyStatusOk' => 'Ok', - 'UI:BulkModifyStatusError' => 'Errore', - 'UI:BulkModifyStatusModified' => 'Modificato', - 'UI:BulkModifyStatusSkipped' => 'Saltato', - 'UI:BulkModify_Count_DistinctValues' => '%1$d valori distinti:', - 'UI:BulkModify:Value_Exists_N_Times' => '%1$s, %2$d volta(e)', - 'UI:BulkModify:N_MoreValues' => '%1$d più valori...~~', - 'UI:AttemptingToSetAReadOnlyAttribute_Name' => 'Tentativo di impostare il campo di sola lettura: %1$s', - 'UI:FailedToApplyStimuli' => 'L\'azione non è riuscita.', - 'UI:StimulusModify_N_ObjectsOf_Class' => '%1$s: Modifica %2$d oggetti della classe %3$s~~', - 'UI:CaseLogTypeYourTextHere' => 'Digitare il tuo testo qui:', - 'UI:CaseLog:DateFormat' => 'A-m-g H:m:s', - 'UI:CaseLog:Header_Date_UserName' => '%1$s - %2$s:~~', - 'UI:CaseLog:InitialValue' => 'Valore iniziale:', - 'UI:AttemptingToSetASlaveAttribute_Name' => 'Il campo %1$s on è scrivibile, perché è comandato dalla sincronizzazione dei dati. Valore non impostato.', - 'UI:ActionNotAllowed' => 'Non hai i permessi per eseguire questa azione su questi oggetti.', - 'UI:BulkAction:NoObjectSelected' => 'Si prega di selezionare almeno un oggetto per eseguire questa operazione', - 'UI:AttemptingToChangeASlaveAttribute_Name' => 'Il campo %1$s on è scrivibile, perché è comandato dalla sincronizzazione dei dati. Valore rimane invariato.', -)); -?> +

    Per essere eseguite, le azioni devono essere associate ai trigger. +Quando è associata a un trigger, ad ogni azione è assegnato un numero "ordine", che specifica in quale ordine le azioni devono essere eseguite.

    ', + 'UI:NotificationsMenu:Triggers' => 'Triggers', + 'UI:NotificationsMenu:AvailableTriggers' => 'Triggers Disponibili', + 'UI:NotificationsMenu:OnCreate' => 'When an object is created~~', + 'UI:NotificationsMenu:OnStateEnter' => 'Quando un oggetto viene creato', + 'UI:NotificationsMenu:OnStateLeave' => 'Quando un oggetto lascia un determinato stato', + 'UI:NotificationsMenu:Actions' => 'Azioni', + 'UI:NotificationsMenu:AvailableActions' => 'Azioni disponibili', + 'Menu:AuditCategories' => 'Categorie di Audit', + 'Menu:AuditCategories+' => '', + 'Menu:Notifications:Title' => 'Categorie di Audit', + 'Menu:RunQueriesMenu' => 'Esegui query', + 'Menu:RunQueriesMenu+' => '', + 'Menu:DataAdministration' => 'Dati di amministrazione', + 'Menu:DataAdministration+' => '', + 'Menu:UniversalSearchMenu' => 'Ricerca universale', + 'Menu:UniversalSearchMenu+' => '', + 'Menu:ApplicationLogMenu' => 'Log dell\'applicazione', + 'Menu:ApplicationLogMenu+' => '', + 'Menu:ApplicationLogMenu:Title' => 'Log dell\'applicazione', + 'Menu:UserManagementMenu' => 'Gestione degli utenti', + 'Menu:UserManagementMenu+' => '', + 'Menu:ProfilesMenu' => 'Profili', + 'Menu:ProfilesMenu+' => '', + 'Menu:ProfilesMenu:Title' => 'Profili', + 'Menu:UserAccountsMenu' => 'Account utente', + 'Menu:UserAccountsMenu+' => '', + 'Menu:UserAccountsMenu:Title' => 'Account utente', + 'UI:iTopVersion:Short' => 'Versione iTop %1$s', + 'UI:iTopVersion:Long' => 'Versione iTop %1$s-%2$s costruita il %3$s', + 'UI:PropertiesTab' => 'Proprietà', + 'UI:OpenDocumentInNewWindow_' => 'Apri questo documento in una nuova finestra: %1$s', + 'UI:DownloadDocument_' => 'Scarica questo documento: %1$s', + 'UI:Document:NoPreview' => 'Non è disponibile un\'anteprima per questo tipo di documento', + 'UI:DeadlineMissedBy_duration' => 'Mancati %1$s', + 'UI:Deadline_LessThan1Min' => '< 1 min', + 'UI:Deadline_Minutes' => '%1$d min', + 'UI:Deadline_Hours_Minutes' => '%1$dh %2$dmin', + 'UI:Deadline_Days_Hours_Minutes' => '%1$dg %2$dh %3$dmin', + 'UI:Help' => 'Aiuto', + 'UI:PasswordConfirm' => '(Conferma)', + 'UI:BeforeAdding_Class_ObjectsSaveThisObject' => 'Prima di aggiungere più %1$s oggetti, salva questo oggetto.', + 'UI:DisplayThisMessageAtStartup' => 'Visualizza questo messaggio in fase di avvio', + 'UI:RelationshipGraph' => 'Visualizzazione grafica', + 'UI:RelationshipList' => 'Lista', + 'UI:OperationCancelled' => 'Operazione Annullata', + 'Portal:Title' => 'Portale Utente iTop', + 'Portal:Refresh' => 'Ricarica', + 'Portal:Back' => 'Indietro', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', + 'Portal:CreateNewRequest' => 'Crea una nuova richiesta', + 'Portal:ChangeMyPassword' => 'Cambia la mia password', + 'Portal:Disconnect' => 'Disconnetti', + 'Portal:OpenRequests' => 'Le mie richieste aperte', + 'Portal:ClosedRequests' => 'My closed requests', + 'Portal:ResolvedRequests' => 'Le mie richieste risolte', + 'Portal:SelectService' => 'Seleziona un servizio dal catalogo:', + 'Portal:PleaseSelectOneService' => 'Si prega di selezionare un servizio', + 'Portal:SelectSubcategoryFrom_Service' => 'Seleziona una sotto-categoria per il servizio %1$s:', + 'Portal:PleaseSelectAServiceSubCategory' => 'Si prega di selezionare una delle sottocategorie', + 'Portal:DescriptionOfTheRequest' => 'Inserisci la descrizione della tua richiesta:', + 'Portal:TitleRequestDetailsFor_Request' => 'Dettagli per la richiesta %1$s:', + 'Portal:NoOpenRequest' => 'Nessuna richiesta in questa categoria.', + 'Portal:NoClosedRequest' => 'Nessuna richiesta in questa categoria.', + 'Portal:Button:CloseTicket' => 'Chiudi questo ticket', + 'Portal:Button:UpdateRequest' => 'Update the request', + 'Portal:EnterYourCommentsOnTicket' => 'Inserisci il tuo commento sulla risoluzione di questo ticket:', + 'Portal:ErrorNoContactForThisUser' => 'Errore: l\'utente corrente non è associato ad un Contatto/Persona. Si prega di contattare l\'amministratore.', + 'Portal:Attachments' => 'Allegati', + 'Portal:AddAttachment' => ' Aggiungi allegati ', + 'Portal:RemoveAttachment' => ' Rimuovi allegati ', + 'Portal:Attachment_No_To_Ticket_Name' => 'Allegato #%1$d a %2$s (%3$s)', + 'Enum:Undefined' => 'Non definito', + 'UI:DurationForm_Days_Hours_Minutes_Seconds' => '%1$s Giorni %2$s Ore %3$s Minuti %4$s Secondi', + 'UI:ModifyAllPageTitle' => 'Modifica Tutto', + 'UI:Modify_N_ObjectsOf_Class' => 'Modifica %1$d oggetto della classe %2$s', + 'UI:Modify_M_ObjectsOf_Class_OutOf_N' => 'Modifica %1$d oggetto della classe %2$s fuori da %3$d~~', + 'UI:Menu:ModifyAll' => 'Modifica...', + 'UI:Button:ModifyAll' => 'Modifica tutto', + 'UI:Button:PreviewModifications' => 'Anteprima Modifiche >>~~', + 'UI:ModifiedObject' => 'Oggetto Modificato', + 'UI:BulkModifyStatus' => 'Operazioni', + 'UI:BulkModifyStatus+' => '', + 'UI:BulkModifyErrors' => 'Errori (eventuali)', + 'UI:BulkModifyErrors+' => '', + 'UI:BulkModifyStatusOk' => 'Ok', + 'UI:BulkModifyStatusError' => 'Errore', + 'UI:BulkModifyStatusModified' => 'Modificato', + 'UI:BulkModifyStatusSkipped' => 'Saltato', + 'UI:BulkModify_Count_DistinctValues' => '%1$d valori distinti:', + 'UI:BulkModify:Value_Exists_N_Times' => '%1$s, %2$d volta(e)', + 'UI:BulkModify:N_MoreValues' => '%1$d più valori...~~', + 'UI:AttemptingToSetAReadOnlyAttribute_Name' => 'Tentativo di impostare il campo di sola lettura: %1$s', + 'UI:FailedToApplyStimuli' => 'L\'azione non è riuscita.', + 'UI:StimulusModify_N_ObjectsOf_Class' => '%1$s: Modifica %2$d oggetti della classe %3$s~~', + 'UI:CaseLogTypeYourTextHere' => 'Digitare il tuo testo qui:', + 'UI:CaseLog:DateFormat' => 'A-m-g H:m:s', + 'UI:CaseLog:Header_Date_UserName' => '%1$s - %2$s:~~', + 'UI:CaseLog:InitialValue' => 'Valore iniziale:', + 'UI:AttemptingToSetASlaveAttribute_Name' => 'Il campo %1$s on è scrivibile, perché è comandato dalla sincronizzazione dei dati. Valore non impostato.', + 'UI:ActionNotAllowed' => 'Non hai i permessi per eseguire questa azione su questi oggetti.', + 'UI:BulkAction:NoObjectSelected' => 'Si prega di selezionare almeno un oggetto per eseguire questa operazione', + 'UI:AttemptingToChangeASlaveAttribute_Name' => 'Il campo %1$s on è scrivibile, perché è comandato dalla sincronizzazione dei dati. Valore rimane invariato.', +)); +?> diff --git a/dictionaries/ja.dictionary.itop.ui.php b/dictionaries/ja.dictionary.itop.ui.php index f17967e537..c3ab05e5be 100644 --- a/dictionaries/ja.dictionary.itop.ui.php +++ b/dictionaries/ja.dictionary.itop.ui.php @@ -880,10 +880,14 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Portal:Title' => 'iTopユーザポータル', // 'iTop user portal', 'Portal:Refresh' => '更新', // 'Refresh', 'Portal:Back' => '戻る', // 'Back', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => '新規リクエストを生成する', // 'Create a new request', 'Portal:ChangeMyPassword' => 'パスワードを変更する', // 'Change my password', 'Portal:Disconnect' => '切断する', // 'Disconnect', 'Portal:OpenRequests' => '発行済みリクエスト', // 'My open requests', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => '解決済みリクエスト', // 'My resolved requests', 'Portal:SelectService' => 'カタログからサービスを選択してください:', // 'Select a service from the catalog:', 'Portal:PleaseSelectOneService' => 'サービスを1つ選んでください', // 'Please select one service', @@ -892,7 +896,9 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Portal:DescriptionOfTheRequest' => 'あなたのリクエストの詳細を記入してください:', // 'Enter the description of your request:', 'Portal:TitleRequestDetailsFor_Request' => 'リクエスト%1$sの詳細:', // Details for request %1$s:', 'Portal:NoOpenRequest' => '本カテゴリにリクエストはありません', // 'No request in this category.', + 'Portal:NoClosedRequest' => 'No request in this category', 'Portal:Button:CloseTicket' => '本チケットを閉じます。', // 'Close this ticket', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => '本チケットの解決について、コメントを入力してください。', // 'Enter your comments about the resolution of this ticket:', 'Portal:ErrorNoContactForThisUser' => 'エラー:現在のユーザはコンタクト/人物に関連づけられていません。管理者に問い合わせてください。', // 'Error: the current user is not associated with a Contact/Person. Please contact your administrator.', 'Portal:Attachments' => '添付', // 'Attachments', diff --git a/dictionaries/pt_br.dictionary.itop.ui.php b/dictionaries/pt_br.dictionary.itop.ui.php index cdd7d0e585..b8d29de34a 100644 --- a/dictionaries/pt_br.dictionary.itop.ui.php +++ b/dictionaries/pt_br.dictionary.itop.ui.php @@ -718,10 +718,14 @@ When associated with a trigger, each action is given an "order" number, specifyi 'Portal:Title' => 'Portal do usuário', 'Portal:Refresh' => 'Atualizar', 'Portal:Back' => 'Voltar', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => 'Criar uma nova requisição', 'Portal:ChangeMyPassword' => 'Alterar minha senha', 'Portal:Disconnect' => 'Sair', 'Portal:OpenRequests' => 'Minhas requisições abertas', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => 'Minhas requisições resolvidas', 'Portal:SelectService' => 'Selecione um serviço do catálogo:', 'Portal:PleaseSelectOneService' => 'Por favor, selecione um serviço', @@ -730,7 +734,9 @@ When associated with a trigger, each action is given an "order" number, specifyi 'Portal:DescriptionOfTheRequest' => 'Digite a descrição de sua solicitação:', 'Portal:TitleRequestDetailsFor_Request' => 'Detalhes para requisição %1$s:', 'Portal:NoOpenRequest' => 'Nenhuma requisição neste categoria.', + 'Portal:NoClosedRequest' => 'Nenhuma requisição neste categoria.', 'Portal:Button:CloseTicket' => 'Fechar este ticket', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Digite os seus comentários sobre a resolução deste incidente:', 'Portal:ErrorNoContactForThisUser' => 'Erro: o usuátio atual não está associado com um contato/pessoa. Por favor, contate o administrador.', 'Portal:Attachments' => 'Anexos', diff --git a/dictionaries/ru.dictionary.itop.ui.php b/dictionaries/ru.dictionary.itop.ui.php index 1dc8ef3163..8258eefae5 100644 --- a/dictionaries/ru.dictionary.itop.ui.php +++ b/dictionaries/ru.dictionary.itop.ui.php @@ -848,10 +848,14 @@ Dict::Add('RU RU', 'Russian', 'Русский', array( 'Portal:Title' => 'Пользовательский iTop портал', 'Portal:Refresh' => 'Обновить', 'Portal:Back' => 'Назад', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => 'Создать новый запрос', 'Portal:ChangeMyPassword' => 'Изменить мой пароль', 'Portal:Disconnect' => 'Отключить', 'Portal:OpenRequests' => 'Мои открытые запросы', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => 'Мои решённые запросы', 'Portal:SelectService' => 'Выбери сервис из каталога:', 'Portal:PleaseSelectOneService' => 'Необходимо выбрать хотя-бы один сервис', @@ -860,7 +864,9 @@ Dict::Add('RU RU', 'Russian', 'Русский', array( 'Portal:DescriptionOfTheRequest' => 'Введи описание запроса:', 'Portal:TitleRequestDetailsFor_Request' => 'Подробности запроса %1$s:', 'Portal:NoOpenRequest' => 'Нет запросов в этой категории.', + 'Portal:NoClosedRequest' => 'No request in this category', 'Portal:Button:CloseTicket' => 'Закрыть этот "тикет"', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Введите ваши каментарии по решению этого "тикета":', 'Portal:ErrorNoContactForThisUser' => 'Ошибка: текющий пользователь не ассоциирован с Контактом/Человеком. Пожалуйста свяжитесь с вашим администратором.', diff --git a/dictionaries/tr.dictionary.itop.ui.php b/dictionaries/tr.dictionary.itop.ui.php index 21653713e6..d6cd4788a6 100644 --- a/dictionaries/tr.dictionary.itop.ui.php +++ b/dictionaries/tr.dictionary.itop.ui.php @@ -847,10 +847,14 @@ Tetikleme gerçekleştiriğinde işlemler tanımlanan sıra numarası ile gerçe 'Portal:Title' => 'iTop Kullanıcı Portalı', 'Portal:Refresh' => 'Yenile', 'Portal:Back' => 'Geri', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => 'Yeni istek yarat', 'Portal:ChangeMyPassword' => 'Şifre değiştir', 'Portal:Disconnect' => 'Çıkış', 'Portal:OpenRequests' => 'Açık isteklerim', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => 'Çözdüğüm istekler', 'Portal:SelectService' => 'Kataloğdan servis seçiniz:', 'Portal:PleaseSelectOneService' => 'Sevis seçiniz', @@ -859,7 +863,9 @@ Tetikleme gerçekleştiriğinde işlemler tanımlanan sıra numarası ile gerçe 'Portal:DescriptionOfTheRequest' => 'İstek tanımlaması:', 'Portal:TitleRequestDetailsFor_Request' => 'İsteğin detayı %1$s:', 'Portal:NoOpenRequest' => 'Bu kategoride istek yok.', + 'Portal:NoClosedRequest' => 'Bu kategoride istek yok.', 'Portal:Button:CloseTicket' => 'Çağrıyı kapat', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'İsteğin çözümüne yönelik açıklamalar:', 'Portal:ErrorNoContactForThisUser' => 'Hata: mevcut kullanıcının irtibat bilgisi yok. Sistem yöneticisi ile irtibata geçiniz.', diff --git a/dictionaries/zh.dictionary.itop.ui.php b/dictionaries/zh.dictionary.itop.ui.php index ff01bcc1ae..70b724e7a4 100644 --- a/dictionaries/zh.dictionary.itop.ui.php +++ b/dictionaries/zh.dictionary.itop.ui.php @@ -846,10 +846,14 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array( 'Portal:Title' => 'iTop 用户门户', 'Portal:Refresh' => '刷新', 'Portal:Back' => '返回', + 'Portal:WelcomeUserOrg' => 'Welcome %1$s, from %2$s', + 'Portal:ShowOngoing' => 'Show open requests', + 'Portal:ShowClosed' => 'Show closed requests', 'Portal:CreateNewRequest' => '创建一个新的请求', 'Portal:ChangeMyPassword' => '改变我的密码', 'Portal:Disconnect' => '断开', 'Portal:OpenRequests' => '我的待解决的请求', + 'Portal:ClosedRequests' => 'My closed requests', 'Portal:ResolvedRequests' => '我的已解决的请求', 'Portal:SelectService' => '从类目中选择一个服务:', 'Portal:PleaseSelectOneService' => '请选择一个服务', @@ -858,7 +862,9 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array( 'Portal:DescriptionOfTheRequest' => '输入您的请求描述:', 'Portal:TitleRequestDetailsFor_Request' => '请求明细内容 %1$s:', 'Portal:NoOpenRequest' => '该类目中没有请求.', + 'Portal:NoClosedRequest' => 'No request in this category', 'Portal:Button:CloseTicket' => '关闭这个单据', + 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => '输入您对于该单据解决情况的评述:', 'Portal:ErrorNoContactForThisUser' => '错误: 当前用户没有和一个联系人或人员关联. 请联系您的系统管理员.', From abd645ca982dac796c7d660fa4f065e77e74d60d Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 15 Sep 2011 15:25:30 +0000 Subject: [PATCH 03/23] Fixed regressions in the portal SVN:trunk[1579] --- portal/index.php | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/portal/index.php b/portal/index.php index fa3326c719..35f0219258 100644 --- a/portal/index.php +++ b/portal/index.php @@ -38,6 +38,27 @@ define('VALIDATE_SERVICESUBCATEGORY_QUERY', 'SELECT ServiceSubcategory AS Sub JO define('ALL_PARAMS', 'from_service_id,org_id,caller_id,service_id,servicesubcategory_id,title,description,impact,urgency,workgroup_id,moreinfo,caller_id,start_date,end_date,duration,impact_duration'); +/** + * Direct end-users to the standard Portal application + */ +class MyPortalURLMaker implements iDBObjectURLMaker +{ + public static function MakeObjectURL($sClass, $iId) + { + switch($sClass) + { + case 'UserRequest': + $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot(); + $sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class=$sClass&id=$iId"; + return $sUrl; + + default: + return ''; + } + } +} + + /** * Displays the portal main menu * @param WebPage $oP The current web page @@ -466,7 +487,7 @@ function ListClosedTickets(WebPage $oP) $iUser = UserRights::GetUserId(); if ($iUser > 0) { - $oSearch->AddCondition('caller_id', $iUser + 12345); + $oSearch->AddCondition('caller_id', $iUser); } $oSet1 = new CMDBObjectSet($oSearch); $oP->add("

    \n"); @@ -742,7 +763,7 @@ try require_once(APPROOT.'/application/loginwebpage.class.inc.php'); LoginWebPage::DoLogin(false /* bMustBeAdmin */, true /* IsAllowedToPortalUsers */); // Check user rights and prompt if needed - ApplicationContext::SetUrlMakerClass('PortalURLMaker'); + ApplicationContext::SetUrlMakerClass('MyPortalURLMaker'); $oUserOrg = GetUserOrg(); From cac76a7e086dfa91894e46a6cd1b17b5a6e85743 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Mon, 19 Sep 2011 10:36:47 +0000 Subject: [PATCH 04/23] #473 Could not load NW interfaces (reconciliation issue) SVN:trunk[1581] --- core/attributedef.class.inc.php | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 7df4cb0fab..09cbd54352 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -180,7 +180,7 @@ abstract class AttributeDefinition public function IsNullAllowed() {return true;} public function GetCode() {return $this->m_sCode;} - public function GetLabel() + public function GetLabel($sDefault = '') { $sLabel = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode, ''); if (strlen($sLabel) == 0) @@ -192,9 +192,14 @@ abstract class AttributeDefinition if (MetaModel::IsValidAttCode($sParentClass, $this->m_sCode)) { $oAttDef = MetaModel::GetAttributeDef($sParentClass, $this->m_sCode); - $sLabel = $oAttDef->GetLabel(); + $sLabel = $oAttDef->GetLabel($sDefault); } } + else + { + // Nothing defined in the class hierarchy: return the default value + $sLabel = $sDefault; + } } return $sLabel; } @@ -212,7 +217,7 @@ abstract class AttributeDefinition } } - public function GetDescription() + public function GetDescription($sDefault = '') { $sDescription = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'+', ''); if (strlen($sDescription) == 0) @@ -223,14 +228,19 @@ abstract class AttributeDefinition if (MetaModel::IsValidAttCode($sParentClass, $this->m_sCode)) { $oAttDef = MetaModel::GetAttributeDef($sParentClass, $this->m_sCode); - $sDescription = $oAttDef->GetDescription(); + $sDescription = $oAttDef->GetDescription($sDefault); } } + else + { + // Nothing defined in the class hierarchy: return the default value + $sDescription = $sDefault; + } } return $sDescription; } - public function GetHelpOnEdition() + public function GetHelpOnEdition($sDefault = '') { $sHelp = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'?', ''); if (strlen($sHelp) == 0) @@ -241,9 +251,14 @@ abstract class AttributeDefinition if (MetaModel::IsValidAttCode($sParentClass, $this->m_sCode)) { $oAttDef = MetaModel::GetAttributeDef($sParentClass, $this->m_sCode); - $sHelp = $oAttDef->GetHelpOnEdition(); + $sHelp = $oAttDef->GetHelpOnEdition($sDefault); } } + else + { + // Nothing defined in the class hierarchy: return the default value + $sHelp = $sDefault; + } } return $sHelp; } @@ -2718,19 +2733,19 @@ class AttributeExternalField extends AttributeDefinition { $oRemoteAtt = $this->GetExtAttDef(); $sDefault = $oRemoteAtt->GetLabel(); - return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode, $sDefault); + return parent::GetLabel($sDefault); } public function GetDescription() { $oRemoteAtt = $this->GetExtAttDef(); $sDefault = $oRemoteAtt->GetDescription(); - return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'+', $sDefault); + return parent::GetDescription($sDefault); } public function GetHelpOnEdition() { $oRemoteAtt = $this->GetExtAttDef(); $sDefault = $oRemoteAtt->GetHelpOnEdition(); - return Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'?', $sDefault); + return parent::GetHelpOnEdition($sDefault); } public function IsExternalKey($iType = EXTKEY_RELATIVE) From 19318973ca168c31bafcd618a9925a25e0225016 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Mon, 19 Sep 2011 11:44:04 +0000 Subject: [PATCH 05/23] Fixed warning (strict standards) on previous fix SVN:trunk[1584] --- core/attributedef.class.inc.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 09cbd54352..edd9ac9680 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -2729,19 +2729,19 @@ class AttributeExternalField extends AttributeDefinition } } - public function GetLabel() + public function GetLabel($sDefault = '') { $oRemoteAtt = $this->GetExtAttDef(); $sDefault = $oRemoteAtt->GetLabel(); return parent::GetLabel($sDefault); } - public function GetDescription() + public function GetDescription($sDefault = '') { $oRemoteAtt = $this->GetExtAttDef(); $sDefault = $oRemoteAtt->GetDescription(); return parent::GetDescription($sDefault); } - public function GetHelpOnEdition() + public function GetHelpOnEdition($sDefault = '') { $oRemoteAtt = $this->GetExtAttDef(); $sDefault = $oRemoteAtt->GetHelpOnEdition(); From 2b1aecda5373f8d8eb2e1a945a777cdd92688202 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 20 Sep 2011 08:22:54 +0000 Subject: [PATCH 06/23] Fixed recent regression on the portal (confusion btw GetContactId and GetUserId) SVN:trunk[1586] --- portal/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/portal/index.php b/portal/index.php index 35f0219258..17fa62577c 100644 --- a/portal/index.php +++ b/portal/index.php @@ -431,7 +431,7 @@ function ListOpenRequests(WebPage $oP) $sOQL = 'SELECT UserRequest WHERE org_id = :org_id AND status NOT IN ("closed")'; $oSearch = DBObjectSearch::FromOQL($sOQL); - $iUser = UserRights::GetUserId(); + $iUser = UserRights::GetContactId(); if ($iUser > 0) { $oSearch->AddCondition('caller_id', $iUser); @@ -452,7 +452,7 @@ function ListResolvedRequests(WebPage $oP) $sOQL = 'SELECT UserRequest WHERE org_id = :org_id AND status = "resolved"'; $oSearch = DBObjectSearch::FromOQL($sOQL); - $iUser = UserRights::GetUserId(); + $iUser = UserRights::GetContactId(); if ($iUser > 0) { $oSearch->AddCondition('caller_id', $iUser); @@ -484,7 +484,7 @@ function ListClosedTickets(WebPage $oP) } $oSearch->AddCondition('org_id', $oUserOrg->GetKey()); $oSearch->AddCondition('status', 'closed'); - $iUser = UserRights::GetUserId(); + $iUser = UserRights::GetContactId(); if ($iUser > 0) { $oSearch->AddCondition('caller_id', $iUser); From b46ed4764dca4d79be82a846d1107e08bf6fdb45 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Tue, 20 Sep 2011 13:50:11 +0000 Subject: [PATCH 07/23] Fixed bug in the new portal: the wizard validation was inoperant when several selection lists were proposed SVN:trunk[1587] --- application/portalwebpage.class.inc.php | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/application/portalwebpage.class.inc.php b/application/portalwebpage.class.inc.php index 77e97603af..4e03c0d8aa 100644 --- a/application/portalwebpage.class.inc.php +++ b/application/portalwebpage.class.inc.php @@ -147,9 +147,18 @@ EOF $this->add_script( << 0); + var bResult; + if (sInputId.length > 0) + { + bResult = ($('input[name='+sInputId+']:checked').length > 0); + } + else + { + // First select found... + bResult = ($('input:checked').length > 0); + } if (!bResult) { alert(sMessage); @@ -804,12 +813,12 @@ EOF } } - public function WizardCheckSelectionOnSubmit($sMessageIfNoSelection) + public function WizardCheckSelectionOnSubmit($sMessageIfNoSelection, $sInputName = '') { $this->add_ready_script( <<m_sWizardId}').submit(function() { - return CheckSelection('$sMessageIfNoSelection'); + return CheckSelection('$sMessageIfNoSelection', '$sInputName'); }); EOF ); From b0145961726904a2c01dd54cb0597fb021609c62 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 21 Sep 2011 12:27:08 +0000 Subject: [PATCH 08/23] #477 Could not specify more than one reconciliation key (regression) + took the opportunity to enhance protection against XSS injection (using column names in the data) SVN:trunk[1588] --- webservices/import.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/webservices/import.php b/webservices/import.php index f206912ad1..16fd53aed6 100644 --- a/webservices/import.php +++ b/webservices/import.php @@ -277,9 +277,9 @@ try $sQualifier = ReadParam($oP, 'qualifier', 'raw_data'); $sCharSet = ReadParam($oP, 'charset', 'raw_data'); $sDateFormat = ReadParam($oP, 'date_format', 'raw_data'); - $sOutput = ReadParam($oP, 'output'); + $sOutput = ReadParam($oP, 'output', 'string'); // $sReportLevel = ReadParam($oP, 'reportlevel'); - $sReconcKeys = ReadParam($oP, 'reconciliationkeys', 'field_name'); + $sReconcKeys = ReadParam($oP, 'reconciliationkeys', 'raw_data'); $sSimulate = ReadParam($oP, 'simulate'); $sComment = ReadParam($oP, 'comment', 'raw_data'); @@ -434,9 +434,12 @@ try } else { - $aFieldList[$iFieldId] = $sFieldName; + // Secure the field names against XSS injection (no <> neither " chars) + $sSafeName = str_replace(array('"', '<', '>'), '', $sFieldName); + $aFieldList[$iFieldId] = $sSafeName; } - } + } + // Note: at this stage the list of fields is supposed to be made of attcodes (and the symbol '->') $aAttList = array(); $aExtKeys = array(); @@ -537,7 +540,9 @@ try { if (!array_key_exists($sReconcKey, $aExtKeys)) { - throw new BulkLoadException("Reconciliation keys not found in the input columns '$sReconcKey' (class: '$sClass')"); + // Protect against XSS injection + $sSafeName = str_replace(array('"', '<', '>'), '', $sReconcKey); + throw new BulkLoadException("Reconciliation key not found in the input columns: '$sSafeName'"); } } From 0de75db474bf5d0d9e5f161f7f8756b307f9388b Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 21 Sep 2011 12:59:16 +0000 Subject: [PATCH 09/23] Portal (regression with the latest implementation, causing a warning) SVN:trunk[1590] --- .../model.itop-welcome-itil.php | 20 +++++++++++++++++++ portal/index.php | 20 ------------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/modules/itop-welcome-itil/model.itop-welcome-itil.php b/modules/itop-welcome-itil/model.itop-welcome-itil.php index 3e177e5e93..a48cfb9b4d 100644 --- a/modules/itop-welcome-itil/model.itop-welcome-itil.php +++ b/modules/itop-welcome-itil/model.itop-welcome-itil.php @@ -63,4 +63,24 @@ class ItopWelcome extends ModuleHandlerAPI } } +/** + * Direct end-users to the standard Portal application + */ +class MyPortalURLMaker implements iDBObjectURLMaker +{ + public static function MakeObjectURL($sClass, $iId) + { + switch($sClass) + { + case 'UserRequest': + $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot(); + $sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class=$sClass&id=$iId"; + return $sUrl; + + default: + return ''; + } + } +} + ?> diff --git a/portal/index.php b/portal/index.php index 17fa62577c..53ee9d774f 100644 --- a/portal/index.php +++ b/portal/index.php @@ -38,26 +38,6 @@ define('VALIDATE_SERVICESUBCATEGORY_QUERY', 'SELECT ServiceSubcategory AS Sub JO define('ALL_PARAMS', 'from_service_id,org_id,caller_id,service_id,servicesubcategory_id,title,description,impact,urgency,workgroup_id,moreinfo,caller_id,start_date,end_date,duration,impact_duration'); -/** - * Direct end-users to the standard Portal application - */ -class MyPortalURLMaker implements iDBObjectURLMaker -{ - public static function MakeObjectURL($sClass, $iId) - { - switch($sClass) - { - case 'UserRequest': - $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot(); - $sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class=$sClass&id=$iId"; - return $sUrl; - - default: - return ''; - } - } -} - /** * Displays the portal main menu From da2b8ab4c091b725beea4fc1219285047cfdc954 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 22 Sep 2011 09:04:12 +0000 Subject: [PATCH 10/23] Fixed security issue: the attachments were visible by anybody (by forming URLs manually), whatever the allowed organizations. The change requires the execution of the setup/migration procedure. SVN:trunk[1591] --- modules/itop-attachments/ajax.attachment.php | 28 ++--- .../itop-attachments/model.attachments.php | 108 +++++++++++++++++- .../itop-attachments/module.attachments.php | 60 +++++++++- pages/ajax.render.php | 19 +-- 4 files changed, 188 insertions(+), 27 deletions(-) diff --git a/modules/itop-attachments/ajax.attachment.php b/modules/itop-attachments/ajax.attachment.php index b3119b0e38..dd72852607 100644 --- a/modules/itop-attachments/ajax.attachment.php +++ b/modules/itop-attachments/ajax.attachment.php @@ -63,25 +63,25 @@ try { try { - $oDoc = utils::ReadPostedDocument('file'); - $oAttachment = MetaModel::NewObject('Attachment'); - $oAttachment->Set('expire', time() + 3600); // one hour... - $oAttachment->Set('temp_id', $sTempId); - $oAttachment->Set('item_class', $sObjClass); - $oAttachment->Set('item_id', 0); - $oAttachment->Set('contents', $oDoc); - $iAttId = $oAttachment->DBInsert(); - - $aResult['msg'] = $oDoc->GetFileName(); - $aResult['icon'] = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($oDoc->GetFileName()); - $aResult['att_id'] = $iAttId; + $oDoc = utils::ReadPostedDocument('file'); + $oAttachment = MetaModel::NewObject('Attachment'); + $oAttachment->Set('expire', time() + 3600); // one hour... + $oAttachment->Set('temp_id', $sTempId); + $oAttachment->Set('item_class', $sObjClass); + $oAttachment->SetDefaultOrgId(); + $oAttachment->Set('contents', $oDoc); + $iAttId = $oAttachment->DBInsert(); + + $aResult['msg'] = $oDoc->GetFileName(); + $aResult['icon'] = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($oDoc->GetFileName()); + $aResult['att_id'] = $iAttId; } catch (FileUploadException $e) { $aResult['error'] = $e->GetMessage(); } - } - $oPage->add(json_encode($aResult)); + } + $oPage->add(json_encode($aResult)); break; case 'remove': diff --git a/modules/itop-attachments/model.attachments.php b/modules/itop-attachments/model.attachments.php index d6bc0b4e92..6d4446fb0f 100644 --- a/modules/itop-attachments/model.attachments.php +++ b/modules/itop-attachments/model.attachments.php @@ -34,7 +34,7 @@ class Attachment extends DBObject { $aParams = array ( - "category" => "addon", + "category" => "addon,bizmodel", "key_type" => "autoincrement", "name_attcode" => array('item_class', 'temp_id'), "state_attcode" => "", @@ -51,15 +51,107 @@ class Attachment extends DBObject MetaModel::Init_AddAttribute(new AttributeString("item_class", array("allowed_values"=>null, "sql"=>"item_class", "default_value"=>"", "is_null_allowed"=>false, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeString("item_id", array("allowed_values"=>null, "sql"=>"item_id", "default_value"=>"", "is_null_allowed"=>true, "depends_on"=>array()))); + MetaModel::Init_AddAttribute(new AttributeInteger("item_org_id", array("allowed_values"=>null, "sql"=>"item_org_id", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array()))); MetaModel::Init_AddAttribute(new AttributeBlob("contents", array("depends_on"=>array()))); - MetaModel::Init_SetZListItems('details', array('temp_id', 'item_class', 'item_id')); + MetaModel::Init_SetZListItems('details', array('temp_id', 'item_class', 'item_id', 'item_org_id')); MetaModel::Init_SetZListItems('advanced_search', array('temp_id', 'item_class', 'item_id')); MetaModel::Init_SetZListItems('standard_search', array('temp_id', 'item_class', 'item_id')); MetaModel::Init_SetZListItems('list', array('temp_id', 'item_class', 'item_id')); } + /** + * Maps the given context parameter name to the appropriate filter/search code for this class + * @param string $sContextParam Name of the context parameter, e.g. 'org_id' + * @return string Filter code, e.g. 'customer_id' + */ + public static function MapContextParam($sContextParam) + { + if ($sContextParam == 'org_id') + { + return 'item_org_id'; + } + else + { + return null; + } + } + + /** + * Set/Update all of the '_item' fields + * @param object $oItem Container item + * @return void + */ + public function SetItem($oItem, $bUpdateOnChange = false) + { + $sClass = get_class($oItem); + $iItemId = $oItem->GetKey(); + + $this->Set('item_class', $sClass); + $this->Set('item_id', $iItemId); + + $aCallSpec = array($sClass, 'MapContextParam'); + if (is_callable($aCallSpec)) + { + $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter + if (MetaModel::IsValidAttCode($sClass, $sAttCode)) + { + $iOrgId = $oItem->Get($sAttCode); + if ($iOrgId > 0) + { + if ($iOrgId != $this->Get('item_org_id')) + { + $this->Set('item_org_id', $iOrgId); + if ($bUpdateOnChange) + { + $this->DBUpdate(); + } + } + } + } + } + } + + /** + * Give a default value for item_org_id (if relevant...) + * @return void + */ + public function SetDefaultOrgId() + { + // First check that the organization CAN be fetched from the target class + // + $sClass = $this->Get('item_class'); + $aCallSpec = array($sClass, 'MapContextParam'); + if (is_callable($aCallSpec)) + { + $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter + if (MetaModel::IsValidAttCode($sClass, $sAttCode)) + { + // Second: check that the organization CAN be fetched from the current user + // + if (MetaModel::IsValidClass('Person')) + { + $aCallSpec = array($sClass, 'MapContextParam'); + if (is_callable($aCallSpec)) + { + $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter + if (MetaModel::IsValidAttCode($sClass, $sAttCode)) + { + // OK - try it + // + $oCurrentPerson = MetaModel::GetObject('Person', UserRights::GetContactId(), false); + if ($oCurrentPerson) + { + $this->Set('item_org_id', $oCurrentPerson->Get($sAttCode)); + } + } + } + } + } + } + } + // Todo - implement a cleanup function (see a way to do that generic !) } @@ -181,6 +273,16 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt public function OnDBUpdate($oObject, $oChange = null) { + if ($this->IsTargetObject($oObject)) + { + // Get all current attachments + $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id"); + $oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey())); + while ($oAttachment = $oSet->Fetch()) + { + $oAttachment->SetItem($oObject, true /*updateonchange*/); + } + } } public function OnDBInsert($oObject, $oChange = null) @@ -424,7 +526,7 @@ EOF } else { - $oAttachment->Set('item_id', $oObject->GetKey()); + $oAttachment->SetItem($oObject); $oAttachment->Set('temp_id', ''); $oAttachment->DBUpdate(); // temporary attachment confirmed, list it in the history diff --git a/modules/itop-attachments/module.attachments.php b/modules/itop-attachments/module.attachments.php index d5cbc8ec9f..149fe7e126 100644 --- a/modules/itop-attachments/module.attachments.php +++ b/modules/itop-attachments/module.attachments.php @@ -30,6 +30,7 @@ SetupWebPage::AddModule( ), 'mandatory' => false, 'visible' => true, + 'installer' => 'AttachmentInstaller', // Components // @@ -63,4 +64,61 @@ SetupWebPage::AddModule( ), ) ); -?> + +// Module installation handler +// +class AttachmentInstaller extends ModuleInstallerAPI +{ + public static function BeforeWritingConfig(Config $oConfiguration) + { + // If you want to override/force some configuration values, do it here + return $oConfiguration; + } + + /** + * Handler called before creating or upgrading the database schema + * @param $oConfiguration Config The new configuration of the application + * @param $sPreviousVersion string PRevious version number of the module (empty string in case of first install) + * @param $sCurrentVersion string Current version number of the module + */ + public static function BeforeDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion) + { + // If you want to migrate data from one format to another, do it here + } + + /** + * Handler called after the creation/update of the database schema + * @param $oConfiguration Config The new configuration of the application + * @param $sPreviousVersion string PRevious version number of the module (empty string in case of first install) + * @param $sCurrentVersion string Current version number of the module + */ + public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion) + { + // For each record having item_org_id unset, + // get the org_id from the container object + // + // Prerequisite: change null into 0 (workaround to the fact that we cannot use IS NULL in OQL) + SetupWebPage::log_info("Initializing attachment/item_org_id - null to zero"); + $sRepair = "UPDATE `Attachment` SET `item_org_id` = 0 WHERE `item_org_id` IS NULL"; + CMDBSource::Query($sRepair); + + SetupWebPage::log_info("Initializing attachment/item_org_id - zero to the container"); + $oSearch = DBObjectSearch::FromOQL('SELECT Attachment WHERE item_org_id = 0'); + $oSet = new DBObjectSet($oSearch); + $iUpdated = 0; + while ($oAttachment = $oSet->Fetch()) + { + $oContainer = MetaModel::GetObject($oAttachment->Get('item_class'), $oAttachment->Get('item_id'), false /* must be found */, true /* allow all data */); + if ($oContainer) + { + $oAttachment->SetItem($oContainer, true /*updateonchange*/); + $iUpdated++; + } + } + + SetupWebPage::log_info("Initializing attachment/item_org_id - $iUpdated records have been adjusted"); + } +} + + +?> \ No newline at end of file diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 8721539ffe..974961a8cf 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -592,16 +592,17 @@ function DownloadDocument(WebPage $oPage, $sClass, $id, $sAttCode, $sContentDisp { try { - $oObj = MetaModel::GetObject($sClass, $id); - if (is_object($oObj)) + $oObj = MetaModel::GetObject($sClass, $id, false, false); + if (!is_object($oObj)) { - $oDocument = $oObj->Get($sAttCode); - if (is_object($oDocument)) - { - $oPage->SetContentType($oDocument->GetMimeType()); - $oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName()); - $oPage->add($oDocument->GetData()); - } + throw new Exception("Invalid id ($id) for class '$sClass' - the object does not exist or you are not allowed to view it"); + } + $oDocument = $oObj->Get($sAttCode); + if (is_object($oDocument)) + { + $oPage->SetContentType($oDocument->GetMimeType()); + $oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName()); + $oPage->add($oDocument->GetData()); } } catch(Exception $e) From 9976999a88f13dbda64b7ac699d551bf67c4fc40 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 22 Sep 2011 10:08:36 +0000 Subject: [PATCH 11/23] Portal: updated dictionary for new buttton "reopen request" SVN:trunk[1592] --- dictionaries/de.dictionary.itop.ui.php | 1 + dictionaries/dictionary.itop.ui.php | 1 + dictionaries/fr.dictionary.itop.ui.php | 1 + dictionaries/hu.dictionary.itop.ui.php | 1 + dictionaries/it.dictionary.itop.ui.php | 1 + dictionaries/ja.dictionary.itop.ui.php | 1 + dictionaries/pt_br.dictionary.itop.ui.php | 1 + dictionaries/ru.dictionary.itop.ui.php | 1 + dictionaries/tr.dictionary.itop.ui.php | 1 + 9 files changed, 9 insertions(+) diff --git a/dictionaries/de.dictionary.itop.ui.php b/dictionaries/de.dictionary.itop.ui.php index 7d8d3ed5ca..59c8310fba 100644 --- a/dictionaries/de.dictionary.itop.ui.php +++ b/dictionaries/de.dictionary.itop.ui.php @@ -906,6 +906,7 @@ Wenn Aktionen mit Trigger verknüpft sind, bekommt jede Aktion eine Auftragsnumm 'Portal:TitleRequestDetailsFor_Request' => 'Details für Request %1$s:', 'Portal:NoOpenRequest' => 'Keinen Request in dieser Kategorie', 'Portal:NoClosedRequest' => 'Keinen Request in dieser Kategorie', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Dieses Ticket schließen', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Geben Sie einen Kommentar zur Lösung dieses Tickets ein:', diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php index 10a581b9f3..ccafe58b14 100644 --- a/dictionaries/dictionary.itop.ui.php +++ b/dictionaries/dictionary.itop.ui.php @@ -883,6 +883,7 @@ When associated with a trigger, each action is given an "order" number, specifyi 'Portal:TitleRequestDetailsFor_Request' => 'Details for request %1$s:', 'Portal:NoOpenRequest' => 'No request in this category', 'Portal:NoClosedRequest' => 'No request in this category', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Close this ticket', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Enter your comments about the resolution of this ticket:', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 9cb77328ab..be58cf583b 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -733,6 +733,7 @@ Lors de l\'association à un déclencheur, on attribue à chaque action un numé 'Portal:TitleRequestDetailsFor_Request' => 'Détails de votre requête %1$s:', 'Portal:NoOpenRequest' => 'Aucune requête.', 'Portal:NoClosedRequest' => 'Aucune requête.', + 'Portal:Button:ReopenTicket' => 'Réouvrir cette requête', 'Portal:Button:CloseTicket' => 'Clôre cette requête', 'Portal:Button:UpdateRequest' => 'Mettre à jour la requête', 'Portal:EnterYourCommentsOnTicket' => 'Vos commentaires à propos du traitement de cette requête:', diff --git a/dictionaries/hu.dictionary.itop.ui.php b/dictionaries/hu.dictionary.itop.ui.php index 2c0681a7dc..a02abe27fa 100755 --- a/dictionaries/hu.dictionary.itop.ui.php +++ b/dictionaries/hu.dictionary.itop.ui.php @@ -732,6 +732,7 @@ Akció kiváltó okhoz rendelésekor kap egy sorszámot , amely meghatározza az 'Portal:TitleRequestDetailsFor_Request' => '%1$s kérés részletei:', 'Portal:NoOpenRequest' => 'A kategóriához nem tartozik nyitott kérés.', 'Portal:NoClosedRequest' => 'No request in this category', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Hibajegy lezárása', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Adjon megjegyzést a megoldáshoz:', diff --git a/dictionaries/it.dictionary.itop.ui.php b/dictionaries/it.dictionary.itop.ui.php index f1d2efbd52..f19a803115 100644 --- a/dictionaries/it.dictionary.itop.ui.php +++ b/dictionaries/it.dictionary.itop.ui.php @@ -737,6 +737,7 @@ Quando è associata a un trigger, ad ogni azione è assegnato un numero "ordine" 'Portal:TitleRequestDetailsFor_Request' => 'Dettagli per la richiesta %1$s:', 'Portal:NoOpenRequest' => 'Nessuna richiesta in questa categoria.', 'Portal:NoClosedRequest' => 'Nessuna richiesta in questa categoria.', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Chiudi questo ticket', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Inserisci il tuo commento sulla risoluzione di questo ticket:', diff --git a/dictionaries/ja.dictionary.itop.ui.php b/dictionaries/ja.dictionary.itop.ui.php index c3ab05e5be..31705c1332 100644 --- a/dictionaries/ja.dictionary.itop.ui.php +++ b/dictionaries/ja.dictionary.itop.ui.php @@ -897,6 +897,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', array( 'Portal:TitleRequestDetailsFor_Request' => 'リクエスト%1$sの詳細:', // Details for request %1$s:', 'Portal:NoOpenRequest' => '本カテゴリにリクエストはありません', // 'No request in this category.', 'Portal:NoClosedRequest' => 'No request in this category', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => '本チケットを閉じます。', // 'Close this ticket', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => '本チケットの解決について、コメントを入力してください。', // 'Enter your comments about the resolution of this ticket:', diff --git a/dictionaries/pt_br.dictionary.itop.ui.php b/dictionaries/pt_br.dictionary.itop.ui.php index b8d29de34a..11ed05d713 100644 --- a/dictionaries/pt_br.dictionary.itop.ui.php +++ b/dictionaries/pt_br.dictionary.itop.ui.php @@ -735,6 +735,7 @@ When associated with a trigger, each action is given an "order" number, specifyi 'Portal:TitleRequestDetailsFor_Request' => 'Detalhes para requisição %1$s:', 'Portal:NoOpenRequest' => 'Nenhuma requisição neste categoria.', 'Portal:NoClosedRequest' => 'Nenhuma requisição neste categoria.', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Fechar este ticket', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Digite os seus comentários sobre a resolução deste incidente:', diff --git a/dictionaries/ru.dictionary.itop.ui.php b/dictionaries/ru.dictionary.itop.ui.php index 8258eefae5..5408721288 100644 --- a/dictionaries/ru.dictionary.itop.ui.php +++ b/dictionaries/ru.dictionary.itop.ui.php @@ -865,6 +865,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array( 'Portal:TitleRequestDetailsFor_Request' => 'Подробности запроса %1$s:', 'Portal:NoOpenRequest' => 'Нет запросов в этой категории.', 'Portal:NoClosedRequest' => 'No request in this category', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Закрыть этот "тикет"', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'Введите ваши каментарии по решению этого "тикета":', diff --git a/dictionaries/tr.dictionary.itop.ui.php b/dictionaries/tr.dictionary.itop.ui.php index d6cd4788a6..ebc686fdfa 100644 --- a/dictionaries/tr.dictionary.itop.ui.php +++ b/dictionaries/tr.dictionary.itop.ui.php @@ -864,6 +864,7 @@ Tetikleme gerçekleştiriğinde işlemler tanımlanan sıra numarası ile gerçe 'Portal:TitleRequestDetailsFor_Request' => 'İsteğin detayı %1$s:', 'Portal:NoOpenRequest' => 'Bu kategoride istek yok.', 'Portal:NoClosedRequest' => 'Bu kategoride istek yok.', + 'Portal:Button:ReopenTicket' => 'Reopen this ticket', 'Portal:Button:CloseTicket' => 'Çağrıyı kapat', 'Portal:Button:UpdateRequest' => 'Update the request', 'Portal:EnterYourCommentsOnTicket' => 'İsteğin çözümüne yönelik açıklamalar:', From 428f1a26cc2ddf7bfe7a5bb3a20b6903b4853a1c Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 22 Sep 2011 11:08:34 +0000 Subject: [PATCH 12/23] Typo ! Impact: Unknown ? SVN:trunk[1593] --- pages/ajax.render.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/ajax.render.php b/pages/ajax.render.php index 974961a8cf..d7f90dd6c7 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -378,7 +378,7 @@ try $sTargetState = utils::ReadParam('target_state', ''); $iTransactionId = utils::ReadParam('transaction_id', ''); $oObj->Set(MetaModel::GetStateAttributeCode($sClass), $sTargetState); - cmdbAbstractObject::DisplayCreationForm($oPage, $sClass, $oObj, array(), array('action' => utils::GetAbsoluteUrlAppRoot().'pages/UI.php', 'transcation_id' => $iTransactionId)); + cmdbAbstractObject::DisplayCreationForm($oPage, $sClass, $oObj, array(), array('action' => utils::GetAbsoluteUrlAppRoot().'pages/UI.php', 'transaction_id' => $iTransactionId)); break; // DisplayBlock From e5ce12ed0ad260c866e2fe456e5ea59168a0909a Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 22 Sep 2011 11:15:40 +0000 Subject: [PATCH 13/23] Make the template system work for real ! SVN:trunk[1594] --- application/ajaxwebpage.class.inc.php | 43 +++++++++++++++++++++++++++ application/itopwebpage.class.inc.php | 5 ++++ application/template.class.inc.php | 20 +++++++++---- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/application/ajaxwebpage.class.inc.php b/application/ajaxwebpage.class.inc.php index 1ccb602dda..ac732ae866 100644 --- a/application/ajaxwebpage.class.inc.php +++ b/application/ajaxwebpage.class.inc.php @@ -88,6 +88,11 @@ class ajax_page extends WebPage return $sPreviousTab; } + public function GetCurrentTab() + { + return $this->m_sCurrentTab; + } + /** * Echoes the content of the whole page * @return void @@ -230,6 +235,44 @@ EOF } } + /** + * Records the current state of the 'html' part of the page output + * @return mixed The current state of the 'html' output + */ + public function start_capture() + { + if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab)) + { + $iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]): 0; + return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset); + } + else + { + return parent::start_capture(); + } + } + + /** + * Returns the part of the html output that occurred since the call to start_capture + * and removes this part from the current html output + * @param $offset mixed The value returned by start_capture + * @return string The part of the html output that was added since the call to start_capture + */ + public function end_capture($offset) + { + if (is_array($offset)) + { + if ($this->m_sCurrentTab != $offset['tab']) echo "

    le TAB a changé !!! currentTab: ".$this->m_sCurrentTab."

    "; + $sCaptured = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], $offset['offset']); + $this->m_aTabs[$offset['tc']]['content'][$offset['tab']] = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], 0, $offset['offset']); + } + else + { + $sCaptured = parent::end_capture($offset); + } + return $sCaptured; + } + /** * Add any text or HTML fragment (identified by an ID) at the end of the body of the page * This is useful to add hidden content, DIVs or FORMs that should not diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index b625152495..29987825d5 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -834,6 +834,11 @@ EOF return $sPreviousTab; } + public function GetCurrentTab() + { + return $this->m_sCurrentTab; + } + /** * Make the given tab the active one, as if it were clicked * DOES NOT WORK: apparently in the *old* version of jquery diff --git a/application/template.class.inc.php b/application/template.class.inc.php index b4a32af352..00c9ec51dc 100644 --- a/application/template.class.inc.php +++ b/application/template.class.inc.php @@ -35,7 +35,15 @@ class DisplayTemplate public function __construct($sTemplate) { - $this->m_aTags = array('itopblock', 'itopcheck', 'itoptabs', 'itoptab', 'itoptoggle', 'itopstring', 'sqlblock'); + $this->m_aTags = array ( + 'itopblock', + 'itopcheck', + 'itoptabs', + 'itoptab', + 'itoptoggle', + 'itopstring', + 'sqlblock' + ); $this->m_sTemplate = $sTemplate; } @@ -208,7 +216,6 @@ class DisplayTemplate $oBlock->RenderContent($oPage); break; - case 'itopblock': // No longer used, handled by DisplayBlock::FromTemplate see above $oPage->add(""); break; @@ -272,6 +279,7 @@ class ObjectDetailsTemplate extends DisplayTemplate public function Render(WebPage $oPage, $aParams = array(), $bEditMode = false) { + $sStateAttCode = MetaModel :: GetStateAttributeCode(get_class($this->m_oObj)); $aTemplateFields = array(); preg_match_all('/\\$this->([a-z0-9_]+)\\$/', $this->m_sTemplate, $aMatches); $aTemplateFields = $aMatches[1]; @@ -302,6 +310,11 @@ class ObjectDetailsTemplate extends DisplayTemplate $iFlags = $iFlags & ~OPT_ATT_READONLY; // Mandatory fields cannot be read-only when creating an object } + if ((!$oAttDef->IsWritable()) || ($sStateAttCode == $sAttCode)) + { + $iFlags = $iFlags | OPT_ATT_READONLY; + } + if ($iFlags & OPT_ATT_HIDDEN) { $aParams['this->label('.$sAttCode.')'] = ''; @@ -313,7 +326,6 @@ class ObjectDetailsTemplate extends DisplayTemplate { if ($bEditMode && ($iFlags & (OPT_ATT_READONLY|OPT_ATT_SLAVE))) { - // Check if the attribute is not read-only because of a synchro... $aReasons = array(); $sSynchroIcon = ''; @@ -336,7 +348,6 @@ class ObjectDetailsTemplate extends DisplayTemplate $aParams['this->comments('.$sAttCode.')'] = $sSynchroIcon; } - if ($bEditMode && !($iFlags & OPT_ATT_READONLY)) //TODO: check the data synchro status... { $aParams['this->field('.$sAttCode.')'] = "".$this->m_oObj->GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef, @@ -388,5 +399,4 @@ class ObjectDetailsTemplate extends DisplayTemplate } //DisplayTemplate::UnitTest(); - ?> From f82a4ada23f9a53f3b172a9b8ac9823fce8743f3 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Thu, 22 Sep 2011 11:40:30 +0000 Subject: [PATCH 14/23] #478 Fixed issue in the audit: the results are wrong whenever an organization is selected SVN:trunk[1595] --- pages/audit.php | 214 ++++++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 108 deletions(-) diff --git a/pages/audit.php b/pages/audit.php index 5ea50f5d6d..63cf0a4367 100644 --- a/pages/audit.php +++ b/pages/audit.php @@ -22,6 +22,112 @@ * @author Denis Flaven * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL */ +/** + * Adds the context parameters to the audit query + */ +function FilterByContext(DBObjectSearch &$oFilter, ApplicationContext $oAppContext) +{ + $sObjClass = $oFilter->GetClass(); + $aContextParams = $oAppContext->GetNames(); + $aCallSpec = array($sObjClass, 'MapContextParam'); + if (is_callable($aCallSpec)) + { + foreach($aContextParams as $sParamName) + { + $sValue = $oAppContext->GetCurrentValue($sParamName, null); + if ($sValue != null) + { + $sAttCode = call_user_func($aCallSpec, $sParamName); // Returns null when there is no mapping for this parameter + if ( ($sAttCode != null) && MetaModel::IsValidAttCode($sObjClass, $sAttCode)) + { + // Check if the condition points to a hierarchical key + if ($sAttCode == 'id') + { + // Filtering on the objects themselves + $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sObjClass); + + if ($sHierarchicalKeyCode !== false) + { + $oRootFilter = new DBObjectSearch($sObjClass); + $oRootFilter->AddCondition($sAttCode, $sValue); + $oFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default + $bConditionAdded = true; + } + } + else + { + $oAttDef = MetaModel::GetAttributeDef($sObjClass, $sAttCode); + $bConditionAdded = false; + if ($oAttDef->IsExternalKey()) + { + $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass()); + + if ($sHierarchicalKeyCode !== false) + { + $oRootFilter = new DBObjectSearch($oAttDef->GetTargetClass()); + $oRootFilter->AddCondition('id', $sValue); + $oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass()); + $oHKFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default + $oFilter->AddCondition_PointingTo($oHKFilter, $sAttCode); + $bConditionAdded = true; + } + } + } + if (!$bConditionAdded) + { + $oFilter->AddCondition($sAttCode, $sValue); + } + } + } + } + } +} + +function GetRuleResultSet($iRuleId, $oDefinitionFilter, $oAppContext) +{ + $oRule = MetaModel::GetObject('AuditRule', $iRuleId); + $sOql = $oRule->Get('query'); + $oRuleFilter = DBObjectSearch::FromOQL($sOql); + FilterByContext($oRuleFilter, $oAppContext); // Not needed since this filter is a subset of the definition filter, but may speedup things + + if ($oRule->Get('valid_flag') == 'false') + { + // The query returns directly the invalid elements + $oFilter = $oRuleFilter; + $oFilter->MergeWith($oDefinitionFilter); + $oErrorObjectSet = new CMDBObjectSet($oFilter); + } + else + { + // The query returns only the valid elements, all the others are invalid + $oFilter = $oRuleFilter; + $oErrorObjectSet = new CMDBObjectSet($oFilter); + $aValidIds = array(0); // Make sure that we have at least one value in the list + while($oObj = $oErrorObjectSet->Fetch()) + { + $aValidIds[] = $oObj->GetKey(); + } + $oFilter = clone $oDefinitionFilter; + $oFilter->AddCondition('id', $aValidIds, 'NOTIN'); + $oErrorObjectSet = new CMDBObjectSet($oFilter); + } + return $oErrorObjectSet; +} + +function GetReportColor($iTotal, $iErrors) +{ + $sResult = 'red'; + if ( ($iTotal == 0) || ($iErrors / $iTotal) <= 0.05 ) + { + $sResult = 'green'; + } + else if ( ($iErrors / $iTotal) <= 0.25 ) + { + $sResult = 'orange'; + } + return $sResult; +} + try { require_once('../approot.inc.php'); @@ -37,114 +143,6 @@ try $oP = new iTopWebPage(Dict::S('UI:Audit:Title')); - /** - * Adds the context parameters to the audit query - */ - function FilterByContext(DBObjectSearch &$oFilter, ApplicationContext $oAppContext) - { - $sObjClass = $oFilter->GetClass(); - $aContextParams = $oAppContext->GetNames(); - $aCallSpec = array($sObjClass, 'MapContextParam'); - if (is_callable($aCallSpec)) - { - foreach($aContextParams as $sParamName) - { - $sValue = $oAppContext->GetCurrentValue($sParamName, null); - if ($sValue != null) - { - $sAttCode = call_user_func($aCallSpec, $sParamName); // Returns null when there is no mapping for this parameter - if ( ($sAttCode != null) && MetaModel::IsValidAttCode($sObjClass, $sAttCode)) - { - $oFilter = new DBObjectSearch($sObjClass); - - // Check if the condition points to a hierarchical key - if ($sAttCode == 'id') - { - // Filtering on the objects themselves - $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($sObjClass); - - if ($sHierarchicalKeyCode !== false) - { - $oRootFilter = new DBObjectSearch($sObjClass); - $oRootFilter->AddCondition($sAttCode, $sValue); - $oFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default - $bConditionAdded = true; - } - } - else - { - $oAttDef = MetaModel::GetAttributeDef($sObjClass, $sAttCode); - $bConditionAdded = false; - if ($oAttDef->IsExternalKey()) - { - $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass()); - - if ($sHierarchicalKeyCode !== false) - { - $oRootFilter = new DBObjectSearch($oAttDef->GetTargetClass()); - $oRootFilter->AddCondition('id', $sValue); - $oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass()); - $oHKFilter->AddCondition_PointingTo($oRootFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW); // Use the 'below' operator by default - $oFilter->AddCondition_PointingTo($oHKFilter, $sAttCode); - $bConditionAdded = true; - } - } - } - if (!$bConditionAdded) - { - $oFilter->AddCondition($sAttCode, $sValue); - } - } - } - } - } - } - - function GetRuleResultSet($iRuleId, $oDefinitionFilter, $oAppContext) - { - $oRule = MetaModel::GetObject('AuditRule', $iRuleId); - $sOql = $oRule->Get('query'); - $oRuleFilter = DBObjectSearch::FromOQL($sOql); - FilterByContext($oRuleFilter, $oAppContext); // Not needed since this filter is a subset of the definition filter, but may speedup things - - if ($oRule->Get('valid_flag') == 'false') - { - // The query returns directly the invalid elements - $oFilter = $oRuleFilter; - $oFilter->MergeWith($oDefinitionFilter); - $oErrorObjectSet = new CMDBObjectSet($oFilter); - } - else - { - // The query returns only the valid elements, all the others are invalid - $oFilter = $oRuleFilter; - $oErrorObjectSet = new CMDBObjectSet($oFilter); - $aValidIds = array(0); // Make sure that we have at least one value in the list - while($oObj = $oErrorObjectSet->Fetch()) - { - $aValidIds[] = $oObj->GetKey(); - } - $oFilter = clone $oDefinitionFilter; - $oFilter->AddCondition('id', $aValidIds, 'NOTIN'); - $oErrorObjectSet = new CMDBObjectSet($oFilter); - } - return $oErrorObjectSet; - } - - function GetReportColor($iTotal, $iErrors) - { - $sResult = 'red'; - if ( ($iTotal == 0) || ($iErrors / $iTotal) <= 0.05 ) - { - $sResult = 'green'; - } - else if ( ($iErrors / $iTotal) <= 0.25 ) - { - $sResult = 'orange'; - } - return $sResult; - } - switch($operation) { case 'errors': From 8ae92cb50e29d0f0cc13eca27118b36421f8d810 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 22 Sep 2011 11:53:49 +0000 Subject: [PATCH 15/23] - Fix a problem with the upgrade (case sensitive table name & prefix) - Display a message when there is no attachment SVN:trunk[1596] --- .../itop-attachments/de.dict.attachments.php | 1 + .../itop-attachments/en.dict.attachments.php | 1 + .../itop-attachments/fr.dict.attachments.php | 1 + .../itop-attachments/model.attachments.php | 21 ++++++++++++------- .../itop-attachments/module.attachments.php | 7 ++++--- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/modules/itop-attachments/de.dict.attachments.php b/modules/itop-attachments/de.dict.attachments.php index cf5605641b..1a2636cfbd 100644 --- a/modules/itop-attachments/de.dict.attachments.php +++ b/modules/itop-attachments/de.dict.attachments.php @@ -36,5 +36,6 @@ Dict::Add('EN US', 'English', 'English', array( 'Attachment:Max_Go' => '(Maximale Datei-Größe: %1$s Go)', 'Attachment:Max_Mo' => '(Maximale Datei-Größe: %1$s Mo)', 'Attachment:Max_Ko' => '(Maximale Datei-Größe: %1$s Ko)', + 'Attachments:NoAttachment' => 'Kein Attachment.', )); ?> diff --git a/modules/itop-attachments/en.dict.attachments.php b/modules/itop-attachments/en.dict.attachments.php index 1c90556ea2..acc673bfd7 100644 --- a/modules/itop-attachments/en.dict.attachments.php +++ b/modules/itop-attachments/en.dict.attachments.php @@ -35,5 +35,6 @@ Dict::Add('EN US', 'English', 'English', array( 'Attachment:Max_Go' => '(Maximum file size: %1$s Go)', 'Attachment:Max_Mo' => '(Maximum file size: %1$s Mo)', 'Attachment:Max_Ko' => '(Maximum file size: %1$s Ko)', + 'Attachments:NoAttachment' => 'No attachment. ', )); ?> diff --git a/modules/itop-attachments/fr.dict.attachments.php b/modules/itop-attachments/fr.dict.attachments.php index 5f10a613ae..f92c7841ff 100644 --- a/modules/itop-attachments/fr.dict.attachments.php +++ b/modules/itop-attachments/fr.dict.attachments.php @@ -35,5 +35,6 @@ Dict::Add('FR FR', 'French', 'Français', array( 'Attachment:Max_Go' => '(Taille de fichier max.: %1$s Gb)', 'Attachment:Max_Mo' => '(Taille de fichier max.: %1$s Mb)', 'Attachment:Max_Ko' => '(Taille de fichier max.: %1$s Kb)', + 'Attachments:NoAttachment' => 'Aucune pièce jointe.', )); ?> \ No newline at end of file diff --git a/modules/itop-attachments/model.attachments.php b/modules/itop-attachments/model.attachments.php index 6d4446fb0f..001a35b704 100644 --- a/modules/itop-attachments/model.attachments.php +++ b/modules/itop-attachments/model.attachments.php @@ -474,14 +474,21 @@ EOF else { $oPage->add(''); - while ($oAttachment = $oSet->Fetch()) + if ($oSet->Count() == 0) { - $iAttId = $oAttachment->GetKey(); - $oDoc = $oAttachment->Get('contents'); - $sFileName = $oDoc->GetFileName(); - $sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName); - $sDownloadLink = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php/?operation=download_document&class=Attachment&id='.$iAttId.'&field=contents'; - $oPage->add(''); + $oPage->add(Dict::S('Attachments:NoAttachment')); + } + else + { + while ($oAttachment = $oSet->Fetch()) + { + $iAttId = $oAttachment->GetKey(); + $oDoc = $oAttachment->Get('contents'); + $sFileName = $oDoc->GetFileName(); + $sIcon = utils::GetAbsoluteUrlAppRoot().AttachmentPlugIn::GetFileIcon($sFileName); + $sDownloadLink = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php/?operation=download_document&class=Attachment&id='.$iAttId.'&field=contents'; + $oPage->add(''); + } } } } diff --git a/modules/itop-attachments/module.attachments.php b/modules/itop-attachments/module.attachments.php index 149fe7e126..ad66a618d9 100644 --- a/modules/itop-attachments/module.attachments.php +++ b/modules/itop-attachments/module.attachments.php @@ -99,11 +99,12 @@ class AttachmentInstaller extends ModuleInstallerAPI // // Prerequisite: change null into 0 (workaround to the fact that we cannot use IS NULL in OQL) SetupWebPage::log_info("Initializing attachment/item_org_id - null to zero"); - $sRepair = "UPDATE `Attachment` SET `item_org_id` = 0 WHERE `item_org_id` IS NULL"; + $sTableName = MetaModel::DBGetTable('Attachment'); + $sRepair = "UPDATE `$sTableName` SET `item_org_id` = 0 WHERE `item_org_id` IS NULL"; CMDBSource::Query($sRepair); - SetupWebPage::log_info("Initializing attachment/item_org_id - zero to the container"); - $oSearch = DBObjectSearch::FromOQL('SELECT Attachment WHERE item_org_id = 0'); + SetupWebPage::log_info("Initializing attachment/item_org_id - zero to the container"); + $oSearch = DBObjectSearch::FromOQL("SELECT `$sTableName` WHERE item_org_id = 0"); $oSet = new DBObjectSet($oSearch); $iUpdated = 0; while ($oAttachment = $oSet->Fetch()) From 5ec37fd26ac3f7d9a5c0cfc8fc929b867aa0ab79 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 22 Sep 2011 11:58:42 +0000 Subject: [PATCH 16/23] - Fix a problem with the upgrade (case sensitive table name & prefix) SVN:trunk[1598] --- modules/itop-attachments/module.attachments.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/itop-attachments/module.attachments.php b/modules/itop-attachments/module.attachments.php index ad66a618d9..2ae724e98a 100644 --- a/modules/itop-attachments/module.attachments.php +++ b/modules/itop-attachments/module.attachments.php @@ -104,7 +104,7 @@ class AttachmentInstaller extends ModuleInstallerAPI CMDBSource::Query($sRepair); SetupWebPage::log_info("Initializing attachment/item_org_id - zero to the container"); - $oSearch = DBObjectSearch::FromOQL("SELECT `$sTableName` WHERE item_org_id = 0"); + $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_org_id = 0"); $oSet = new DBObjectSet($oSearch); $iUpdated = 0; while ($oAttachment = $oSet->Fetch()) From 5080bd58d54a9268914570951bd82a3b86d66958 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 22 Sep 2011 16:35:33 +0000 Subject: [PATCH 17/23] Removed some Debug/Warning messages SVN:trunk[1600] --- application/ajaxwebpage.class.inc.php | 14 ++++++++++---- application/itopwebpage.class.inc.php | 11 +++++++++-- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/application/ajaxwebpage.class.inc.php b/application/ajaxwebpage.class.inc.php index ac732ae866..d2f8817d87 100644 --- a/application/ajaxwebpage.class.inc.php +++ b/application/ajaxwebpage.class.inc.php @@ -243,7 +243,7 @@ EOF { if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab)) { - $iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]): 0; + $iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer]['content'][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer]['content'][$this->m_sCurrentTab]): 0; return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset); } else @@ -262,9 +262,15 @@ EOF { if (is_array($offset)) { - if ($this->m_sCurrentTab != $offset['tab']) echo "

    le TAB a changé !!! currentTab: ".$this->m_sCurrentTab."

    "; - $sCaptured = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], $offset['offset']); - $this->m_aTabs[$offset['tc']]['content'][$offset['tab']] = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], 0, $offset['offset']); + if (isset($this->m_aTabs[$offset['tc']]['content'][$offset['tab']])) + { + $sCaptured = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], $offset['offset']); + $this->m_aTabs[$offset['tc']]['content'][$offset['tab']] = substr($this->m_aTabs[$offset['tc']]['content'][$offset['tab']], 0, $offset['offset']); + } + else + { + $sCaptured = ''; + } } else { diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index 29987825d5..ccb854ec97 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -937,8 +937,15 @@ EOF { if (is_array($offset)) { - $sCaptured = substr($this->m_aTabs[$offset['tc']][$offset['tab']], $offset['offset']); - $this->m_aTabs[$offset['tc']][$offset['tab']] = substr($this->m_aTabs[$offset['tc']][$offset['tab']], 0, $offset['offset']); + if (isset($this->m_aTabs[$offset['tc']][$offset['tab']])) + { + $sCaptured = substr($this->m_aTabs[$offset['tc']][$offset['tab']], $offset['offset']); + $this->m_aTabs[$offset['tc']][$offset['tab']] = substr($this->m_aTabs[$offset['tc']][$offset['tab']], 0, $offset['offset']); + } + else + { + $sCaptured = ''; + } } else { From ec226ce76dc590aa94671e53bda42af22ee4a36a Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 22 Sep 2011 16:37:47 +0000 Subject: [PATCH 18/23] Cosmetic fix: the "loading..." indicator was visible/spinning when reloading any other field of the form ! SVN:trunk[1601] --- modules/itop-attachments/model.attachments.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/itop-attachments/model.attachments.php b/modules/itop-attachments/model.attachments.php index 001a35b704..d89a689a72 100644 --- a/modules/itop-attachments/model.attachments.php +++ b/modules/itop-attachments/model.attachments.php @@ -394,7 +394,7 @@ EOF function ajaxFileUpload() { //starting setting some animation when the ajax starts and completes - $("#loading").ajaxStart(function(){ + $("#attachment_loading").ajaxStart(function(){ $(this).show(); }).ajaxComplete(function(){ $(this).hide(); @@ -462,9 +462,9 @@ EOF $oPage->add('
    '); $oPage->add('
    '); $sMaxUpload = $this->GetMaxUpload(); - $oPage->p(Dict::S('Attachments:AddAttachment').' '.$sMaxUpload); + $oPage->p(Dict::S('Attachments:AddAttachment').' '.$sMaxUpload); //$oPage->p(''); - $oPage->p(''); + $oPage->p(''); $oPage->add(''); if ($this->m_bDeleteEnabled) { From 099afb54517d11ab1ba2b53174d402597c4d4b11 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Fri, 23 Sep 2011 13:30:21 +0000 Subject: [PATCH 19/23] Fixed regression on attribute labels; introduced in [1581] SVN:trunk[1602] --- core/attributedef.class.inc.php | 99 ++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index edd9ac9680..97eca619aa 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -180,12 +180,20 @@ abstract class AttributeDefinition public function IsNullAllowed() {return true;} public function GetCode() {return $this->m_sCode;} - public function GetLabel($sDefault = '') + public function GetLabel($sDefault = null) { + // If no default value is specified, let's define the most relevant one for developping purposes + if (is_null($sDefault)) + { + $sDefault = $this->m_sCode; + } + $sLabel = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode, ''); if (strlen($sLabel) == 0) { - $sLabel = $this->m_sCode; + // Nothing found: go higher in the hierarchy (if possible) + // + $sLabel = $sDefault; $sParentClass = MetaModel::GetParentClass($this->m_sHostClass); if ($sParentClass) { @@ -195,11 +203,6 @@ abstract class AttributeDefinition $sLabel = $oAttDef->GetLabel($sDefault); } } - else - { - // Nothing defined in the class hierarchy: return the default value - $sLabel = $sDefault; - } } return $sLabel; } @@ -217,50 +220,56 @@ abstract class AttributeDefinition } } - public function GetDescription($sDefault = '') + public function GetDescription($sDefault = null) { - $sDescription = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'+', ''); - if (strlen($sDescription) == 0) + // If no default value is specified, let's define the most relevant one for developping purposes + if (is_null($sDefault)) { + $sDefault = ''; + } + $sLabel = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'+', ''); + if (strlen($sLabel) == 0) + { + // Nothing found: go higher in the hierarchy (if possible) + // + $sLabel = $sDefault; $sParentClass = MetaModel::GetParentClass($this->m_sHostClass); if ($sParentClass) { if (MetaModel::IsValidAttCode($sParentClass, $this->m_sCode)) { $oAttDef = MetaModel::GetAttributeDef($sParentClass, $this->m_sCode); - $sDescription = $oAttDef->GetDescription($sDefault); + $sLabel = $oAttDef->GetDescription($sDefault); } } - else - { - // Nothing defined in the class hierarchy: return the default value - $sDescription = $sDefault; - } } - return $sDescription; + return $sLabel; } - public function GetHelpOnEdition($sDefault = '') + public function GetHelpOnEdition($sDefault = null) { - $sHelp = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'?', ''); - if (strlen($sHelp) == 0) + // If no default value is specified, let's define the most relevant one for developping purposes + if (is_null($sDefault)) { + $sDefault = ''; + } + $sLabel = Dict::S('Class:'.$this->m_sHostClass.'/Attribute:'.$this->m_sCode.'?', ''); + if (strlen($sLabel) == 0) + { + // Nothing found: go higher in the hierarchy (if possible) + // + $sLabel = $sDefault; $sParentClass = MetaModel::GetParentClass($this->m_sHostClass); if ($sParentClass) { if (MetaModel::IsValidAttCode($sParentClass, $this->m_sCode)) { $oAttDef = MetaModel::GetAttributeDef($sParentClass, $this->m_sCode); - $sHelp = $oAttDef->GetHelpOnEdition($sDefault); + $sLabel = $oAttDef->GetHelpOnEdition($sDefault); } } - else - { - // Nothing defined in the class hierarchy: return the default value - $sHelp = $sDefault; - } } - return $sHelp; + return $sLabel; } public function GetHelpOnSmartSearch() @@ -2729,23 +2738,35 @@ class AttributeExternalField extends AttributeDefinition } } - public function GetLabel($sDefault = '') + public function GetLabel($sDefault = null) { - $oRemoteAtt = $this->GetExtAttDef(); - $sDefault = $oRemoteAtt->GetLabel(); - return parent::GetLabel($sDefault); + $sLabel = parent::GetLabel(''); + if (strlen($sLabel) == 0) + { + $oRemoteAtt = $this->GetExtAttDef(); + $sLabel = $oRemoteAtt->GetLabel($this->m_sCode); + } + return $sLabel; } - public function GetDescription($sDefault = '') + public function GetDescription($sDefault = null) { - $oRemoteAtt = $this->GetExtAttDef(); - $sDefault = $oRemoteAtt->GetDescription(); - return parent::GetDescription($sDefault); + $sLabel = parent::GetDescription(''); + if (strlen($sLabel) == 0) + { + $oRemoteAtt = $this->GetExtAttDef(); + $sLabel = $oRemoteAtt->GetDescription(''); + } + return $sLabel; } - public function GetHelpOnEdition($sDefault = '') + public function GetHelpOnEdition($sDefault = null) { - $oRemoteAtt = $this->GetExtAttDef(); - $sDefault = $oRemoteAtt->GetHelpOnEdition(); - return parent::GetHelpOnEdition($sDefault); + $sLabel = parent::GetHelpOnEdition(''); + if (strlen($sLabel) == 0) + { + $oRemoteAtt = $this->GetExtAttDef(); + $sLabel = $oRemoteAtt->GetHelpOnEdition(''); + } + return $sLabel; } public function IsExternalKey($iType = EXTKEY_RELATIVE) From b454b24e0feb0112d1782acb0a12834faee0ccc6 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Fri, 23 Sep 2011 14:14:58 +0000 Subject: [PATCH 20/23] Rename the cron.params file to avoid overwriting the current config when updating. SVN:trunk[1605] --- webservices/{cron.params => cron.distrib} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename webservices/{cron.params => cron.distrib} (100%) diff --git a/webservices/cron.params b/webservices/cron.distrib similarity index 100% rename from webservices/cron.params rename to webservices/cron.distrib From 5b3350f6d5f47095130448196a627430ccfeeb08 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Wed, 28 Sep 2011 10:07:27 +0000 Subject: [PATCH 21/23] Fixed Trac #482: link to OpenSearch Xml page was broken SVN:trunk[1606] --- application/itopwebpage.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/itopwebpage.class.inc.php b/application/itopwebpage.class.inc.php index ccb854ec97..714e0684d4 100644 --- a/application/itopwebpage.class.inc.php +++ b/application/itopwebpage.class.inc.php @@ -623,7 +623,7 @@ EOF } echo "\n"; } - echo "\n"; + echo "\n"; echo "\n"; echo "\n"; From e8c8e4a0d704ace952d6412c78487000c5752463 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 28 Sep 2011 10:17:53 +0000 Subject: [PATCH 22/23] #481 Special characters not transcribed correctly in Portal (regression in 1.2) SVN:trunk[1607] --- portal/index.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/portal/index.php b/portal/index.php index 53ee9d774f..15e2cec3c4 100644 --- a/portal/index.php +++ b/portal/index.php @@ -108,7 +108,7 @@ function SelectServiceCategory($oP, $oUserOrg) { $sChecked = "checked"; } - $oP->p("

"); + $oP->p("

"); $oP->p("

".$oService->GetAsHTML('description')."

\n"); @@ -144,7 +144,7 @@ function SelectServiceSubCategory($oP, $oUserOrg) if (is_object($oServiceCategory)) { $oP->add("
\n"); - $oP->add("

".Dict::Format('Portal:SelectSubcategoryFrom_Service', htmlentities($oServiceCategory->GetName(), ENT_QUOTES, 'UTF-8'))."

\n"); + $oP->add("

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

\n"); $oP->WizardFormStart('request_wizard', $iDefaultWizNext); $oP->add("\n"); while($oSubService = $oSet->Fetch()) @@ -163,7 +163,7 @@ function SelectServiceSubCategory($oP, $oUserOrg) $oP->add(""); $oP->add(""); $oP->add(""); @@ -221,9 +221,9 @@ EOF $oRequest->Set('servicesubcategory_id', $aParameters['servicesubcategory_id']); $oAttDef = MetaModel::GetAttributeDef('UserRequest', 'service_id'); - $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => htmlentities($oServiceCategory->GetName(), ENT_QUOTES, 'UTF-8')); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $oServiceCategory->GetName()); $oAttDef = MetaModel::GetAttributeDef('UserRequest', 'servicesubcategory_id'); - $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => htmlentities($oServiceSubCategory->GetName(), ENT_QUOTES, 'UTF-8')); + $aDetails[] = array('label' => $oAttDef->GetLabel(), 'value' => $oServiceSubCategory->GetName()); $iFlags = 0; foreach($aList as $sAttCode) From a3a94cccbb6c5a05875dae0696383b47e99dcf49 Mon Sep 17 00:00:00 2001 From: Romain Quetiez Date: Wed, 28 Sep 2011 12:55:15 +0000 Subject: [PATCH 23/23] #484 Fixed issue with IIS ("Wrong password" at first prompt) SVN:trunk[1609] --- application/loginwebpage.class.inc.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index 679a00f08c..514fafb4a2 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -346,12 +346,10 @@ EOF case 'external': // Web server supplied authentication $bExternalAuth = false; - $sExtAuthVar = MetaModel::GetConfig()->GetExternalAuthenticationVariable(); // In which variable is the info passed ? - $sEval = '$bExternalAuth = isset('.$sExtAuthVar.');'; - eval($sEval); - if ($bExternalAuth) - { - eval('$sAuthUser = '.$sExtAuthVar.';'); // Retrieve the value + $sExtAuthVar = MetaModel::GetConfig()->GetExternalAuthenticationVariable(); // In which variable is the info passed ? + eval('$sAuthUser = isset('.$sExtAuthVar.') ? '.$sExtAuthVar.' : false;'); // Retrieve the value + if ($sAuthUser && (strlen($sAuthUser) > 0)) + { $sAuthPwd = ''; // No password in this case the web server already authentified the user... $sLoginMode = 'external'; $sAuthentication = 'external';
"); - $oP->add("

"); + $oP->add("

"); $oP->add("

".$oSubService->GetAsHTML('description')."

"); $oP->add("