function DoShowGrantSumary($oPage)
 {
     if ($this->GetRawName() == "Administrator") {
         // Looks dirty, but ok that's THE ONE
         $oPage->p(Dict::S('UI:UserManagement:AdminProfile+'));
         return;
     }
     // Note: for sure, we assume that the instance is derived from UserRightsProjection
     $oUserRights = UserRights::GetModuleInstance();
     $aDisplayData = array();
     foreach (MetaModel::GetClasses('bizmodel') as $sClass) {
         // Skip non instantiable classes
         if (MetaModel::IsAbstract($sClass)) {
             continue;
         }
         $aStimuli = array();
         foreach (MetaModel::EnumStimuli($sClass) as $sStimulusCode => $oStimulus) {
             $oGrant = $oUserRights->GetClassStimulusGrant($this->GetKey(), $sClass, $sStimulusCode);
             if (is_object($oGrant) && $oGrant->Get('permission') == 'yes') {
                 $aStimuli[] = '<span title="' . $sStimulusCode . ': ' . htmlentities($oStimulus->GetDescription(), ENT_QUOTES, 'UTF-8') . '">' . htmlentities($oStimulus->GetLabel(), ENT_QUOTES, 'UTF-8') . '</span>';
             }
         }
         $sStimuli = implode(', ', $aStimuli);
         $aDisplayData[] = array('class' => MetaModel::GetName($sClass), 'read' => $this->GetGrantAsHtml($oUserRights, $sClass, 'Read'), 'bulkread' => $this->GetGrantAsHtml($oUserRights, $sClass, 'Bulk Read'), 'write' => $this->GetGrantAsHtml($oUserRights, $sClass, 'Modify'), 'bulkwrite' => $this->GetGrantAsHtml($oUserRights, $sClass, 'Bulk Modify'), 'delete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'Delete'), 'bulkdelete' => $this->GetGrantAsHtml($oUserRights, $sClass, 'Bulk Delete'), 'stimuli' => $sStimuli);
     }
     $aDisplayConfig = array();
     $aDisplayConfig['class'] = array('label' => Dict::S('UI:UserManagement:Class'), 'description' => Dict::S('UI:UserManagement:Class+'));
     $aDisplayConfig['read'] = array('label' => Dict::S('UI:UserManagement:Action:Read'), 'description' => Dict::S('UI:UserManagement:Action:Read+'));
     $aDisplayConfig['bulkread'] = array('label' => Dict::S('UI:UserManagement:Action:BulkRead'), 'description' => Dict::S('UI:UserManagement:Action:BulkRead+'));
     $aDisplayConfig['write'] = array('label' => Dict::S('UI:UserManagement:Action:Modify'), 'description' => Dict::S('UI:UserManagement:Action:Modify+'));
     $aDisplayConfig['bulkwrite'] = array('label' => Dict::S('UI:UserManagement:Action:BulkModify'), 'description' => Dict::S('UI:UserManagement:Action:BulkModify+'));
     $aDisplayConfig['delete'] = array('label' => Dict::S('UI:UserManagement:Action:Delete'), 'description' => Dict::S('UI:UserManagement:Action:Delete+'));
     $aDisplayConfig['bulkdelete'] = array('label' => Dict::S('UI:UserManagement:Action:BulkDelete'), 'description' => Dict::S('UI:UserManagement:Action:BulkDelete+'));
     $aDisplayConfig['stimuli'] = array('label' => Dict::S('UI:UserManagement:Action:Stimuli'), 'description' => Dict::S('UI:UserManagement:Action:Stimuli+'));
     $oPage->table($aDisplayConfig, $aDisplayData);
 }
Пример #2
0
 /**
  * Helper function to build a select from the list of valid classes for a given action
  * @param string $sName The name of the select in the HTML form
  * @param string $sDefaulfValue The defaut value (i.e the value selected by default)
  * @param integer $iWidthPx The width (in pixels) of the drop-down list
  * @param integer $iActionCode The ActionCode (from UserRights) to check for authorization for the classes
  * @return string The HTML fragment corresponding to the select tag
  */
 function GetClassesSelect($sName, $sDefaultValue, $iWidthPx, $iActionCode = null)
 {
     $sHtml = "<select id=\"select_{$sName}\" name=\"{$sName}\">";
     $sHtml .= "<option tyle=\"width: " . $iWidthPx . "px;\" title=\"Select the class you want to load\" value=\"\">" . Dict::S('UI:CSVImport:ClassesSelectOne') . "</option>\n";
     $aValidClasses = array();
     $aClassCategories = array('bizmodel');
     if (UserRights::IsAdministrator()) {
         $aClassCategories = array('bizmodel', 'application', 'addon/authentication');
     }
     foreach ($aClassCategories as $sClassCategory) {
         foreach (MetaModel::GetClasses($sClassCategory) as $sClassName) {
             if ((is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode)) && !MetaModel::IsAbstract($sClassName)) {
                 $sSelected = $sClassName == $sDefaultValue ? " selected" : "";
                 $sDescription = MetaModel::GetClassDescription($sClassName);
                 $sDisplayName = MetaModel::GetName($sClassName);
                 $aValidClasses[$sDisplayName] = "<option style=\"width: " . $iWidthPx . "px;\" title=\"{$sDescription}\" value=\"{$sClassName}\"{$sSelected}>{$sDisplayName}</option>";
             }
         }
     }
     ksort($aValidClasses);
     $sHtml .= implode("\n", $aValidClasses);
     $sHtml .= "</select>";
     return $sHtml;
 }
Пример #3
0
 /**
  * Overload the check of the "enable" state of this menu to take into account
  * derived classes of objects
  */
 public function IsEnabled()
 {
     // Enable this menu, only if the current user has enough rights to create such an object, or an object of
     // any child class
     $aSubClasses = MetaModel::EnumChildClasses($this->sClass, ENUM_CHILD_CLASSES_ALL);
     // Including the specified class itself
     $bActionIsAllowed = false;
     foreach ($aSubClasses as $sCandidateClass) {
         if (!MetaModel::IsAbstract($sCandidateClass) && UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES) {
             $bActionIsAllowed = true;
             break;
             // Enough for now
         }
     }
     return $bActionIsAllowed;
 }
Пример #4
0
 if (substr($sClassSpec, 0, 7) == 'SELECT ') {
     $oFilter = DBObjectSearch::FromOQL($sClassSpec);
     $sClassName = $oFilter->GetClass();
     $sNeedleFormat = isset($aAccelerators[$sClassName]['needle']) ? $aAccelerators[$sClassName]['needle'] : '%$needle$%';
     $sNeedle = str_replace('$needle$', $sFullText, $sNeedleFormat);
     $aParams = array('needle' => $sNeedle);
 } else {
     $sClassName = $sClassSpec;
     $oFilter = new DBObjectSearch($sClassName);
     $aParams = array();
     foreach ($aFullTextNeedles as $sSearchText) {
         $oFilter->AddCondition_FullText($sSearchText);
     }
 }
 // Skip abstract classes
 if (MetaModel::IsAbstract($sClassName)) {
     continue;
 }
 if ($iTune > 0) {
     $fStartedClass = microtime(true);
 }
 $oSet = new DBObjectSet($oFilter, array(), $aParams);
 if (array_key_exists($sClassName, $aAccelerators) && array_key_exists('attributes', $aAccelerators[$sClassName])) {
     $oSet->OptimizeColumnLoad(array($oFilter->GetClassAlias() => $aAccelerators[$sClassName]['attributes']));
 }
 $sFullTextJS = addslashes($sFullText);
 $bEnableEnlarge = array_key_exists($sClassName, $aAccelerators) && array_key_exists('query', $aAccelerators[$sClassName]);
 if (array_key_exists($sClassName, $aAccelerators) && array_key_exists('enable_enlarge', $aAccelerators[$sClassName])) {
     $bEnableEnlarge &= $aAccelerators[$sClassName]['enable_enlarge'];
 }
 $sEnlargeTheSearch = <<<EOF
Пример #5
0
 /**
  * Renders the "Actions" popup menu for the given set of objects
  * 
  * Note that the menu links containing (or ending) with a hash (#) will have their fragment
  * part (whatever is after the hash) dynamically replaced (by javascript) when the menu is
  * displayed, to correspond to the current hash/fragment in the page. This allows modifying
  * an object in with the same tab active by default as the tab that was active when selecting
  * the "Modify..." action.
  */
 public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId)
 {
     if ($this->m_sStyle == 'popup') {
         $this->m_sStyle = 'list';
     }
     $sHtml = '';
     $oAppContext = new ApplicationContext();
     $sContext = $oAppContext->GetForLink();
     if (!empty($sContext)) {
         $sContext = '&' . $sContext;
     }
     $sClass = $this->m_oFilter->GetClass();
     $oReflectionClass = new ReflectionClass($sClass);
     $oSet = new CMDBObjectSet($this->m_oFilter);
     $sFilter = $this->m_oFilter->serialize();
     $sFilterDesc = $this->m_oFilter->ToOql(true);
     $aActions = array();
     $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
     $sRootUrl = utils::GetAbsoluteUrlAppRoot();
     // 1:n links, populate the target object as a default value when creating a new linked object
     if (isset($aExtraParams['target_attr'])) {
         $aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id'];
     }
     $sDefault = '';
     if (!empty($aExtraParams['default'])) {
         foreach ($aExtraParams['default'] as $sKey => $sValue) {
             $sDefault .= "&default[{$sKey}]={$sValue}";
         }
     }
     $bIsCreationAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) == UR_ALLOWED_YES && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
     switch ($oSet->Count()) {
         case 0:
             // No object in the set, the only possible action is "new"
             if ($bIsCreationAllowed) {
                 $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}");
             }
             break;
         case 1:
             $oObj = $oSet->Fetch();
             $id = $oObj->GetKey();
             $bLocked = false;
             if (MetaModel::GetConfig()->Get('concurrent_lock_enabled')) {
                 $aLockInfo = iTopOwnershipLock::IsLocked(get_class($oObj), $id);
                 if ($aLockInfo['locked']) {
                     $bLocked = true;
                     //$this->AddMenuSeparator($aActions);
                     //$aActions['concurrent_lock_unlock'] = array ('label' => Dict::S('UI:Menu:ReleaseConcurrentLock'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}");
                 }
             }
             $bRawModifiedAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
             $bIsModifyAllowed = !$bLocked && $bRawModifiedAllowed;
             $bIsDeleteAllowed = !$bLocked && UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
             // Just one object in the set, possible actions are "new / clone / modify and delete"
             if (!isset($aExtraParams['link_attr'])) {
                 if ($bIsModifyAllowed) {
                     $aActions['UI:Menu:Modify'] = array('label' => Dict::S('UI:Menu:Modify'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=modify&class={$sClass}&id={$id}{$sContext}#");
                 }
                 if ($bIsCreationAllowed) {
                     $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}");
                 }
                 if ($bIsDeleteAllowed) {
                     $aActions['UI:Menu:Delete'] = array('label' => Dict::S('UI:Menu:Delete'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=delete&class={$sClass}&id={$id}{$sContext}");
                 }
                 // Transitions / Stimuli
                 if (!$bLocked) {
                     $aTransitions = $oObj->EnumTransitions();
                     if (count($aTransitions)) {
                         $this->AddMenuSeparator($aActions);
                         $aStimuli = Metamodel::EnumStimuli(get_class($oObj));
                         foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
                             $iActionAllowed = get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction' ? UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet) : UR_ALLOWED_NO;
                             switch ($iActionAllowed) {
                                 case UR_ALLOWED_YES:
                                     $aActions[$sStimulusCode] = array('label' => $aStimuli[$sStimulusCode]->GetLabel(), 'url' => "{$sRootUrl}pages/UI.php?operation=stimulus&stimulus={$sStimulusCode}&class={$sClass}&id={$id}{$sContext}");
                                     break;
                                 default:
                                     // Do nothing
                             }
                         }
                     }
                 }
                 // Relations...
                 $aRelations = MetaModel::EnumRelationsEx($sClass);
                 if (count($aRelations)) {
                     $this->AddMenuSeparator($aActions);
                     foreach ($aRelations as $sRelationCode => $aRelationInfo) {
                         if (array_key_exists('down', $aRelationInfo)) {
                             $aActions[$sRelationCode . '_down'] = array('label' => $aRelationInfo['down'], 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=swf_navigator&relation={$sRelationCode}&direction=down&class={$sClass}&id={$id}{$sContext}");
                         }
                         if (array_key_exists('up', $aRelationInfo)) {
                             $aActions[$sRelationCode . '_up'] = array('label' => $aRelationInfo['up'], 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=swf_navigator&relation={$sRelationCode}&direction=up&class={$sClass}&id={$id}{$sContext}");
                         }
                     }
                 }
                 if ($bLocked && $bRawModifiedAllowed) {
                     // Add a special menu to kill the lock, but only to allowed users who can also modify this object
                     $aAllowedProfiles = MetaModel::GetConfig()->Get('concurrent_lock_override_profiles');
                     $bCanKill = false;
                     $oUser = UserRights::GetUserObject();
                     $aUserProfiles = array();
                     if (!is_null($oUser)) {
                         $oProfileSet = $oUser->Get('profile_list');
                         while ($oProfile = $oProfileSet->Fetch()) {
                             $aUserProfiles[$oProfile->Get('profile')] = true;
                         }
                     }
                     foreach ($aAllowedProfiles as $sProfile) {
                         if (array_key_exists($sProfile, $aUserProfiles)) {
                             $bCanKill = true;
                             break;
                         }
                     }
                     if ($bCanKill) {
                         $this->AddMenuSeparator($aActions);
                         $aActions['concurrent_lock_unlock'] = array('label' => Dict::S('UI:Menu:KillConcurrentLock'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=kill_lock&class={$sClass}&id={$id}{$sContext}");
                     }
                 }
                 /*
                 $this->AddMenuSeparator($aActions);
                 // Static menus: Email this page & CSV Export
                 $sUrl = ApplicationContext::MakeObjectUrl($sClass, $id);
                 $aActions['UI:Menu:EMail'] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=".urlencode($oObj->GetRawName())."&body=".urlencode($sUrl));
                 $aActions['UI:Menu:CSVExport'] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."&format=csv{$sContext}");
                 // The style tells us whether the menu is displayed on a list of one object, or on the details of the given object 
                 if ($this->m_sStyle == 'list')
                 {
                 	// Actions specific to the list
                 	$sOQL = addslashes($sFilterDesc);
                 	$aActions['UI:Menu:AddToDashboard'] = array ('label' => Dict::S('UI:Menu:AddToDashboard'), 'url' => "#", 'onclick' => "return DashletCreationDlg('$sOQL')");
                 }
                 */
             }
             $this->AddMenuSeparator($aActions);
             foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) {
                 $oSet->Rewind();
                 foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $sUrl) {
                     $aActions[$sLabel] = array('label' => $sLabel, 'url' => $sUrl);
                 }
             }
             break;
         default:
             // Check rights
             // New / Modify
             $bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
             $bIsBulkModifyAllowed = !MetaModel::IsAbstract($sClass) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet) && $oReflectionClass->IsSubclassOf('cmdbAbstractObject');
             $bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet);
             if (isset($aExtraParams['link_attr'])) {
                 $id = $aExtraParams['object_id'];
                 $sTargetAttr = $aExtraParams['target_attr'];
                 $oAttDef = MetaModel::GetAttributeDef($sClass, $sTargetAttr);
                 $sTargetClass = $oAttDef->GetTargetClass();
                 $bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet);
                 if ($bIsModifyAllowed) {
                     $aActions['UI:Menu:Add'] = array('label' => Dict::S('UI:Menu:Add'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=modify_links&class={$sClass}&link_attr=" . $aExtraParams['link_attr'] . "&target_class={$sTargetClass}&id={$id}&addObjects=true{$sContext}");
                 }
                 if ($bIsBulkModifyAllowed) {
                     $aActions['UI:Menu:Manage'] = array('label' => Dict::S('UI:Menu:Manage'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=modify_links&class={$sClass}&link_attr=" . $aExtraParams['link_attr'] . "&target_class={$sTargetClass}&id={$id}{$sContext}");
                 }
                 //if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All...', 'url' => "#"); }
             } else {
                 // many objects in the set, possible actions are: new / modify all / delete all
                 if ($bIsCreationAllowed) {
                     $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}");
                 }
                 if ($bIsBulkModifyAllowed) {
                     $aActions['UI:Menu:ModifyAll'] = array('label' => Dict::S('UI:Menu:ModifyAll'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=select_for_modify_all&class={$sClass}&filter=" . urlencode($sFilter) . "{$sContext}");
                 }
                 if ($bIsBulkDeleteAllowed) {
                     $aActions['UI:Menu:BulkDelete'] = array('label' => Dict::S('UI:Menu:BulkDelete'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=select_for_deletion&filter=" . urlencode($sFilter) . "{$sContext}");
                 }
                 // Stimuli
                 $aStates = MetaModel::EnumStates($sClass);
                 // Do not perform time consuming computations if there are too may objects in the list
                 $iLimit = MetaModel::GetConfig()->Get('complex_actions_limit');
                 if (count($aStates) > 0 && ($iLimit == 0 || $oSet->Count() < $iLimit)) {
                     // Life cycle actions may be available... if all objects are in the same state
                     //
                     // Group by <state>
                     $oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias());
                     $aGroupBy = array('__state__' => $oGroupByExp);
                     $aQueryParams = array();
                     if (isset($aExtraParams['query_params'])) {
                         $aQueryParams = $aExtraParams['query_params'];
                     }
                     $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy);
                     $aRes = CMDBSource::QueryToArray($sSql);
                     if (count($aRes) == 1) {
                         // All objects are in the same state...
                         $sState = $aRes[0]['__state__'];
                         $aTransitions = Metamodel::EnumTransitions($sClass, $sState);
                         if (count($aTransitions)) {
                             $this->AddMenuSeparator($aActions);
                             $aStimuli = Metamodel::EnumStimuli($sClass);
                             foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
                                 $oSet->Rewind();
                                 // As soon as the user rights implementation will browse the object set,
                                 // then we might consider using OptimizeColumnLoad() here
                                 $iActionAllowed = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet);
                                 $iActionAllowed = get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction' ? $iActionAllowed : UR_ALLOWED_NO;
                                 switch ($iActionAllowed) {
                                     case UR_ALLOWED_YES:
                                     case UR_ALLOWED_DEPENDS:
                                         $aActions[$sStimulusCode] = array('label' => $aStimuli[$sStimulusCode]->GetLabel(), 'url' => "{$sRootUrl}pages/UI.php?operation=select_bulk_stimulus&stimulus={$sStimulusCode}&state={$sState}&class={$sClass}&filter=" . urlencode($sFilter) . "{$sContext}");
                                         break;
                                     default:
                                         // Do nothing
                                 }
                             }
                         }
                     }
                 }
                 /*
                 $this->AddMenuSeparator($aActions);
                 $sUrl = utils::GetAbsoluteUrlAppRoot();
                 $aActions['UI:Menu:EMail'] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=$sFilterDesc&body=".urlencode("{$sUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."{$sContext}"));
                 $aActions['UI:Menu:CSVExport'] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."&format=csv{$sContext}");
                 $sOQL = addslashes($sFilterDesc);
                 $aActions['UI:Menu:AddToDashboard'] = array ('label' => Dict::S('UI:Menu:AddToDashboard'), 'url' => "#", 'onclick' => "return DashletCreationDlg('$sOQL')");
                 */
             }
     }
     $this->AddMenuSeparator($aActions);
     foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) {
         $oSet->Rewind();
         foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $data) {
             if (is_array($data)) {
                 // New plugins can provide javascript handlers via the 'onclick' property
                 //TODO: enable extension of different menus by checking the 'target' property ??
                 $aActions[$sLabel] = array('label' => $sLabel, 'url' => isset($data['url']) ? $data['url'] : '#', 'onclick' => isset($data['onclick']) ? $data['onclick'] : '');
             } else {
                 // Backward compatibility with old plugins
                 $aActions[$sLabel] = array('label' => $sLabel, 'url' => $data);
             }
         }
     }
     // New extensions based on iPopupMenuItem interface
     switch ($this->m_sStyle) {
         case 'list':
             $oSet->Rewind();
             $param = $oSet;
             $iMenuId = iPopupMenuExtension::MENU_OBJLIST_ACTIONS;
             break;
         case 'details':
             $oSet->Rewind();
             $param = $oSet->Fetch();
             $iMenuId = iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS;
             break;
     }
     utils::GetPopupMenuItems($oPage, $iMenuId, $param, $aActions);
     $aFavoriteActions = array();
     $aCallSpec = array($sClass, 'GetShortcutActions');
     if (is_callable($aCallSpec)) {
         $aShortcutActions = call_user_func($aCallSpec, $sClass);
         foreach ($aActions as $key => $aAction) {
             if (in_array($key, $aShortcutActions)) {
                 $aFavoriteActions[] = $aAction;
                 unset($aActions[$key]);
             }
         }
     } else {
         $aShortcutActions = array();
     }
     if (count($aFavoriteActions) > 0) {
         $sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>" . Dict::S('UI:Menu:OtherActions') . "\n<ul>\n";
     } else {
         $sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>" . Dict::S('UI:Menu:Actions') . "\n<ul>\n";
     }
     $sHtml .= $oPage->RenderPopupMenuItems($aActions, $aFavoriteActions);
     static $bPopupScript = false;
     if (!$bPopupScript) {
         // Output this once per page...
         $oPage->add_ready_script("\$(\"div.itop_popup>ul\").popupmenu();\n");
         $bPopupScript = true;
     }
     return $sHtml;
 }
Пример #6
0
    /**
     * Get the HTML fragment corresponding to the ext key editing widget
     * @param WebPage $oP The web page used for all the output
     * @param Hash $aArgs Extra context arguments
     * @return string The HTML fragment to be inserted into the page
     */
    public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true)
    {
        if (!is_null($bSearchMode)) {
            $this->bSearchMode = $bSearchMode;
        }
        $sTitle = addslashes($sTitle);
        $oPage->add_linked_script('../js/extkeywidget.js');
        $oPage->add_linked_script('../js/forms-json-utils.js');
        $bCreate = !$this->bSearchMode && !MetaModel::IsAbstract($this->sTargetClass) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation);
        $bExtensions = true;
        $sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm');
        $sAttrFieldPrefix = $this->bSearchMode ? '' : 'attr_';
        $sHTMLValue = "<span style=\"white-space:nowrap\">";
        // no wrap
        $sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL());
        if ($this->bSearchMode) {
            $sWizHelper = 'null';
            $sWizHelperJSON = "''";
            $sJSSearchMode = 'true';
        } else {
            if (isset($aArgs['wizHelper'])) {
                $sWizHelper = $aArgs['wizHelper'];
            } else {
                $sWizHelper = 'oWizardHelper' . $sFormPrefix;
            }
            $sWizHelperJSON = $sWizHelper . '.UpdateWizardToJSON()';
            $sJSSearchMode = 'false';
        }
        if (is_null($oAllowedValues)) {
            throw new Exception('Implementation: null value for allowed values definition');
        } elseif ($oAllowedValues->Count() < $iMaxComboLength) {
            // Discrete list of values, use a SELECT or RADIO buttons depending on the config
            switch ($sDisplayStyle) {
                case 'radio':
                case 'radio_horizontal':
                case 'radio_vertical':
                    $sValidationField = "<span id=\"v_{$this->iId}\"></span>";
                    $sHTMLValue = '';
                    $bVertical = $sDisplayStyle != 'radio_horizontal';
                    $bExtensions = false;
                    $oAllowedValues->Rewind();
                    $aAllowedValues = array();
                    while ($oObj = $oAllowedValues->Fetch()) {
                        $aAllowedValues[$oObj->GetKey()] = $oObj->GetName();
                    }
                    $sHTMLValue = $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", $bMandatory, $bVertical, $sValidationField);
                    $aEventsList[] = 'change';
                    break;
                case 'select':
                case 'list':
                default:
                    $sSelectMode = 'true';
                    $sHelpText = '';
                    //$this->oAttDef->GetHelpOnEdition();
                    if ($this->bSearchMode) {
                        if ($bSearchMultiple) {
                            $sHTMLValue = "<select class=\"multiselect\" multiple title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"{$this->iId}\">\n";
                        } else {
                            $sHTMLValue = "<select title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"{$this->iId}\">\n";
                            $sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any');
                            $sHTMLValue .= "<option value=\"\">{$sDisplayValue}</option>\n";
                        }
                    } else {
                        $sHTMLValue = "<select title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"{$this->iId}\">\n";
                        $sHTMLValue .= "<option value=\"\">" . Dict::S('UI:SelectOne') . "</option>\n";
                    }
                    $oAllowedValues->Rewind();
                    while ($oObj = $oAllowedValues->Fetch()) {
                        $key = $oObj->GetKey();
                        $display_value = $oObj->GetName();
                        if ($oAllowedValues->Count() == 1 && $bMandatory == 'true') {
                            // When there is only once choice, select it by default
                            $sSelected = ' selected';
                        } else {
                            $sSelected = is_array($value) && in_array($key, $value) || $value == $key ? ' selected' : '';
                        }
                        $sHTMLValue .= "<option value=\"{$key}\"{$sSelected}>{$display_value}</option>\n";
                    }
                    $sHTMLValue .= "</select>\n";
                    if ($this->bSearchMode && $bSearchMultiple) {
                        $aOptions = array('header' => true, 'checkAllText' => Dict::S('UI:SearchValue:CheckAll'), 'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'), 'noneSelectedText' => Dict::S('UI:SearchValue:Any'), 'selectedText' => Dict::S('UI:SearchValue:NbSelected'), 'selectedList' => 1);
                        $sJSOptions = json_encode($aOptions);
                        $oPage->add_ready_script("\$('.multiselect').multiselect({$sJSOptions});");
                    }
                    $oPage->add_ready_script(<<<EOF
\t\toACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '{$sFilter}', '{$sTitle}', true, {$sWizHelper}, '{$this->sAttCode}', {$sJSSearchMode});
\t\toACWidget_{$this->iId}.emptyHtml = "<div style=\\"background: #fff; border:0; text-align:center; vertical-align:middle;\\"><p>{$sMessage}</p></div>";
\t\t\$('#{$this->iId}').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
\t\t\$('#{$this->iId}').bind('change', function() { \$(this).trigger('extkeychange') } );

EOF
);
            }
            // Switch
        } else {
            // Too many choices, use an autocomplete
            $sSelectMode = 'false';
            // Check that the given value is allowed
            $oSearch = $oAllowedValues->GetFilter();
            $oSearch->AddCondition('id', $value);
            $oSet = new DBObjectSet($oSearch);
            if ($oSet->Count() == 0) {
                $value = null;
            }
            if (is_null($value) || $value == 0) {
                $sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : '';
            } else {
                $sDisplayValue = $this->GetObjectName($value);
            }
            $iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 3;
            //@@@ $this->oAttDef->GetMinAutoCompleteChars();
            $iFieldSize = isset($aArgs['iFieldSize']) ? $aArgs['iFieldSize'] : 30;
            //@@@ $this->oAttDef->GetMaxSize();
            // the input for the auto-complete
            $sHTMLValue = "<input count=\"" . $oAllowedValues->Count() . "\" type=\"text\" id=\"label_{$this->iId}\" size=\"{$iFieldSize}\" value=\"{$sDisplayValue}\"/>&nbsp;";
            $sHTMLValue .= "<img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_search.gif\" onClick=\"oACWidget_{$this->iId}.Search();\"/>&nbsp;";
            // another hidden input to store & pass the object's Id
            $sHTMLValue .= "<input type=\"hidden\" id=\"{$this->iId}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"" . htmlentities($value, ENT_QUOTES, 'UTF-8') . "\" />\n";
            $JSSearchMode = $this->bSearchMode ? 'true' : 'false';
            // Scripts to start the autocomplete and bind some events to it
            $oPage->add_ready_script(<<<EOF
\t\toACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '{$sFilter}', '{$sTitle}', false, {$sWizHelper}, '{$this->sAttCode}', {$sJSSearchMode});
\t\toACWidget_{$this->iId}.emptyHtml = "<div style=\\"background: #fff; border:0; text-align:center; vertical-align:middle;\\"><p>{$sMessage}</p></div>";
\t\t\$('#label_{$this->iId}').autocomplete(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { scroll:true, minChars:{$iMinChars}, autoFill:false, matchContains:true, mustMatch: true, keyHolder:'#{$this->iId}', extraParams:{operation:'ac_extkey', sTargetClass:'{$this->sTargetClass}',sFilter:'{$sFilter}',bSearchMode:{$JSSearchMode}, json: function() { return {$sWizHelperJSON}; } }});
\t\t\$('#label_{$this->iId}').keyup(function() { if (\$(this).val() == '') { \$('#{$this->iId}').val(''); } } ); // Useful for search forms: empty value in the "label", means no value, immediatly !
\t\t\$('#label_{$this->iId}').result( function(event, data, formatted) { OnAutoComplete('{$this->iId}', event, data, formatted); } );
\t\t\$('#{$this->iId}').bind('update', function() { oACWidget_{$this->iId}.Update(); } );
\t\tif (\$('#ac_dlg_{$this->iId}').length == 0)
\t\t{
\t\t\t\$('body').append('<div id="ac_dlg_{$this->iId}"></div>');
\t\t}
EOF
);
        }
        if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) {
            $sHTMLValue .= "<img id=\"mini_tree_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_tree.gif\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"/>&nbsp;";
            $oPage->add_ready_script(<<<EOF
\t\t\tif (\$('#ac_tree_{$this->iId}').length == 0)
\t\t\t{
\t\t\t\t\$('body').append('<div id="ac_tree_{$this->iId}"></div>');
\t\t\t}\t\t
EOF
);
        }
        if ($bCreate && $bExtensions) {
            $sHTMLValue .= "<img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/>&nbsp;";
            $oPage->add_ready_script(<<<EOF
\t\tif (\$('#ajax_{$this->iId}').length == 0)
\t\t{
\t\t\t\$('body').append('<div id="ajax_{$this->iId}"></div>');
\t\t}
EOF
);
        }
        if ($sDisplayStyle == 'select' || $sDisplayStyle == 'list') {
            $sHTMLValue .= "<span id=\"v_{$this->iId}\"></span>";
        }
        $sHTMLValue .= "</span>";
        // end of no wrap
        return $sHTMLValue;
    }
 /**
  * Helper to form a value, given JSON decoded data
  * The operation is the opposite to GetForJSON	 
  */
 public function FromJSONToValue($json)
 {
     $sTargetClass = $this->Get('linked_class');
     $aLinks = array();
     foreach ($json as $aValues) {
         if (isset($aValues['finalclass'])) {
             $sLinkClass = $aValues['finalclass'];
             if (!is_subclass_of($sLinkClass, $sTargetClass)) {
                 throw new CoreException('Wrong class for link attribute specification', array('requested_class' => $sLinkClass, 'expected_class' => $sTargetClass));
             }
         } elseif (MetaModel::IsAbstract($sTargetClass)) {
             throw new CoreException('Missing finalclass for link attribute specification');
         } else {
             $sLinkClass = $sTargetClass;
         }
         $oLink = MetaModel::NewObject($sLinkClass);
         foreach ($aValues as $sAttCode => $sValue) {
             $oLink->Set($sAttCode, $sValue);
         }
         // Check (roughly) if such a link is valid
         $aErrors = array();
         foreach (MetaModel::ListAttributeDefs($sTargetClass) as $sAttCode => $oAttDef) {
             if ($oAttDef->IsExternalKey()) {
                 if ($oAttDef->GetTargetClass() == $this->GetHostClass() || is_subclass_of($this->GetHostClass(), $oAttDef->GetTargetClass())) {
                     continue;
                     // Don't check the key to self
                 }
             }
             if ($oAttDef->IsWritable() && $oAttDef->IsNull($oLink->Get($sAttCode)) && !$oAttDef->IsNullAllowed()) {
                 $aErrors[] = $sAttCode;
             }
         }
         if (count($aErrors) > 0) {
             throw new CoreException("Missing value for mandatory attribute(s): " . implode(', ', $aErrors));
         }
         $aLinks[] = $oLink;
     }
     $oSet = DBObjectSet::FromArray($sTargetClass, $aLinks);
     return $oSet;
 }
 /**
  *	Get the friendly name for the class and its subclasses (if finalclass = 'subclass' ...)
  *	Simplifies the final expression by grouping classes having the same name expression	 
  *	Used when querying a parent class 	 
  */
 protected static function GetExtendedNameExpression($sClass)
 {
     // 1st step - get all of the required expressions (instantiable classes)
     //            and group them using their OQL representation
     //
     $aFNExpressions = array();
     // signature => array('expression' => oExp, 'classes' => array of classes)
     foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sSubClass) {
         if ($sSubClass != $sClass && MetaModel::IsAbstract($sSubClass)) {
             continue;
         }
         $oSubClassName = MetaModel::GetNameExpression($sSubClass);
         $sSignature = $oSubClassName->Render();
         if (!array_key_exists($sSignature, $aFNExpressions)) {
             $aFNExpressions[$sSignature] = array('expression' => $oSubClassName, 'classes' => array());
         }
         $aFNExpressions[$sSignature]['classes'][] = $sSubClass;
     }
     // 2nd step - build the final name expression depending on the finalclass
     //
     if (count($aFNExpressions) == 1) {
         $aExpData = reset($aFNExpressions);
         $oNameExpression = $aExpData['expression'];
     } else {
         $oNameExpression = null;
         foreach ($aFNExpressions as $sSignature => $aExpData) {
             $oClassListExpr = ListExpression::FromScalars($aExpData['classes']);
             $oClassExpr = new FieldExpression('finalclass', $sClass);
             $oClassInList = new BinaryExpression($oClassExpr, 'IN', $oClassListExpr);
             if (is_null($oNameExpression)) {
                 $oNameExpression = $aExpData['expression'];
             } else {
                 $oNameExpression = new FunctionExpression('IF', array($oClassInList, $aExpData['expression'], $oNameExpression));
             }
         }
     }
     return $oNameExpression;
 }
 public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US')
 {
     CMDBObject::SetTrackInfo('Initialization');
     $oChange = CMDBObject::GetCurrentChange();
     $iContactId = 0;
     // Support drastic data model changes: no organization class (or not writable)!
     if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization')) {
         $oOrg = new Organization();
         $oOrg->Set('name', 'My Company/Department');
         $oOrg->Set('code', 'SOMECODE');
         $iOrgId = $oOrg->DBInsertTrackedNoReload($oChange, true);
         // Support drastic data model changes: no Person class  (or not writable)!
         if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person')) {
             $oContact = new Person();
             $oContact->Set('name', 'My last name');
             $oContact->Set('first_name', 'My first name');
             if (MetaModel::IsValidAttCode('Person', 'org_id')) {
                 $oContact->Set('org_id', $iOrgId);
             }
             if (MetaModel::IsValidAttCode('Person', 'phone')) {
                 $oContact->Set('phone', '+00 000 000 000');
             }
             $oContact->Set('email', '*****@*****.**');
             $iContactId = $oContact->DBInsertTrackedNoReload($oChange, true);
         }
     }
     $oUser = new UserLocal();
     $oUser->Set('login', $sAdminUser);
     $oUser->Set('password', $sAdminPwd);
     if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && $iContactId != 0) {
         $oUser->Set('contactid', $iContactId);
     }
     $oUser->Set('language', $sLanguage);
     // Language was chosen during the installation
     // Add this user to the very specific 'admin' profile
     $oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => ADMIN_PROFILE_NAME), true);
     if (is_object($oAdminProfile)) {
         $oUserProfile = new URP_UserProfile();
         //$oUserProfile->Set('userid', $iUserId);
         $oUserProfile->Set('profileid', $oAdminProfile->GetKey());
         $oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile');
         //$oUserProfile->DBInsertTrackedNoReload($oChange, true /* skip security */);
         $oSet = DBObjectSet::FromObject($oUserProfile);
         $oUser->Set('profile_list', $oSet);
     }
     $iUserId = $oUser->DBInsertTrackedNoReload($oChange, true);
     return true;
 }
Пример #10
0
$oP->add('</div>');
$oP->add('');
$oP->add('');
$oP->EndCollapsibleSection();
$oP->add('<p>&nbsp;</p>');
$oP->AddTabContainer('Tabs_0');
$oP->SetCurrentTabContainer('Tabs_0');
$oP->SetCurrentTab(Dict::S('UI:NotificationsMenu:Triggers'));
$oP->add('<h2>' . Dict::S('UI:NotificationsMenu:AvailableTriggers') . '</h2>');
$oFilter = new DBObjectSearch('Trigger');
$aParams = array();
$oBlock = new DisplayBlock($oFilter, 'list', false, $aParams);
$oBlock->Display($oP, 'block_0', $aParams);
$aActionClasses = array();
foreach (MetaModel::EnumChildClasses('Action', ENUM_CHILD_CLASSES_EXCLUDETOP) as $sActionClass) {
    if (!MetaModel::IsAbstract($sActionClass)) {
        $aActionClasses[] = $sActionClass;
    }
}
$oP->SetCurrentTab(Dict::S('UI:NotificationsMenu:Actions'));
if (count($aActionClasses) == 1) {
    // Preserve old style
    $oP->add('<h2>' . Dict::S('UI:NotificationsMenu:AvailableActions') . '</h2>');
}
$iBlock = 0;
foreach ($aActionClasses as $sActionClass) {
    if (count($aActionClasses) > 1) {
        // New style
        $oP->add('<h2>' . MetaModel::GetName($sActionClass) . '</h2>');
    }
    $oFilter = new DBObjectSearch($sActionClass);
 public function MakeValueFromString($sProposedValue, $bLocalizedValue = false, $sSepItem = null, $sSepAttribute = null, $sSepValue = null, $sAttributeQualifier = null)
 {
     if (is_null($sSepItem) || empty($sSepItem)) {
         $sSepItem = MetaModel::GetConfig()->Get('link_set_item_separator');
     }
     if (is_null($sSepAttribute) || empty($sSepAttribute)) {
         $sSepAttribute = MetaModel::GetConfig()->Get('link_set_attribute_separator');
     }
     if (is_null($sSepValue) || empty($sSepValue)) {
         $sSepValue = MetaModel::GetConfig()->Get('link_set_value_separator');
     }
     if (is_null($sAttributeQualifier) || empty($sAttributeQualifier)) {
         $sAttributeQualifier = MetaModel::GetConfig()->Get('link_set_attribute_qualifier');
     }
     $sTargetClass = $this->Get('linked_class');
     $sInput = str_replace($sSepItem, "\n", $sProposedValue);
     $oCSVParser = new CSVParser($sInput, $sSepAttribute, $sAttributeQualifier);
     $aInput = $oCSVParser->ToArray(0);
     $aLinks = array();
     foreach ($aInput as $aRow) {
         // 1st - get the values, split the extkey->searchkey specs, and eventually get the finalclass value
         $aExtKeys = array();
         $aValues = array();
         foreach ($aRow as $sCell) {
             $iSepPos = strpos($sCell, $sSepValue);
             if ($iSepPos === false) {
                 // Houston...
                 throw new CoreException('Wrong format for link attribute specification', array('value' => $sCell));
             }
             $sAttCode = trim(substr($sCell, 0, $iSepPos));
             $sValue = substr($sCell, $iSepPos + strlen($sSepValue));
             if (preg_match('/^(.+)->(.+)$/', $sAttCode, $aMatches)) {
                 $sKeyAttCode = $aMatches[1];
                 $sRemoteAttCode = $aMatches[2];
                 $aExtKeys[$sKeyAttCode][$sRemoteAttCode] = $sValue;
                 if (!MetaModel::IsValidAttCode($sTargetClass, $sKeyAttCode)) {
                     throw new CoreException('Wrong attribute code for link attribute specification', array('class' => $sTargetClass, 'attcode' => $sKeyAttCode));
                 }
                 $oKeyAttDef = MetaModel::GetAttributeDef($sTargetClass, $sKeyAttCode);
                 $sRemoteClass = $oKeyAttDef->GetTargetClass();
                 if (!MetaModel::IsValidAttCode($sRemoteClass, $sRemoteAttCode)) {
                     throw new CoreException('Wrong attribute code for link attribute specification', array('class' => $sRemoteClass, 'attcode' => $sRemoteAttCode));
                 }
             } else {
                 if (!MetaModel::IsValidAttCode($sTargetClass, $sAttCode)) {
                     throw new CoreException('Wrong attribute code for link attribute specification', array('class' => $sTargetClass, 'attcode' => $sAttCode));
                 }
                 $aValues[$sAttCode] = $sValue;
             }
         }
         // 2nd - Instanciate the object and set the value
         if (isset($aValues['finalclass'])) {
             $sLinkClass = $aValues['finalclass'];
             if (!is_subclass_of($sLinkClass, $sTargetClass)) {
                 throw new CoreException('Wrong class for link attribute specification', array('requested_class' => $sLinkClass, 'expected_class' => $sTargetClass));
             }
         } elseif (MetaModel::IsAbstract($sTargetClass)) {
             throw new CoreException('Missing finalclass for link attribute specification');
         } else {
             $sLinkClass = $sTargetClass;
         }
         $oLink = MetaModel::NewObject($sLinkClass);
         foreach ($aValues as $sAttCode => $sValue) {
             $oLink->Set($sAttCode, $sValue);
         }
         // 3rd - Set external keys from search conditions
         foreach ($aExtKeys as $sKeyAttCode => $aReconciliation) {
             $oKeyAttDef = MetaModel::GetAttributeDef($sTargetClass, $sKeyAttCode);
             $sKeyClass = $oKeyAttDef->GetTargetClass();
             $oExtKeyFilter = new CMDBSearchFilter($sKeyClass);
             $aReconciliationDesc = array();
             foreach ($aReconciliation as $sRemoteAttCode => $sValue) {
                 $oExtKeyFilter->AddCondition($sRemoteAttCode, $sValue, '=');
                 $aReconciliationDesc[] = "{$sRemoteAttCode}={$sValue}";
             }
             $oExtKeySet = new CMDBObjectSet($oExtKeyFilter);
             switch ($oExtKeySet->Count()) {
                 case 0:
                     $sReconciliationDesc = implode(', ', $aReconciliationDesc);
                     throw new CoreException("Found no match", array('ext_key' => $sKeyAttCode, 'reconciliation' => $sReconciliationDesc));
                     break;
                 case 1:
                     $oRemoteObj = $oExtKeySet->Fetch();
                     $oLink->Set($sKeyAttCode, $oRemoteObj->GetKey());
                     break;
                 default:
                     $sReconciliationDesc = implode(', ', $aReconciliationDesc);
                     throw new CoreException("Found several matches", array('ext_key' => $sKeyAttCode, 'reconciliation' => $sReconciliationDesc));
                     // Found several matches, ambiguous
             }
         }
         // Check (roughly) if such a link is valid
         $aErrors = array();
         foreach (MetaModel::ListAttributeDefs($sTargetClass) as $sAttCode => $oAttDef) {
             if ($oAttDef->IsExternalKey()) {
                 if ($oAttDef->GetTargetClass() == $this->GetHostClass() || is_subclass_of($this->GetHostClass(), $oAttDef->GetTargetClass())) {
                     continue;
                     // Don't check the key to self
                 }
             }
             if ($oAttDef->IsWritable() && $oAttDef->IsNull($oLink->Get($sAttCode)) && !$oAttDef->IsNullAllowed()) {
                 $aErrors[] = $sAttCode;
             }
         }
         if (count($aErrors) > 0) {
             throw new CoreException("Missing value for mandatory attribute(s): " . implode(', ', $aErrors));
         }
         $aLinks[] = $oLink;
     }
     $oSet = DBObjectSet::FromArray($sTargetClass, $aLinks);
     return $oSet;
 }
Пример #12
0
 if (empty($sClass)) {
     throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'class'));
 }
 $aArgs = utils::ReadParam('default', array(), false, 'raw_data');
 $aContext = $oAppContext->GetAsHash();
 foreach ($oAppContext->GetNames() as $key) {
     $aArgs[$key] = $oAppContext->GetCurrentValue($key);
 }
 // If the specified class has subclasses, ask the user an instance of which class to create
 $aSubClasses = MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL);
 // Including the specified class itself
 $aPossibleClasses = array();
 $sRealClass = '';
 if ($bCheckSubClass) {
     foreach ($aSubClasses as $sCandidateClass) {
         if (!MetaModel::IsAbstract($sCandidateClass) && UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES) {
             $aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
         }
     }
     // Only one of the subclasses can be instantiated...
     if (count($aPossibleClasses) == 1) {
         $aKeys = array_keys($aPossibleClasses);
         $sRealClass = $aKeys[0];
     }
 } else {
     $sRealClass = $sClass;
 }
 if (!empty($sRealClass)) {
     // Display the creation form
     $sClassLabel = MetaModel::GetName($sRealClass);
     // Note: some code has been duplicated to the case 'apply_new' when a data integrity issue has been found
Пример #13
0
/**
 * Display the details of a given class of objects
 */
function DisplayClassDetails($oPage, $sClass, $sContext)
{
    $oPage->add("<h2>" . MetaModel::GetName($sClass) . " ({$sClass}) - " . MetaModel::GetClassDescription($sClass) . "</h2>\n");
    if (MetaModel::IsAbstract($sClass)) {
        $oPage->p(Dict::S('UI:Schema:AbstractClass'));
    } else {
        $oPage->p(Dict::S('UI:Schema:NonAbstractClass'));
    }
    //	$oPage->p("<h3>".Dict::S('UI:Schema:ClassHierarchyTitle')."</h3>");
    $aParentClasses = array();
    foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass) {
        $aParentClasses[] = MakeClassHLink($sParentClass, $sContext);
    }
    if (count($aParentClasses) > 0) {
        $sParents = implode(' &gt;&gt; ', $aParentClasses) . " &gt;&gt; <b>{$sClass}</b>";
    } else {
        $sParents = '';
    }
    $oPage->p("[<a href=\"schema.php?operation=list{$sContext}\">" . Dict::S('UI:Schema:AllClasses') . "</a>] {$sParents}");
    if (MetaModel::HasChildrenClasses($sClass)) {
        $oPage->add("<ul id=\"ClassHierarchy\">");
        $oPage->add("<li class=\"closed\">" . $sClass . "\n");
        DisplaySubclasses($oPage, $sClass, $sContext);
        $oPage->add("</li>\n");
        $oPage->add("</ul>\n");
        $oPage->add_ready_script('$("#ClassHierarchy").treeview();');
    }
    $oPage->p('');
    $oPage->AddTabContainer('details');
    $oPage->SetCurrentTabContainer('details');
    // List the attributes of the object
    $aForwardChangeTracking = MetaModel::GetTrackForwardExternalKeys($sClass);
    $aDetails = array();
    foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
        if ($oAttDef->IsExternalKey()) {
            $sValue = Dict::Format('UI:Schema:ExternalKey_To', MakeClassHLink($oAttDef->GetTargetClass(), $sContext));
            if (array_key_exists($sAttCode, $aForwardChangeTracking)) {
                $oLinkSet = $aForwardChangeTracking[$sAttCode];
                $sRemoteClass = $oLinkSet->GetHostClass();
                $sValue = $sValue . "<span title=\"Forward changes to {$sRemoteClass}\">*</span>";
            }
        } elseif ($oAttDef->IsLinkSet()) {
            $sValue = MakeClassHLink($oAttDef->GetLinkedClass(), $sContext);
        } else {
            $sValue = $oAttDef->GetDescription();
        }
        $sType = $oAttDef->GetType() . ' (' . $oAttDef->GetTypeDesc() . ')';
        $sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
        $sAllowedValues = "";
        $sMoreInfo = "";
        $aCols = array();
        foreach ($oAttDef->GetSQLColumns() as $sCol => $sFieldDesc) {
            $aCols[] = "{$sCol}: {$sFieldDesc}";
        }
        if (count($aCols) > 0) {
            $sCols = implode(', ', $aCols);
            $aMoreInfo = array();
            $aMoreInfo[] = Dict::Format('UI:Schema:Columns_Description', $sCols);
            $aMoreInfo[] = Dict::Format('UI:Schema:Default_Description', $oAttDef->GetDefaultValue());
            $aMoreInfo[] = $oAttDef->IsNullAllowed() ? Dict::S('UI:Schema:NullAllowed') : Dict::S('UI:Schema:NullNotAllowed');
            $sMoreInfo .= implode(', ', $aMoreInfo);
        }
        if ($oAttDef instanceof AttributeEnum) {
            // Display localized values for the enum (which depend on the localization provided by the class)
            $aLocalizedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array());
            $aDescription = array();
            foreach ($aLocalizedValues as $val => $sDisplay) {
                $aDescription[] = htmlentities("{$val} => ", ENT_QUOTES, 'UTF-8') . $sDisplay;
            }
            $sAllowedValues = implode(', ', $aDescription);
        } else {
            $sAllowedValues = '';
        }
        $aDetails[] = array('code' => $oAttDef->GetCode(), 'type' => $sType, 'origin' => $sOrigin, 'label' => $oAttDef->GetLabel(), 'description' => $sValue, 'values' => $sAllowedValues, 'moreinfo' => $sMoreInfo);
    }
    $oPage->SetCurrentTab(Dict::S('UI:Schema:Attributes'));
    $aConfig = array('code' => array('label' => Dict::S('UI:Schema:AttributeCode'), 'description' => Dict::S('UI:Schema:AttributeCode+')), 'label' => array('label' => Dict::S('UI:Schema:Label'), 'description' => Dict::S('UI:Schema:Label+')), 'type' => array('label' => Dict::S('UI:Schema:Type'), 'description' => Dict::S('UI:Schema:Type+')), 'origin' => array('label' => Dict::S('UI:Schema:Origin'), 'description' => Dict::S('UI:Schema:Origin+')), 'description' => array('label' => Dict::S('UI:Schema:Description'), 'description' => Dict::S('UI:Schema:Description+')), 'values' => array('label' => Dict::S('UI:Schema:AllowedValues'), 'description' => Dict::S('UI:Schema:AllowedValues+')), 'moreinfo' => array('label' => Dict::S('UI:Schema:MoreInfo'), 'description' => Dict::S('UI:Schema:MoreInfo+')));
    $oPage->table($aConfig, $aDetails);
    // List the search criteria for this object
    $aDetails = array();
    foreach (MetaModel::GetClassFilterDefs($sClass) as $sFilterCode => $oFilterDef) {
        $aOpDescs = array();
        foreach ($oFilterDef->GetOperators() as $sOpCode => $sOpDescription) {
            $sIsTheLooser = $sOpCode == $oFilterDef->GetLooseOperator() ? " (loose search)" : "";
            $aOpDescs[] = "{$sOpCode} ({$sOpDescription}){$sIsTheLooser}";
        }
        $aDetails[] = array('code' => $sFilterCode, 'description' => $oFilterDef->GetLabel(), 'operators' => implode(" / ", $aOpDescs));
    }
    $oPage->SetCurrentTab(Dict::S('UI:Schema:SearchCriteria'));
    $aConfig = array('code' => array('label' => Dict::S('UI:Schema:FilterCode'), 'description' => Dict::S('UI:Schema:FilterCode+')), 'description' => array('label' => Dict::S('UI:Schema:FilterDescription'), 'description' => Dict::S('UI:Schema:FilterDescription+')), 'operators' => array('label' => Dict::S('UI:Schema:AvailOperators'), 'description' => Dict::S('UI:Schema:AvailOperators+')));
    $oPage->table($aConfig, $aDetails);
    $oPage->SetCurrentTab(Dict::S('UI:Schema:ChildClasses'));
    DisplaySubclasses($oPage, $sClass, $sContext);
    $oPage->SetCurrentTab(Dict::S('UI:Schema:ReferencingClasses'));
    DisplayReferencingClasses($oPage, $sClass, $sContext);
    $oPage->SetCurrentTab(Dict::S('UI:Schema:RelatedClasses'));
    DisplayRelatedClasses($oPage, $sClass, $sContext);
    $oPage->SetCurrentTab(Dict::S('UI:Schema:LifeCycle'));
    DisplayLifecycle($oPage, $sClass, $sContext);
    $oPage->SetCurrentTab(Dict::S('UI:Schema:Triggers'));
    DisplayTriggers($oPage, $sClass, $sContext);
    $oPage->SetCurrentTab();
    $oPage->SetCurrentTabContainer();
}
Пример #14
0
 /**
  * Check if the speficied stimulus is allowed for the set of objects
  * @return UR_ALLOWED_YES, UR_ALLOWED_NO or UR_ALLOWED_DEPENDS
  */
 public function IsAllowed()
 {
     $sClass = $this->oFilter->GetClass();
     if (MetaModel::IsAbstract($sClass)) {
         return UR_ALLOWED_NO;
     }
     // Safeguard, not implemented if the base class of the set is abstract !
     $oSet = new DBObjectSet($this->oFilter);
     $iActionAllowed = UserRights::IsStimulusAllowed($sClass, $this->iActionCode, $oSet);
     if ($iActionAllowed == UR_ALLOWED_NO) {
         $this->iAllowedCount = 0;
         $this->aAllowedIDs = array();
     } else {
         // Hmmm, may not be needed right now because we limit the "multiple" action to object in
         // the same state... may be useful later on if we want to extend this behavior...
         // Check for each object if the action is allowed or not
         $this->aAllowedIDs = array();
         $oSet->Rewind();
         $iAllowedCount = 0;
         $iActionAllowed = UR_ALLOWED_DEPENDS;
         while ($oObj = $oSet->Fetch()) {
             $aTransitions = $oObj->EnumTransitions();
             if (array_key_exists($this->iActionCode, $aTransitions)) {
                 // Temporary optimization possible: since the current implementation
                 // of IsActionAllowed does not perform a 'per instance' check, we could
                 // skip this second validation phase and assume it would return UR_ALLOWED_YES
                 $oObjSet = DBObjectSet::FromArray($sClass, array($oObj));
                 if (!UserRights::IsStimulusAllowed($sClass, $this->iActionCode, $oObjSet)) {
                     $this->aAllowedIDs[$oObj->GetKey()] = false;
                 } else {
                     // Assume UR_ALLOWED_YES, since there is just one object !
                     $this->aAllowedIDs[$oObj->GetKey()] = true;
                     $this->iState = $oObj->GetState();
                     $this->iAllowedCount++;
                 }
             } else {
                 $this->aAllowedIDs[$oObj->GetKey()] = false;
             }
         }
     }
     if ($this->iAllowedCount == $oSet->Count()) {
         $iActionAllowed = UR_ALLOWED_YES;
     }
     if ($this->iAllowedCount == 0) {
         $iActionAllowed = UR_ALLOWED_NO;
     }
     return $iActionAllowed;
 }
 public function GetObjectCreationDlg(WebPage $oPage, $sProposedRealClass = '')
 {
     // For security reasons: check that the "proposed" class is actually a subclass of the linked class
     // and that the current user is allowed to create objects of this class
     $sRealClass = '';
     $oPage->add('<div class="wizContainer" style="vertical-align:top;"><div>');
     $aSubClasses = MetaModel::EnumChildClasses($this->sLinkedClass, ENUM_CHILD_CLASSES_ALL);
     // Including the specified class itself
     $aPossibleClasses = array();
     foreach ($aSubClasses as $sCandidateClass) {
         if (!MetaModel::IsAbstract($sCandidateClass) && UserRights::IsActionAllowed($sCandidateClass, UR_ACTION_MODIFY) == UR_ALLOWED_YES) {
             if ($sCandidateClass == $sProposedRealClass) {
                 $sRealClass = $sProposedRealClass;
             }
             $aPossibleClasses[$sCandidateClass] = MetaModel::GetName($sCandidateClass);
         }
     }
     // Only one of the subclasses can be instantiated...
     if (count($aPossibleClasses) == 1) {
         $aKeys = array_keys($aPossibleClasses);
         $sRealClass = $aKeys[0];
     }
     if ($sRealClass != '') {
         $oPage->add("<h1>" . MetaModel::GetClassIcon($sRealClass) . "&nbsp;" . Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($sRealClass)) . "</h1>\n");
         $oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
         $sExtKeyToMe = $oLinksetDef->GetExtKeyToMe();
         $aFieldFlags = array($sExtKeyToMe => OPT_ATT_HIDDEN);
         cmdbAbstractObject::DisplayCreationForm($oPage, $sRealClass, null, array(), array('formPrefix' => $this->sInputid, 'noRelations' => true, 'fieldsFlags' => $aFieldFlags));
     } else {
         $sClassLabel = MetaModel::GetName($this->sLinkedClass);
         $oPage->add('<p>' . Dict::Format('UI:SelectTheTypeOf_Class_ToCreate', $sClassLabel));
         $oPage->add('<nobr><select name="class">');
         asort($aPossibleClasses);
         foreach ($aPossibleClasses as $sClassName => $sClassLabel) {
             $oPage->add("<option value=\"{$sClassName}\">{$sClassLabel}</option>");
         }
         $oPage->add('</select>');
         $oPage->add('&nbsp; <button type="button" onclick="$(\'#' . $this->sInputid . '\').directlinks(\'subclassSelected\');">' . Dict::S('UI:Button:Apply') . '</button><span class="indicator" style="display:inline-block;width:16px"></span></nobr></p>');
     }
     $oPage->add('</div></div>');
 }