/**
  * Constructs a DisplayBlock object from a DBObjectSet already in memory
  * @param $oSet DBObjectSet
  * @return DisplayBlock The DisplayBlock object, or null if the creation failed
  */
 public static function FromObjectSet(DBObjectSet $oSet, $sStyle, $aParams = array())
 {
     $oDummyFilter = new DBObjectSearch($oSet->GetClass());
     $aKeys = array();
     while ($oObject = $oSet->Fetch()) {
         $aKeys[] = $oObject->GetKey();
     }
     $oSet->Rewind();
     if (count($aKeys) > 0) {
         $oDummyFilter->AddCondition('id', $aKeys, 'IN');
     } else {
         $oDummyFilter->AddCondition('id', 0, '=');
     }
     $oBlock = new DisplayBlock($oDummyFilter, $sStyle, false, $aParams);
     // DisplayBlocks built this way are synchronous
     return $oBlock;
 }
Exemplo n.º 2
0
/**
 * Adds the context parameters to the audit query
 */
function FilterByContext(DBSearch &$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);
                    }
                }
            }
        }
    }
}
Exemplo n.º 3
0
/**
 * Create a User Request ticket from the basic information retrieved from an email
 * @param string $sSenderEmail eMail address of the sender (From), used to lookup a contact in iTop
 * @param string $sSubject eMail's subject, will be turned into the title of the ticket
 * @param string $sBody Body of the email, will be fitted into the ticket's description
 * @return UserRequest The created ticket, or  null if the creation failed for some reason...
 */
function CreateTicket($sSenderEmail, $sSubject, $sBody)
{
    $oTicket = null;
    try {
        $oContactSearch = new DBObjectSearch('Contact');
        // Can be either a Person or a Team, but must be a valid Contact
        $oContactSearch->AddCondition('email', $sSenderEmail, '=');
        $oSet = new DBObjectSet($oContactSearch);
        if ($oSet->Count() == 1) {
            $oContact = $oSet->Fetch();
            $oOrganization = MetaModel::GetObject('Organization', $oContact->Get('org_id'));
            $oTicket = new UserRequest();
            $oTicket->Set('title', $sSubject);
            $oTicket->Set('description', $sBody);
            $oTicket->Set('org_id', $oOrganization->GetKey());
            $oTicket->Set('caller_id', $oContact->GetKey());
            $oTicket->Set('impact', DEFAULT_IMPACT);
            $oTicket->Set('urgency', DEFAULT_URGENCY);
            $oTicket->Set('product', DEFAULT_PRODUCT);
            $oTicket->Set('service_id', DEFAULT_SERVICE_ID);
            //  Can be replaced by a search for a valid service for this 'org_id'
            $oTicket->Set('servicesubcategory_id', DEFAULT_SUBSERVICE_ID);
            // Same as above...
            $oTicket->Set('workgroup_id', DEFAULT_WORKGROUP_ID);
            // Same as above...
            // Record the change information about the object
            $oMyChange = MetaModel::NewObject("CMDBChange");
            $oMyChange->Set("date", time());
            $sUserString = $oContact->GetName() . ', submitted by email';
            $oMyChange->Set("userinfo", $sUserString);
            $iChangeId = $oMyChange->DBInsert();
            $oTicket->DBInsertTracked($oMyChange);
        } else {
            echo "No contact found in iTop having the email: {$sSenderEmail}, email message ignored.\n";
        }
    } catch (Exception $e) {
        echo "Error: exception " . $e->getMessage();
        $oTicket = null;
    }
    return $oTicket;
}
Exemplo n.º 4
0
/**
 * Displays the user's changeable preferences
 * @param $oP WebPage The web page used for the output
 */
function DisplayPreferences($oP)
{
    $oAppContext = new ApplicationContext();
    $sURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?' . $oAppContext->GetForLink();
    $oP->add('<div class="page_header"><h1><img style="vertical-align:middle" src="../images/preferences.png"/>&nbsp;' . Dict::S('UI:Preferences') . "</h1></div>\n");
    $oP->add('<div id="user_prefs" style="max-width:800px; min-width:400px;">');
    //////////////////////////////////////////////////////////////////////////
    //
    // User Language selection
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('UI:FavoriteLanguage') . '</legend>');
    $oP->add('<form method="post">');
    $aLanguages = Dict::GetLanguages();
    $aSortedlang = array();
    foreach ($aLanguages as $sCode => $aLang) {
        if (MetaModel::GetConfig()->Get('demo_mode')) {
            if ($sCode != Dict::GetUserLanguage()) {
                // Demo mode: only the current user language is listed in the available choices
                continue;
            }
        }
        $aSortedlang[$aLang['description']] = $sCode;
    }
    ksort($aSortedlang);
    $oP->add('<p>' . Dict::S('UI:Favorites:SelectYourLanguage') . ' <select name="language">');
    foreach ($aSortedlang as $sCode) {
        $sSelected = $sCode == Dict::GetUserLanguage() ? 'selected' : '';
        $oP->add('<option value="' . $sCode . '" ' . $sSelected . '/>' . $aLanguages[$sCode]['description'] . ' (' . $aLanguages[$sCode]['localized_description'] . ')</option>');
    }
    $oP->add('</select></p>');
    $oP->add('<input type="hidden" name="operation" value="apply_language"/>');
    $oP->add($oAppContext->GetForForm());
    $oP->add('<p><input type="button" onClick="window.location.href=\'' . $sURL . '\'" value="' . Dict::S('UI:Button:Cancel') . '"/>');
    $oP->add('&nbsp;&nbsp;');
    $oP->add('<input type="submit" value="' . Dict::S('UI:Button:Apply') . '"/></p>');
    $oP->add('</form>');
    $oP->add('</fieldset>');
    //////////////////////////////////////////////////////////////////////////
    //
    // Other (miscellaneous) settings
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('UI:FavoriteOtherSettings') . '</legend>');
    $oP->add('<form method="post" onsubmit="return ValidateOtherSettings()">');
    $iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
    $oP->add('<p>' . Dict::Format('UI:Favorites:Default_X_ItemsPerPage', '<input id="default_page_size" name="default_page_size" type="text" size="3" value="' . $iDefaultPageSize . '"/><span id="v_default_page_size"></span>') . '</p>');
    $oP->add('<input type="hidden" name="operation" value="apply_others"/>');
    $oP->add($oAppContext->GetForForm());
    $oP->add('<p><input type="button" onClick="window.location.href=\'' . $sURL . '\'" value="' . Dict::S('UI:Button:Cancel') . '"/>');
    $oP->add('&nbsp;&nbsp;');
    $oP->add('<input id="other_submit" type="submit" value="' . Dict::S('UI:Button:Apply') . '"/></p>');
    $oP->add('</form>');
    $oP->add('</fieldset>');
    $oP->add_script(<<<EOF
function ValidateOtherSettings()
{
\tvar sPageLength = \$('#default_page_size').val();
\tvar iPageLength = parseInt(sPageLength , 10);
\tif (/^[0-9]+\$/.test(sPageLength) && (iPageLength > 0))
\t{
\t\t\$('#v_default_page_size').html('');
\t\t\$('#other_submit').removeAttr('disabled');
\t\treturn true;
\t}
\telse
\t{
\t\t\$('#v_default_page_size').html('<img src="../images/validation_error.png"/>');
\t\t\$('#other_submit').attr('disabled', 'disabled');
\t\treturn false;
\t}
}
EOF
);
    //////////////////////////////////////////////////////////////////////////
    //
    // Favorite Organizations
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('UI:FavoriteOrganizations') . '</legend>');
    $oP->p(Dict::S('UI:FavoriteOrganizations+'));
    $oP->add('<form method="post">');
    // Favorite organizations: the organizations listed in the drop-down menu
    $sOQL = ApplicationMenu::GetFavoriteSiloQuery();
    $oFilter = DBObjectSearch::FromOQL($sOQL);
    $oBlock = new DisplayBlock($oFilter, 'list', false);
    $oBlock->Display($oP, 1, array('menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount' => '.selectedCount', 'table_id' => 'user_prefs'));
    $oP->add($oAppContext->GetForForm());
    $oP->add('<input type="hidden" name="operation" value="apply"/>');
    $oP->add('<p><input type="button" onClick="window.location.href=\'' . $sURL . '\'" value="' . Dict::S('UI:Button:Cancel') . '"/>');
    $oP->add('&nbsp;&nbsp;');
    $oP->add('<input type="submit" value="' . Dict::S('UI:Button:Apply') . '"/></p>');
    $oP->add('</form>');
    $oP->add('</fieldset>');
    $aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null);
    if ($aFavoriteOrgs == null) {
        // All checked
        $oP->add_ready_script(<<<EOF
\tif (\$('#user_prefs table.pagination').length > 0)
\t{
\t\t// paginated display, restore the selection
\t\tvar pager = \$('#user_prefs form .pager');
\t\t\$(':input[name=selectionMode]', pager).val('negative');
\t\t\$('#user_prefs table.listResults').trigger('load_selection');
\t}
\telse
\t{
\t\t\$('#user_prefs table.listResults').trigger('check_all');
\t}
EOF
);
    } else {
        $sChecked = implode('","', $aFavoriteOrgs);
        $oP->add_ready_script(<<<EOF
\tvar aChecked = ["{$sChecked}"];
\tif (\$('#user_prefs table.pagination').length > 0)
\t{
\t\t// paginated display, restore the selection
\t\tvar pager = \$('#user_prefs form .pager');
\t\t\$(':input[name=selectionMode]', pager).val('positive');
\t\tfor (i=0; i<aChecked.length; i++)
\t\t{
\t\t\tpager.append('<input type="hidden" name="storedSelection[]" id="'+aChecked[i]+'" value="'+aChecked[i]+'"/>');
\t\t}
\t\t\$('#user_prefs table.listResults').trigger('load_selection');
\t\t
\t}
\telse
\t{
\t\t\$('#user_prefs form :checkbox[name^=selectObject]').each( function()
\t\t\t{
\t\t\t\tif (\$.inArray(\$(this).val(), aChecked) > -1)
\t\t\t\t{
\t\t\t\t\t\$(this).attr('checked', true);
\t\t\t\t\t\$(this).trigger('change');
\t\t\t\t}
\t\t\t});
\t}
EOF
);
    }
    //////////////////////////////////////////////////////////////////////////
    //
    // Shortcuts
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('Menu:MyShortcuts') . '</legend>');
    //$oP->p(Dict::S('UI:Menu:MyShortcuts+'));
    $oBMSearch = new DBObjectSearch('Shortcut');
    $oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
    //$aExtraParams = array('menu' => false, 'toolkit_menu' => false, 'display_limit' => false, 'localize_values' => $bLocalize, 'zlist' => 'details');
    $aExtraParams = array();
    $oBlock = new DisplayBlock($oBMSearch, 'list', false, $aExtraParams);
    $oBlock->Display($oP, 'shortcut_list', array('view_link' => false, 'menu' => false, 'toolkit_menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount' => '#shortcut_selection_count', 'table_id' => 'user_prefs_shortcuts'));
    $oP->add('<p>');
    $oSet = new DBObjectSet($oBMSearch);
    if ($oSet->Count() > 0) {
        $sButtons = '<img src="../images/tv-item-last.gif">';
        $sButtons .= '&nbsp;';
        $sButtons .= '<button id="shortcut_btn_rename">' . Dict::S('UI:Button:Rename') . '</button>';
        $sButtons .= '&nbsp;';
        $sButtons .= '<button id="shortcut_btn_delete">' . Dict::S('UI:Button:Delete') . '</button>';
        // Selection count updated by the pager, and used to enable buttons
        $oP->add('<input type="hidden" id="shortcut_selection_count"/>');
        $oP->add('</fieldset>');
        $sConfirmDelete = addslashes(Dict::S('UI:ShortcutDelete:Confirm'));
        $oP->add_ready_script(<<<EOF
function OnShortcutBtnRename()
{
\tvar oParams = \$('#datatable_shortcut_list').datatable('GetMultipleSelectionParams');
\toParams.operation = 'shortcut_rename_dlg';

\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data){
\t\t\$('body').append(data);
\t});
\treturn false;
}

function OnShortcutBtnDelete()
{
\tif (confirm('{$sConfirmDelete}'))
\t{
\t\tvar oParams = \$('#datatable_shortcut_list').datatable('GetMultipleSelectionParams');
\t\toParams.operation = 'shortcut_delete_go';

\t\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data){
\t\t\t\$('body').append(data);
\t\t});
\t}
\treturn false;
}

function OnSelectionCountChange()
{
\tvar iCountSelected = \$("#shortcut_selection_count").val();
\tif (iCountSelected == 0)
\t{
\t\t\$('#shortcut_btn_rename').attr('disabled', 'disabled');
\t\t\$('#shortcut_btn_delete').attr('disabled', 'disabled');
\t}
\telse if (iCountSelected == 1)
\t{
\t\t\$('#shortcut_btn_rename').removeAttr('disabled');
\t\t\$('#shortcut_btn_delete').removeAttr('disabled');
\t}
\telse
\t{
\t\t\$('#shortcut_btn_rename').attr('disabled', 'disabled');
\t\t\$('#shortcut_btn_delete').removeAttr('disabled');
\t}
}

var oUpperCheckBox = \$('#datatable_shortcut_list .checkAll').first();
oUpperCheckBox.parent().width(oUpperCheckBox.width() + 2);

\$('#datatable_shortcut_list').append('<tr><td colspan="2">&nbsp;&nbsp;&nbsp;{$sButtons}</td></tr>');
\$('#shortcut_selection_count').bind('change', OnSelectionCountChange);
\$('#shortcut_btn_rename').bind('click', OnShortcutBtnRename);
\$('#shortcut_btn_delete').bind('click', OnShortcutBtnDelete);
OnSelectionCountChange();
EOF
);
    }
    // if count > 0
    //////////////////////////////////////////////////////////////////////////
    //
    // Footer
    //
    $oP->add('</div>');
    $oP->add_ready_script("\$('#fav_page_length').bind('keyup change', function(){ ValidateOtherSettings(); })");
}
Exemplo n.º 5
0
 /**
  * Describe (as a text string) the modifications corresponding to this change
  */
 public function GetDescription()
 {
     // Temporary, until we change the options of GetDescription() -needs a more global revision
     $bIsHtml = true;
     $sResult = '';
     $sTargetObjectClass = 'Attachment';
     $iTargetObjectKey = $this->Get('attachment_id');
     $sFilename = htmlentities($this->Get('filename'), ENT_QUOTES, 'UTF-8');
     $oTargetSearch = new DBObjectSearch($sTargetObjectClass);
     $oTargetSearch->AddCondition('id', $iTargetObjectKey, '=');
     $oMonoObjectSet = new DBObjectSet($oTargetSearch);
     if ($oMonoObjectSet->Count() > 0) {
         $oAttachment = $oMonoObjectSet->Fetch();
         $oDoc = $oAttachment->Get('contents');
         $sPreview = $oDoc->IsPreviewAvailable() ? 'data-preview="true"' : '';
         $sResult = Dict::Format('Attachments:History_File_Added', '<span class="attachment-history-added attachment"><a ' . $sPreview . ' target="_blank" href="' . $oDoc->GetDownloadURL($sTargetObjectClass, $iTargetObjectKey, 'contents') . '">' . $sFilename . '</a></span>');
     } else {
         $sResult = Dict::Format('Attachments:History_File_Added', '<span class="attachment-history-deleted">' . $sFilename . '</span>');
     }
     return $sResult;
 }
Exemplo n.º 6
0
                $oFilter->AddCondition_FullText($sSearchText);
            }
            $oSet = new DBObjectSet($oFilter);
            $oPage->add("<div class=\"page_header\">\n");
            $oPage->add("<h2>" . MetaModel::GetClassIcon($sClass) . "&nbsp;<span class=\"hilite\">" . Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', $oSet->Count(), Metamodel::GetName($sClass)) . "</h2>\n");
            $oPage->add("</div>\n");
            if ($oSet->Count() > 0) {
                $aLeafs = array();
                while ($oObj = $oSet->Fetch()) {
                    if (get_class($oObj) == $sClass) {
                        $aLeafs[] = $oObj->GetKey();
                    }
                }
                $oLeafsFilter = new DBObjectSearch($sClass);
                if (count($aLeafs) > 0) {
                    $oLeafsFilter->AddCondition('id', $aLeafs, 'IN');
                    $oBlock = new DisplayBlock($oLeafsFilter, 'list', false);
                    $sBlockId = 'global_search_' . $sClass;
                    $oPage->add('<div id="' . $sBlockId . '">');
                    $oBlock->RenderContent($oPage, array('table_id' => $sBlockId, 'currentId' => $sBlockId));
                    $oPage->add('</div>');
                    $oPage->P('&nbsp;');
                    // Some space ?
                    // Hide "no object found"
                    $oPage->add_ready_script('$("#no_object_found").hide();');
                }
            }
            $oPage->add_ready_script(<<<EOF
\$('#full_text_indicator').hide();
\$('#full_text_progress,#full_text_progress_placeholder').hide(500);
EOF
Exemplo n.º 7
0
                    $sDefaultKeys = '"' . implode('", "', $aDefaultKeys) . '"';
                }
                $oPage->add_ready_script(<<<EOF
\t\t\$('select[name^=field]').change( DoCheckMapping );
\t\taDefaultKeys = new Array({$sDefaultKeys});
\t\tDoCheckMapping();
EOF
);
            }
            break;
        case 'get_csv_template':
            $sClassName = utils::ReadParam('class_name');
            $sFormat = utils::ReadParam('format', 'csv');
            if (MetaModel::IsValidClass($sClassName)) {
                $oSearch = new DBObjectSearch($sClassName);
                $oSearch->AddCondition('id', 0, '=');
                // Make sure we create an empty set
                $oSet = new CMDBObjectSet($oSearch);
                $sResult = cmdbAbstractObject::GetSetAsCSV($oSet, array('showMandatoryFields' => true));
                $sClassDisplayName = MetaModel::GetName($sClassName);
                $sDisposition = utils::ReadParam('disposition', 'inline');
                if ($sDisposition == 'attachment') {
                    switch ($sFormat) {
                        case 'xlsx':
                            $oPage = new ajax_page("");
                            $oPage->SetContentType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
                            $oPage->SetContentDisposition('attachment', $sClassDisplayName . '.xlsx');
                            require_once APPROOT . '/application/excelexporter.class.inc.php';
                            $writer = new XLSXWriter();
                            $writer->setAuthor(UserRights::GetUserFriendlyName());
                            $aHeaders = array(0 => explode(',', $sResult));
Exemplo n.º 8
0
/**
 * Lists all the currently closed tickets
 * @param WebPage $oP The current web page
 * @return void
 */
function ListClosedTickets(WebPage $oP)
{
    $aAttSpecs = explode(',', PORTAL_TICKETS_SEARCH_CRITERIA);
    // Remove the caller_id form the search criteria if the user is not a Portal Power User
    // since the user is only allowed to see her/his own tickets
    foreach ($aAttSpecs as $idx => $sAttCode) {
        if ($sAttCode == 'caller_id' && !IsPowerUser()) {
            unset($aAttSpecs[$idx]);
        }
    }
    $aClasses = GetTicketClasses();
    $sMainClass = reset($aClasses);
    $oP->DisplaySearchForm($sMainClass, $aAttSpecs, array('operation' => 'show_closed'), 'search_', false);
    $oUserOrg = GetUserOrg();
    $oP->add("<h1>" . Dict::S('Portal:ClosedRequests') . "</h1>\n");
    $aClassToSet = array();
    foreach (GetTicketClasses() as $sClass) {
        $oSearch = $oP->PostedParamsToFilter($sClass, $aAttSpecs, 'search_');
        if (is_null($oSearch)) {
            $oSearch = new DBObjectSearch($sClass);
        }
        $oSearch->AddCondition('org_id', $oUserOrg->GetKey());
        $oSearch->AddCondition('status', 'closed');
        $iUser = UserRights::GetContactId();
        if ($iUser > 0 && !IsPowerUser()) {
            $oSearch->AddCondition('caller_id', $iUser);
        }
        $aClassToSet[$sClass] = new CMDBObjectSet($oSearch);
    }
    DisplayRequestLists($oP, $aClassToSet);
}
 /**
  * Loads the preferences for the current user, creating the record in the database
  * if needed
  */
 protected static function Load()
 {
     if (self::$oUserPrefs != null) {
         return;
     }
     $oSearch = new DBObjectSearch('appUserPreferences');
     $oSearch->AddCondition('userid', UserRights::GetUserId(), '=');
     $oSet = new DBObjectSet($oSearch);
     $oObj = $oSet->Fetch();
     if ($oObj == null) {
         // No prefs (yet) for this user, create the object
         $oObj = new appUserPreferences();
         $oObj->Set('userid', UserRights::GetUserId());
         $oObj->Set('preferences', array());
         // Default preferences: an empty array
         try {
             $oObj->DBInsert();
         } catch (Exception $e) {
             // Ignore errors
         }
     }
     self::$oUserPrefs = $oObj;
 }
Exemplo n.º 10
0
 public static function GetCreationForm($sOQL = null, $sTableSettings = null)
 {
     $oForm = new DesignerForm();
     // Find a unique default name
     // -> The class of the query + an index if necessary
     if ($sOQL == null) {
         $sDefault = '';
     } else {
         $oBMSearch = new DBObjectSearch('Shortcut');
         $oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
         $oBMSet = new DBObjectSet($oBMSearch);
         $aNames = $oBMSet->GetColumnAsArray('name');
         $oSearch = DBObjectSearch::FromOQL($sOQL);
         $sDefault = utils::MakeUniqueName($oSearch->GetClass(), $aNames);
     }
     $oField = new DesignerTextField('name', Dict::S('Class:Shortcut/Attribute:name'), $sDefault);
     $oField->SetMandatory(true);
     $oForm->AddField($oField);
     /*
     $oField = new DesignerComboField('auto_reload', Dict::S('Class:ShortcutOQL/Attribute:auto_reload'), 'none');
     $oAttDef = MetaModel::GetAttributeDef(__class__, 'auto_reload');
     $oField->SetAllowedValues($oAttDef->GetAllowedValues());
     $oField->SetMandatory(true);
     $oForm->AddField($oField);
     */
     $oField = new DesignerBooleanField('auto_reload', Dict::S('Class:ShortcutOQL/Attribute:auto_reload'), false);
     $oForm->AddField($oField);
     $oField = new DesignerTextField('auto_reload_sec', Dict::S('Class:ShortcutOQL/Attribute:auto_reload_sec'), MetaModel::GetConfig()->GetStandardReloadInterval());
     $oField->SetValidationPattern('^$|^0*([5-9]|[1-9][0-9]+)$');
     // Can be empty, or a number > 4
     $oField->SetMandatory(false);
     $oForm->AddField($oField);
     $oField = new DesignerHiddenField('oql', '', $sOQL);
     $oForm->AddField($oField);
     $oField = new DesignerHiddenField('table_settings', '', $sTableSettings);
     $oForm->AddField($oField);
     return $oForm;
 }
Exemplo n.º 11
0
    public function Display(WebPage $oP, $aExtraParams = array())
    {
        $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $this->m_sLinkageAttr);
        $sTargetClass = $oAttDef->GetTargetClass();
        $oTargetObj = MetaModel::GetObject($sTargetClass, $this->m_iObjectId);
        $oP->set_title("iTop - " . MetaModel::GetName($this->m_sLinkedClass) . " objects linked with " . MetaModel::GetName(get_class($oTargetObj)) . ": " . $oTargetObj->GetRawName());
        $oP->add("<div class=\"wizContainer\">\n");
        $oP->add("<form method=\"post\">\n");
        $oP->add("<div class=\"page_header\">\n");
        $oP->add("<input type=\"hidden\" id=\"linksToRemove\" name=\"linksToRemove\" value=\"\">\n");
        $oP->add("<input type=\"hidden\" name=\"operation\" value=\"do_modify_links\">\n");
        $oP->add("<input type=\"hidden\" name=\"class\" value=\"{$this->m_sClass}\">\n");
        $oP->add("<input type=\"hidden\" name=\"linkage\" value=\"{$this->m_sLinkageAttr}\">\n");
        $oP->add("<input type=\"hidden\" name=\"object_id\" value=\"{$this->m_iObjectId}\">\n");
        $oP->add("<input type=\"hidden\" name=\"linking_attcode\" value=\"{$this->m_sLinkingAttCode}\">\n");
        $oP->add("<h1>" . Dict::Format('UI:ManageObjectsOf_Class_LinkedWith_Class_Instance', MetaModel::GetName($this->m_sLinkedClass), MetaModel::GetName(get_class($oTargetObj)), "<span class=\"hilite\">" . $oTargetObj->GetHyperlink() . "</span>") . "</h1>\n");
        $oP->add("</div>\n");
        $oP->add_script(<<<EOF
\t\tfunction OnSelectChange()
\t\t{
\t\t\tvar nbChecked = \$('.selection:checked').length;
\t\t\tif (nbChecked > 0)
\t\t\t{
\t\t\t\t\$('#btnRemove').removeAttr('disabled');
\t\t\t}
\t\t\telse
\t\t\t{
\t\t\t\t\$('#btnRemove').attr('disabled','disabled');
\t\t\t}
\t\t}
\t\t
\t\tfunction RemoveSelected()
\t\t{
\t\t\t\$('.selection:checked').each(
\t\t\t\tfunction()
\t\t\t\t{
\t\t\t\t\t\$('#linksToRemove').val(\$('#linksToRemove').val() + ' ' + this.value);
\t\t\t\t\t\$('#row_'+this.value).remove();
\t\t\t\t}
\t\t\t);
\t\t\t// Disable the button since all the selected items have been removed
\t\t\t\$('#btnRemove').attr('disabled','disabled');
\t\t\t// Re-run the zebra plugin to properly highlight the remaining lines
\t\t\t\$('.listResults').trigger('update');
\t\t\t
\t\t}
\t\t
\t\tfunction AddObjects()
\t\t{
\t\t\t// TO DO: compute the list of objects already linked with the current Object
\t\t\t\$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { 'operation': 'addObjects',
\t\t\t\t\t\t\t\t\t\t'class': '{$this->m_sClass}',
\t\t\t\t\t\t\t\t\t\t'linkageAttr': '{$this->m_sLinkageAttr}',
\t\t\t\t\t\t\t\t\t\t'linkedClass': '{$this->m_sLinkedClass}',
\t\t\t\t\t\t\t\t\t\t'objectId': '{$this->m_iObjectId}'
\t\t\t\t\t\t\t\t\t\t}, 
\t\t\t\tfunction(data)
\t\t\t\t{
\t\t\t\t\t\$('#ModalDlg').html(data);
\t\t\t\t\tdlgWidth = \$(document).width() - 100;
\t\t\t\t\t\$('#ModalDlg').css('width', dlgWidth);
\t\t\t\t\t\$('#ModalDlg').css('left', 50);
\t\t\t\t\t\$('#ModalDlg').css('top', 50);
\t\t\t\t\t\$('#ModalDlg').dialog( 'open' );
\t\t\t\t},
\t\t\t\t'html'
\t\t\t);
\t\t}
\t\t
\t\tfunction SearchObjectsToAdd(currentFormId)
\t\t{
\t\t\tvar theMap = { 'class': '{$this->m_sClass}',
\t\t\t\t\t\t   'linkageAttr': '{$this->m_sLinkageAttr}',
\t\t\t\t\t\t   'linkedClass': '{$this->m_sLinkedClass}',
\t\t\t\t\t\t   'objectId': '{$this->m_iObjectId}'
\t\t\t\t\t\t }
\t\t\tif (\$('#'+currentFormId+' :input[name=class]').val() != undefined)
\t\t\t{
\t\t\t\ttheMap.linkedClass = \$('#'+currentFormId+' :input[name=class]').val();
\t\t\t}
\t\t\t// Gather the parameters from the search form
\t\t\t\$('#'+currentFormId+' :input').each(
\t\t\t\tfunction(i)
\t\t\t\t{
\t\t\t\t\tif (this.name != '')
\t\t\t\t\t{
\t\t\t\t\t\ttheMap[this.name] = this.value;
\t\t\t\t\t}
\t\t\t\t}
\t\t\t);
\t\t\ttheMap['operation'] = 'searchObjectsToAdd';
\t\t\t
\t\t\t// Run the query and display the results
\t\t\t\$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
\t\t\t\tfunction(data)
\t\t\t\t{
\t\t\t\t\t\$('#SearchResultsToAdd').html(data);
\t\t\t\t\t\$('#SearchResultsToAdd .listResults').tablesorter( { headers: {0: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables
\t\t\t\t\t
\t\t\t\t},
\t\t\t\t'html'
\t\t\t);

\t\t\treturn false;
\t\t}
\t\t
\t\tfunction DoAddObjects(currentFormId)
\t\t{
\t\t\tvar theMap = { 'class': '{$this->m_sClass}',
\t\t\t\t\t\t   'linkageAttr': '{$this->m_sLinkageAttr}',
\t\t\t\t\t\t   'linkedClass': '{$this->m_sLinkedClass}',
\t\t\t\t\t\t   'objectId': '{$this->m_iObjectId}'
\t\t\t\t\t\t }
\t\t\t
\t\t\t// Gather the parameters from the search form
\t\t\t\$('#'+currentFormId+' :input').each(
\t\t\t\tfunction(i)
\t\t\t\t{
\t\t\t\t\tif ( (this.name != '') && ((this.type != 'checkbox') || (this.checked)) ) 
\t\t\t\t\t{
\t\t\t\t\t\t//console.log(this.type);
\t\t\t\t\t\tarrayExpr = /\\[\\]\$/;
\t\t\t\t\t\tif (arrayExpr.test(this.name))
\t\t\t\t\t\t{
\t\t\t\t\t\t\t// Array
\t\t\t\t\t\t\tif (theMap[this.name] == undefined)
\t\t\t\t\t\t\t{
\t\t\t\t\t\t\t\ttheMap[this.name] = new Array();
\t\t\t\t\t\t\t}
\t\t\t\t\t\t\ttheMap[this.name].push(this.value);
\t\t\t\t\t\t}
\t\t\t\t\t\telse
\t\t\t\t\t\t{
\t\t\t\t\t\t\ttheMap[this.name] = this.value;
\t\t\t\t\t\t}
\t\t\t\t\t}
\t\t\t\t}
\t\t\t);
\t\t\ttheMap['operation'] = 'doAddObjects';
\t\t\t
\t\t\t// Run the query and display the results
\t\t\t\$.post( GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', theMap, 
\t\t\t\tfunction(data)
\t\t\t\t{
\t\t\t\t\t//console.log('Data: ' + data);
\t\t\t\t\tif (data != '')
\t\t\t\t\t{
\t\t\t\t\t\t\$('#empty_row').remove();
\t\t\t\t\t}
\t\t\t\t\t\$('.listResults tbody').append(data);
\t\t\t\t\t\$('.listResults').trigger('update');
\t\t\t\t\t\$('.listResults').tablesorter( { headers: {0: false}}, widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables
\t\t\t\t},
\t\t\t\t'html'
\t\t\t);
\t\t\t\$('#ModalDlg').dialog('close');
\t\t\treturn false;
\t\t}
\t\t
\t\tfunction InitForm()
\t\t{
\t\t\t// make sure that the form is clean
\t\t\t\$('.selection').each( function() { this.checked = false; });
\t\t\t\$('#btnRemove').attr('disabled','disabled');
\t\t\t\$('#linksToRemove').val('');
\t\t}
\t\t
\t\tfunction SubmitHook() 
\t\t{
\t\t\tvar the_form = this;
\t\t\tSearchObjectsToAdd(the_form.id);
\t\t\treturn false;
\t\t}
EOF
);
        $oP->add_ready_script("InitForm();");
        $oFilter = new DBObjectSearch($this->m_sClass);
        $oFilter->AddCondition($this->m_sLinkageAttr, $this->m_iObjectId, '=');
        $oSet = new DBObjectSet($oFilter);
        $aForm = array();
        while ($oCurrentLink = $oSet->Fetch()) {
            $aRow = array();
            $key = $oCurrentLink->GetKey();
            $oLinkedObj = MetaModel::GetObject($this->m_sLinkedClass, $oCurrentLink->Get($this->m_sLinkingAttCode));
            $aForm[$key] = $this->GetFormRow($oP, $oLinkedObj, $oCurrentLink);
        }
        //var_dump($aTableLabels);
        //var_dump($aForm);
        $this->DisplayFormTable($oP, $this->m_aTableConfig, $aForm);
        $oP->add("<span style=\"float:left;\">&nbsp;&nbsp;&nbsp;<img src=\"../images/tv-item-last.gif\">&nbsp;&nbsp;<input id=\"btnRemove\" type=\"button\" value=\"" . Dict::S('UI:RemoveLinkedObjectsOf_Class') . "\" onClick=\"RemoveSelected();\" >");
        $oP->add("&nbsp;&nbsp;&nbsp;<input id=\"btnAdd\" type=\"button\" value=\"" . Dict::Format('UI:AddLinkedObjectsOf_Class', MetaModel::GetName($this->m_sLinkedClass)) . "\" onClick=\"AddObjects();\"></span>\n");
        $oP->add("<span style=\"float:right;\"><input id=\"btnCancel\" type=\"button\" value=\"" . Dict::S('UI:Button:Cancel') . "\" onClick=\"BackToDetails('" . $sTargetClass . "', " . $this->m_iObjectId . ");\">");
        $oP->add("&nbsp;&nbsp;&nbsp;<input id=\"btnOk\" type=\"submit\" value=\"" . Dict::S('UI:Button:Ok') . "\"></span>\n");
        $oP->add("<span style=\"clear:both;\"><p>&nbsp;</p></span>\n");
        $oP->add("</div>\n");
        $oP->add("</form>\n");
        if (isset($aExtraParams['StartWithAdd']) && $aExtraParams['StartWithAdd']) {
            $oP->add_ready_script("AddObjects();");
        }
    }
Exemplo n.º 12
0
 public function Process(CMDBChange $oChange = null)
 {
     // Note: $oChange can be null, in which case the aim is to check what would be done
     // Debug...
     //
     if (false) {
         echo "<pre>\n";
         echo "Attributes:\n";
         print_r($this->m_aAttList);
         echo "ExtKeys:\n";
         print_r($this->m_aExtKeys);
         echo "Reconciliation:\n";
         print_r($this->m_aReconcilKeys);
         echo "Synchro scope:\n";
         print_r($this->m_sSynchroScope);
         echo "Synchro changes:\n";
         print_r($this->m_aOnDisappear);
         //echo "Data:\n";
         //print_r($this->m_aData);
         echo "</pre>\n";
         exit;
     }
     $aResult = array();
     if (!is_null($this->m_sDateFormat) && strlen($this->m_sDateFormat) > 0) {
         // Translate dates from the source data
         //
         foreach ($this->m_aAttList as $sAttCode => $iCol) {
             $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
             if ($oAttDef instanceof AttributeDateTime) {
                 foreach ($this->m_aData as $iRow => $aRowData) {
                     $sNewDate = utils::StringToTime($this->m_aData[$iRow][$iCol], $this->m_sDateFormat);
                     if ($sNewDate !== false) {
                         // Todo - improve the reporting
                         $this->m_aData[$iRow][$iCol] = $sNewDate;
                     } else {
                         // Leave the cell unchanged
                         $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
                         $aResult[$iRow][$sAttCode] = new CellStatus_Issue(null, $this->m_aData[$iRow][$iCol], Dict::S('UI:CSVReport-Row-Issue-DateFormat'));
                     }
                 }
             }
         }
     }
     // Compute the results
     //
     if (!is_null($this->m_sSynchroScope)) {
         $aVisited = array();
     }
     $iPreviousTimeLimit = ini_get('max_execution_time');
     $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
     foreach ($this->m_aData as $iRow => $aRowData) {
         set_time_limit($iLoopTimeLimit);
         if (isset($aResult[$iRow]["__STATUS__"])) {
             // An issue at the earlier steps - skip the rest
             continue;
         }
         try {
             $oReconciliationFilter = new DBObjectSearch($this->m_sClass);
             $bSkipQuery = false;
             foreach ($this->m_aReconcilKeys as $sAttCode) {
                 $valuecondition = null;
                 if (array_key_exists($sAttCode, $this->m_aExtKeys)) {
                     if ($this->IsNullExternalKeySpec($aRowData, $sAttCode)) {
                         $oExtKey = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
                         if ($oExtKey->IsNullAllowed()) {
                             $valuecondition = $oExtKey->GetNullValue();
                             $aResult[$iRow][$sAttCode] = new CellStatus_Void($oExtKey->GetNullValue());
                         } else {
                             $aResult[$iRow][$sAttCode] = new CellStatus_NullIssue();
                         }
                     } else {
                         // The value has to be found or verified
                         list($sQuery, $aMatches) = $this->ResolveExternalKey($aRowData, $sAttCode, $aResult[$iRow]);
                         if (count($aMatches) == 1) {
                             $oRemoteObj = reset($aMatches);
                             // first item
                             $valuecondition = $oRemoteObj->GetKey();
                             $aResult[$iRow][$sAttCode] = new CellStatus_Void($oRemoteObj->GetKey());
                         } elseif (count($aMatches) == 0) {
                             $aResult[$iRow][$sAttCode] = new CellStatus_SearchIssue();
                         } else {
                             $aResult[$iRow][$sAttCode] = new CellStatus_Ambiguous(null, count($aMatches), $sQuery);
                         }
                     }
                 } else {
                     // The value is given in the data row
                     $iCol = $this->m_aAttList[$sAttCode];
                     if ($sAttCode == 'id') {
                         $valuecondition = $aRowData[$iCol];
                     } else {
                         $oAttDef = MetaModel::GetAttributeDef($this->m_sClass, $sAttCode);
                         $valuecondition = $oAttDef->MakeValueFromString($aRowData[$iCol], $this->m_bLocalizedValues);
                     }
                 }
                 if (is_null($valuecondition)) {
                     $bSkipQuery = true;
                 } else {
                     $oReconciliationFilter->AddCondition($sAttCode, $valuecondition, '=');
                 }
             }
             if ($bSkipQuery) {
                 $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Reconciliation'));
             } else {
                 $oReconciliationSet = new CMDBObjectSet($oReconciliationFilter);
                 switch ($oReconciliationSet->Count()) {
                     case 0:
                         $oTargetObj = $this->CreateObject($aResult, $iRow, $aRowData, $oChange);
                         // $aResult[$iRow]["__STATUS__"]=> set in CreateObject
                         $aVisited[] = $oTargetObj->GetKey();
                         break;
                     case 1:
                         $oTargetObj = $oReconciliationSet->Fetch();
                         $this->UpdateObject($aResult, $iRow, $oTargetObj, $aRowData, $oChange);
                         // $aResult[$iRow]["__STATUS__"]=> set in UpdateObject
                         if (!is_null($this->m_sSynchroScope)) {
                             $aVisited[] = $oTargetObj->GetKey();
                         }
                         break;
                     default:
                         // Found several matches, ambiguous
                         $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::S('UI:CSVReport-Row-Issue-Ambiguous'));
                         $aResult[$iRow]["id"] = new CellStatus_Ambiguous(0, $oReconciliationSet->Count(), $oReconciliationFilter->ToOql());
                         $aResult[$iRow]["finalclass"] = 'n/a';
                 }
             }
         } catch (Exception $e) {
             $aResult[$iRow]["__STATUS__"] = new RowStatus_Issue(Dict::Format('UI:CSVReport-Row-Issue-Internal', get_class($e), $e->getMessage()));
         }
     }
     if (!is_null($this->m_sSynchroScope)) {
         // Compute the delta between the scope and visited objects
         $oScopeSearch = DBObjectSearch::FromOQL($this->m_sSynchroScope);
         $oScopeSet = new DBObjectSet($oScopeSearch);
         while ($oObj = $oScopeSet->Fetch()) {
             $iObj = $oObj->GetKey();
             if (!in_array($iObj, $aVisited)) {
                 set_time_limit($iLoopTimeLimit);
                 $iRow++;
                 $this->UpdateMissingObject($aResult, $iRow, $oObj, $oChange);
             }
         }
     }
     set_time_limit($iPreviousTimeLimit);
     // Fill in the blanks - the result matrix is expected to be 100% complete
     //
     foreach ($this->m_aData as $iRow => $aRowData) {
         foreach ($this->m_aAttList as $iCol) {
             if (!array_key_exists($iCol, $aResult[$iRow])) {
                 $aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
             }
         }
         foreach ($this->m_aExtKeys as $sAttCode => $aForeignAtts) {
             if (!array_key_exists($sAttCode, $aResult[$iRow])) {
                 $aResult[$iRow][$sAttCode] = new CellStatus_Void('n/a');
             }
             foreach ($aForeignAtts as $sForeignAttCode => $iCol) {
                 if (!array_key_exists($iCol, $aResult[$iRow])) {
                     // The foreign attribute is one of our reconciliation key
                     $aResult[$iRow][$iCol] = new CellStatus_Void($aRowData[$iCol]);
                 }
             }
         }
     }
     return $aResult;
 }
 protected function DisplayAsBlock(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $bDisplayMenu)
 {
     $oLinksetDef = MetaModel::GetAttributeDef($this->sClass, $this->sAttCode);
     $sTargetClass = $oLinksetDef->GetLinkedClass();
     if ($oCurrentObj && $oCurrentObj->IsNew() && $bDisplayMenu) {
         $oPage->p(Dict::Format('UI:BeforeAdding_Class_ObjectsSaveThisObject', MetaModel::GetName($sTargetClass)));
     } else {
         $oFilter = new DBObjectSearch($sTargetClass);
         $oFilter->AddCondition($oLinksetDef->GetExtKeyToMe(), $oCurrentObj->GetKey(), '=');
         $aDefaults = array($oLinksetDef->GetExtKeyToMe() => $oCurrentObj->GetKey());
         $oAppContext = new ApplicationContext();
         foreach ($oAppContext->GetNames() as $sKey) {
             // The linked object inherits the parent's value for the context
             if (MetaModel::IsValidAttCode($this->sClass, $sKey) && $oCurrentObj) {
                 $aDefaults[$sKey] = $oCurrentObj->Get($sKey);
             }
         }
         $aParams = array('target_attr' => $oLinksetDef->GetExtKeyToMe(), 'object_id' => $oCurrentObj ? $oCurrentObj->GetKey() : null, 'menu' => $bDisplayMenu, 'default' => $aDefaults, 'table_id' => $this->sClass . '_' . $this->sAttCode);
         $oBlock = new DisplayBlock($oFilter, 'list', false);
         $oBlock->Display($oPage, $this->sInputid, $aParams);
     }
 }
 /**
  * Search for an organization with the given code in the database
  *
  * @param string $Id The organization Id to look for
  * @return cmdbOrganization the organization if it exists, null otherwise
  */
 protected function GetOrganization($sId)
 {
     $oOrg = null;
     $oFilter = new DBObjectSearch('Organization');
     $oFilter->AddCondition('id', $sId, '=');
     $oSet = new CMDBObjectSet($oFilter);
     if ($oSet->Count() > 0) {
         $oOrg = $oSet->Fetch();
         // Let's take the first one found
     }
     return $oOrg;
 }
Exemplo n.º 15
0
 public static function GetObjectByColumn($sClass, $sAttCode, $value, $bMustBeFoundUnique = true)
 {
     if (!isset(self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value])) {
         self::_check_subclass($sClass);
         $oObjSearch = new DBObjectSearch($sClass);
         $oObjSearch->AddCondition($sAttCode, $value, '=');
         $oSet = new DBObjectSet($oObjSearch);
         if ($oSet->Count() == 1) {
             self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value] = $oSet->fetch();
         } else {
             if ($bMustBeFoundUnique) {
                 throw new CoreException('Failed to get an object by column', array('class' => $sClass, 'attcode' => $sAttCode, 'value' => $value, 'matches' => $oSet->Count()));
             }
             self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value] = null;
         }
     }
     return self::$m_aCacheObjectByColumn[$sClass][$sAttCode][$value];
 }
Exemplo n.º 16
0
 function test_updatecolumn()
 {
     $oMyChange = MetaModel::NewObject("CMDBChange");
     $oMyChange->Set("date", time());
     $oMyChange->Set("userinfo", "test_updatecolumn / Made by robot #" . rand(1, 100));
     $iChangeId = $oMyChange->DBInsert();
     $sNewEmail = "updatecol" . rand(9, 250) . "@quedlaballe.com";
     echo "<h4>Update a the email: set to '{$sNewEmail}'</h4>";
     $oMyFilter = new DBObjectSearch("cmdbContact");
     $oMyFilter->AddCondition("name", "o", "Contains");
     echo "Candidates before:</br>";
     $this->search_and_show_list($oMyFilter);
     MetaModel::BulkUpdateTracked($oMyChange, $oMyFilter, array("email" => $sNewEmail));
     echo "Candidates after:</br>";
     $this->search_and_show_list($oMyFilter);
 }
Exemplo n.º 17
0
 /**
  * Helper to link objects
  *
  * @param string sLinkAttCode
  * @param string sLinkedClass
  * @param array $aLinkList
  * @param DBObject oTargetObj
  * @param WebServiceResult oRes
  *
  * @return array List of objects that could not be found
  */
 protected function AddLinkedObjects($sLinkAttCode, $sParamName, $sLinkedClass, $aLinkList, &$oTargetObj, &$oRes)
 {
     $oLinkAtt = MetaModel::GetAttributeDef(get_class($oTargetObj), $sLinkAttCode);
     $sLinkClass = $oLinkAtt->GetLinkedClass();
     $sExtKeyToItem = $oLinkAtt->GetExtKeyToRemote();
     $aItemsFound = array();
     $aItemsNotFound = array();
     if (is_null($aLinkList)) {
         return $aItemsNotFound;
     }
     foreach ($aLinkList as $aItemData) {
         if (!array_key_exists('class', $aItemData)) {
             $oRes->LogWarning("Parameter {$sParamName}: missing 'class' specification");
             continue;
             // skip
         }
         $sTargetClass = $aItemData['class'];
         if (!MetaModel::IsValidClass($sTargetClass)) {
             $oRes->LogError("Parameter {$sParamName}: invalid class '{$sTargetClass}'");
             continue;
             // skip
         }
         if (!MetaModel::IsParentClass($sLinkedClass, $sTargetClass)) {
             $oRes->LogError("Parameter {$sParamName}: '{$sTargetClass}' is not a child class of '{$sLinkedClass}'");
             continue;
             // skip
         }
         $oReconFilter = new DBObjectSearch($sTargetClass);
         $aCIStringDesc = array();
         foreach ($aItemData['search'] as $sAttCode => $value) {
             if (!MetaModel::IsValidFilterCode($sTargetClass, $sAttCode)) {
                 $aCodes = array_keys(MetaModel::GetClassFilterDefs($sTargetClass));
                 $oRes->LogError("Parameter {$sParamName}: '{$sAttCode}' is not a valid filter code for class '{$sTargetClass}', expecting a value in {" . implode(', ', $aCodes) . "}");
                 continue 2;
                 // skip the entire item
             }
             $aCIStringDesc[] = "{$sAttCode}: {$value}";
             // The attribute is one of our reconciliation key
             $oReconFilter->AddCondition($sAttCode, $value, '=');
         }
         if (count($aCIStringDesc) == 1) {
             // take the last and unique value to describe the object
             $sItemDesc = $value;
         } else {
             // describe the object by the given keys
             $sItemDesc = $sTargetClass . '(' . implode('/', $aCIStringDesc) . ')';
         }
         $oExtObjects = new CMDBObjectSet($oReconFilter);
         switch ($oExtObjects->Count()) {
             case 0:
                 $oRes->LogWarning("Parameter {$sParamName}: object to link {$sLinkedClass} / {$sItemDesc} could not be found (searched: '" . $oReconFilter->ToOQL(true) . "')");
                 $aItemsNotFound[] = $sItemDesc;
                 break;
             case 1:
                 $aItemsFound[] = array('object' => $oExtObjects->Fetch(), 'link_values' => @$aItemData['link_values'], 'desc' => $sItemDesc);
                 break;
             default:
                 $oRes->LogWarning("Parameter {$sParamName}: Found " . $oExtObjects->Count() . " matches for item '{$sItemDesc}' (searched: '" . $oReconFilter->ToOQL(true) . "')");
                 $aItemsNotFound[] = $sItemDesc;
         }
     }
     if (count($aItemsFound) > 0) {
         $aLinks = array();
         foreach ($aItemsFound as $aItemData) {
             $oLink = MetaModel::NewObject($sLinkClass);
             $oLink->Set($sExtKeyToItem, $aItemData['object']->GetKey());
             foreach ($aItemData['link_values'] as $sKey => $value) {
                 if (!MetaModel::IsValidAttCode($sLinkClass, $sKey)) {
                     $oRes->LogWarning("Parameter {$sParamName}: Attaching item '" . $aItemData['desc'] . "', the attribute code '{$sKey}' is not valid ; check the class '{$sLinkClass}'");
                 } else {
                     $oLink->Set($sKey, $value);
                 }
             }
             $aLinks[] = $oLink;
         }
         $oImpactedInfraSet = DBObjectSet::FromArray($sLinkClass, $aLinks);
         $oTargetObj->Set($sLinkAttCode, $oImpactedInfraSet);
     }
     return $aItemsNotFound;
 }
Exemplo n.º 18
0
 public function GetReferencingObjects($bAllowAllData = false)
 {
     $aDependentObjects = array();
     $aRererencingMe = MetaModel::EnumReferencingClasses(get_class($this));
     foreach ($aRererencingMe as $sRemoteClass => $aExtKeys) {
         foreach ($aExtKeys as $sExtKeyAttCode => $oExtKeyAttDef) {
             // skip if this external key is behind an external field
             if (!$oExtKeyAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
                 continue;
             }
             $oSearch = new DBObjectSearch($sRemoteClass);
             $oSearch->AddCondition($sExtKeyAttCode, $this->GetKey(), '=');
             if ($bAllowAllData) {
                 $oSearch->AllowAllData();
             }
             $oSet = new CMDBObjectSet($oSearch);
             if ($oSet->Count() > 0) {
                 $aDependentObjects[$sRemoteClass][$sExtKeyAttCode] = array('attribute' => $oExtKeyAttDef, 'objects' => $oSet);
             }
         }
     }
     return $aDependentObjects;
 }
Exemplo n.º 19
0
 /**
  * Helper method to create a CAS based user
  * @param string $sEmail
  * @param array $aGroups
  * @return bool true on success, false otherwise
  */
 protected static function CreateCASUser($sEmail, $aGroups)
 {
     if (!MetaModel::IsValidClass('URP_Profiles')) {
         phpCAS::log("URP_Profiles is not a valid class. Automatic creation of Users is not supported in this context, sorry.");
         return false;
     }
     $oUser = MetaModel::GetObjectByName('UserExternal', $sEmail, false);
     if ($oUser == null) {
         // Create the user, link it to a contact
         phpCAS::log("Info: the user '{$sEmail}' does not exist. A new UserExternal will be created.");
         $oSearch = new DBObjectSearch('Person');
         $oSearch->AddCondition('email', $sEmail);
         $oSet = new DBObjectSet($oSearch);
         $iContactId = 0;
         switch ($oSet->Count()) {
             case 0:
                 phpCAS::log("Error: found no contact with the email: '{$sEmail}'. Cannot create the user in iTop.");
                 return false;
             case 1:
                 $oContact = $oSet->Fetch();
                 $iContactId = $oContact->GetKey();
                 phpCAS::log("Info: Found 1 contact '" . $oContact->GetName() . "' (id={$iContactId}) corresponding to the email '{$sEmail}'.");
                 break;
             default:
                 phpCAS::log("Error: " . $oSet->Count() . " contacts have the same email: '{$sEmail}'. Cannot create a user for this email.");
                 return false;
         }
         $oUser = new UserExternal();
         $oUser->Set('login', $sEmail);
         $oUser->Set('contactid', $iContactId);
         $oUser->Set('language', MetaModel::GetConfig()->GetDefaultLanguage());
     } else {
         phpCAS::log("Info: the user '{$sEmail}' already exists (id=" . $oUser->GetKey() . ").");
     }
     // Now synchronize the profiles
     if (!self::SetProfilesFromCAS($oUser, $aGroups)) {
         return false;
     } else {
         if ($oUser->IsNew() || $oUser->IsModified()) {
             $oMyChange = MetaModel::NewObject("CMDBChange");
             $oMyChange->Set("date", time());
             $oMyChange->Set("userinfo", 'CAS/LDAP Synchro');
             $oMyChange->DBInsert();
             if ($oUser->IsNew()) {
                 $oUser->DBInsertTracked($oMyChange);
             } else {
                 $oUser->DBUpdateTracked($oMyChange);
             }
         }
         return true;
     }
 }
 /**
  * Search objects from a polymorph search specification (Rest/Json)
  * 	 
  * @param string $sClass Name of the class
  * @param mixed $key Either search criteria (substructure), or an object or an OQL string.
  * @return DBObjectSet The search result set
  * @throws Exception If the input structure is not valid
  */
 public static function GetObjectSetFromKey($sClass, $key)
 {
     if (is_object($key)) {
         if (isset($key->finalclass)) {
             $sClass = $key->finalclass;
             if (!MetaModel::IsValidClass($sClass)) {
                 throw new Exception("finalclass: Unknown class '{$sClass}'");
             }
         }
         $oSearch = new DBObjectSearch($sClass);
         foreach ($key as $sAttCode => $value) {
             $realValue = static::MakeValue($sClass, $sAttCode, $value);
             $oSearch->AddCondition($sAttCode, $realValue, '=');
         }
     } elseif (is_numeric($key)) {
         $oSearch = new DBObjectSearch($sClass);
         $oSearch->AddCondition('id', $key);
     } elseif (is_string($key)) {
         // OQL
         $oSearch = DBObjectSearch::FromOQL($key);
         $oObjectSet = new DBObjectSet($oSearch);
     } else {
         throw new Exception("Wrong format for key");
     }
     $oObjectSet = new DBObjectSet($oSearch);
     return $oObjectSet;
 }
 /**
  * Initializes the default search parameters based on 1) a 'current' object and 2) the silos defined by the context
  * @param DBObject $oSourceObj
  * @param DBObjectSearch $oSearch
  */
 protected function SetSearchDefaultFromContext($oSourceObj, &$oSearch)
 {
     $oAppContext = new ApplicationContext();
     $sSrcClass = get_class($oSourceObj);
     $sDestClass = $oSearch->GetClass();
     foreach ($oAppContext->GetNames() as $key) {
         // Find the value of the object corresponding to each 'context' parameter
         $aCallSpec = array($sSrcClass, 'MapContextParam');
         $sAttCode = '';
         if (is_callable($aCallSpec)) {
             $sAttCode = call_user_func($aCallSpec, $key);
             // Returns null when there is no mapping for this parameter
         }
         if (MetaModel::IsValidAttCode($sSrcClass, $sAttCode)) {
             $oAttDef = MetaModel::GetAttributeDef($sSrcClass, $sAttCode);
             $defaultValue = $oSourceObj->Get($sAttCode);
             // Find the attcode for the same 'context' parameter in the destination class
             // and sets its value as the default value for the search condition
             $aCallSpec = array($sDestClass, 'MapContextParam');
             $sAttCode = '';
             if (is_callable($aCallSpec)) {
                 $sAttCode = call_user_func($aCallSpec, $key);
                 // Returns null when there is no mapping for this parameter
             }
             if (MetaModel::IsValidAttCode($sDestClass, $sAttCode) && !empty($defaultValue)) {
                 $oSearch->AddCondition($sAttCode, $defaultValue);
             }
         }
     }
 }
 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));
                 }
                 $oAttDef = MetaModel::GetAttributeDef($sTargetClass, $sAttCode);
                 $aValues[$sAttCode] = $oAttDef->MakeValueFromString($sValue, $bLocalizedValue, $sSepItem, $sSepAttribute, $sSepValue, $sAttributeQualifier);
             }
         }
         // 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 DBObjectSearch($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;
 }
 /**
  * Store an object in the database and remember the mapping
  * between its original ID and the newly created ID in the database
  */
 protected function StoreObject($sClass, $oTargetObj, $iSrcId, $bSearch = false, $bUpdateKeyCacheOnly = false)
 {
     $iObjId = 0;
     try {
         if ($bSearch) {
             // Check if the object does not already exist, based on its usual reconciliation keys...
             $aReconciliationKeys = MetaModel::GetReconcKeys($sClass);
             if (count($aReconciliationKeys) > 0) {
                 // Some reconciliation keys have been defined, use them to search for the object
                 $oSearch = new DBObjectSearch($sClass);
                 $iConditionsCount = 0;
                 foreach ($aReconciliationKeys as $sAttCode) {
                     if ($oTargetObj->Get($sAttCode) != '') {
                         $oSearch->AddCondition($sAttCode, $oTargetObj->Get($sAttCode), '=');
                         $iConditionsCount++;
                     }
                 }
                 if ($iConditionsCount > 0) {
                     $oSet = new DBObjectSet($oSearch);
                     if ($oSet->count() == 1) {
                         // The object already exists, reuse it
                         $oExistingObject = $oSet->Fetch();
                         $iObjId = $oExistingObject->GetKey();
                     }
                 }
             }
         }
         if ($iObjId == 0) {
             if ($oTargetObj->IsNew()) {
                 if (!$bUpdateKeyCacheOnly) {
                     $iObjId = $oTargetObj->DBInsertNoReload();
                     $this->m_iCountCreated++;
                 }
             } else {
                 $iObjId = $oTargetObj->GetKey();
                 if (!$bUpdateKeyCacheOnly) {
                     $oTargetObj->DBUpdate();
                 }
             }
         }
     } catch (Exception $e) {
         SetupPage::log_error("An object could not be recorded - {$sClass}/{$iSrcId} - " . $e->getMessage());
         $this->m_aErrors[] = "An object could not be recorded - {$sClass}/{$iSrcId} - " . $e->getMessage();
     }
     $aParentClasses = MetaModel::EnumParentClasses($sClass);
     $aParentClasses[] = $sClass;
     foreach ($aParentClasses as $sObjClass) {
         $this->m_aKeys[$sObjClass][$iSrcId] = $iObjId;
     }
     $this->m_aObjectsCache[$sClass][$iObjId] = $oTargetObj;
 }
 /**
  * Describe (as a text string) the modifications corresponding to this change
  */
 public function GetDescription()
 {
     $sResult = '';
     $oTargetObjectClass = $this->Get('objclass');
     $oTargetObjectKey = $this->Get('objkey');
     $oTargetSearch = new DBObjectSearch($oTargetObjectClass);
     $oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
     $oMonoObjectSet = new DBObjectSet($oTargetSearch);
     if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES) {
         if (!MetaModel::IsValidAttCode($this->Get('objclass'), $this->Get('attcode'))) {
             return '';
         }
         // Protects against renamed attributes...
         $oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
         $sAttName = $oAttDef->GetLabel();
         $sLinkClass = $oAttDef->GetLinkedClass();
         $aLinkClasses = MetaModel::EnumChildClasses($sLinkClass, ENUM_CHILD_CLASSES_ALL);
         // Search for changes on the corresponding link
         //
         $oSearch = new DBObjectSearch('CMDBChangeOpSetAttribute');
         $oSearch->AddCondition('change', $this->Get('change'), '=');
         $oSearch->AddCondition('objkey', $this->Get('link_id'), '=');
         if (count($aLinkClasses) == 1) {
             // Faster than the whole building of the expression below for just one value ??
             $oSearch->AddCondition('objclass', $sLinkClass, '=');
         } else {
             $oField = new FieldExpression('objclass', $oSearch->GetClassAlias());
             $sListExpr = '(' . implode(', ', CMDBSource::Quote($aLinkClasses)) . ')';
             $sOQLCondition = $oField->Render() . " IN {$sListExpr}";
             $oNewCondition = Expression::FromOQL($sOQLCondition);
             $oSearch->AddConditionExpression($oNewCondition);
         }
         $oSet = new DBObjectSet($oSearch);
         $aChanges = array();
         while ($oChangeOp = $oSet->Fetch()) {
             $aChanges[] = $oChangeOp->GetDescription();
         }
         if (count($aChanges) == 0) {
             return '';
         }
         $sItemDesc = MetaModel::GetHyperLink($this->Get('item_class'), $this->Get('item_id'));
         $sResult = $sAttName . ' - ';
         $sResult .= Dict::Format('Change:LinkSet:Modified', $sItemDesc);
         $sResult .= ' : ' . implode(', ', $aChanges);
     }
     return $sResult;
 }
Exemplo n.º 25
0
 public function Revert()
 {
     $oUDSearch = new DBObjectSearch('UserDashboard');
     $oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
     $oUDSearch->AddCondition('menu_code', $this->sId, '=');
     $oUDSet = new DBObjectSet($oUDSearch);
     if ($oUDSet->Count() > 0) {
         // Assuming there is at most one couple {user, menu}!
         $oUserDashboard = $oUDSet->Fetch();
         $oUserDashboard->DBDelete();
     }
 }
Exemplo n.º 26
0
 public function PopulateChildMenus()
 {
     // Load user shortcuts in DB
     //
     $oBMSearch = new DBObjectSearch('Shortcut');
     $oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
     $oBMSet = new DBObjectSet($oBMSearch, array('friendlyname' => true));
     // ascending on friendlyname
     $fRank = 1;
     while ($oShortcut = $oBMSet->Fetch()) {
         $sName = $this->GetMenuId() . '_' . $oShortcut->GetKey();
         $oShortcutMenu = new ShortcutMenuNode($sName, $oShortcut, $this->GetIndex(), $fRank++);
     }
     // Complete the tree
     //
     parent::PopulateChildMenus();
 }
Exemplo n.º 27
0
 protected function RecordObjDeletion($objkey)
 {
     $sRootClass = MetaModel::GetRootClass(get_class($this));
     // Delete any existing change tracking about the current object
     $oFilter = new DBObjectSearch('CMDBChangeOp');
     $oFilter->AddCondition('objclass', get_class($this), '=');
     $oFilter->AddCondition('objkey', $objkey, '=');
     MetaModel::PurgeData($oFilter);
     parent::RecordObjDeletion($objkey);
     $oMyChangeOp = MetaModel::NewObject("CMDBChangeOpDelete");
     $oMyChangeOp->Set("objclass", MetaModel::GetRootClass(get_class($this)));
     $oMyChangeOp->Set("objkey", $objkey);
     $oMyChangeOp->Set("fclass", get_class($this));
     $oMyChangeOp->Set("fname", substr($this->GetRawName(), 0, 255));
     // Protect against very long friendly names
     $iId = $oMyChangeOp->DBInsertNoReload();
 }
 /**
  * Perform all the needed checks to delete one (or more) objects
  */
 public static function DeleteObjects(WebPage $oP, $sClass, $aObjects, $bPreview, $sCustomOperation, $aContextData = array())
 {
     $oDeletionPlan = new DeletionPlan();
     foreach ($aObjects as $oObj) {
         if ($bPreview) {
             $oObj->CheckToDelete($oDeletionPlan);
         } else {
             $oObj->DBDeleteTracked(CMDBObject::GetCurrentChange(), null, $oDeletionPlan);
         }
     }
     if ($bPreview) {
         if (count($aObjects) == 1) {
             $oObj = $aObjects[0];
             $oP->add("<h1>" . Dict::Format('UI:Delete:ConfirmDeletionOf_Name', $oObj->GetName()) . "</h1>\n");
         } else {
             $oP->add("<h1>" . Dict::Format('UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . "</h1>\n");
         }
         // Explain what should be done
         //
         $aDisplayData = array();
         foreach ($oDeletionPlan->ListDeletes() as $sTargetClass => $aDeletes) {
             foreach ($aDeletes as $iId => $aData) {
                 $oToDelete = $aData['to_delete'];
                 $bAutoDel = $aData['mode'] == DEL_SILENT || $aData['mode'] == DEL_AUTO;
                 if (array_key_exists('issue', $aData)) {
                     if ($bAutoDel) {
                         if (isset($aData['requested_explicitely'])) {
                             $sConsequence = Dict::Format('UI:Delete:CannotDeleteBecause', $aData['issue']);
                         } else {
                             $sConsequence = Dict::Format('UI:Delete:ShouldBeDeletedAtomaticallyButNotPossible', $aData['issue']);
                         }
                     } else {
                         $sConsequence = Dict::Format('UI:Delete:MustBeDeletedManuallyButNotPossible', $aData['issue']);
                     }
                 } else {
                     if ($bAutoDel) {
                         if (isset($aData['requested_explicitely'])) {
                             $sConsequence = '';
                             // not applicable
                         } else {
                             $sConsequence = Dict::S('UI:Delete:WillBeDeletedAutomatically');
                         }
                     } else {
                         $sConsequence = Dict::S('UI:Delete:MustBeDeletedManually');
                     }
                 }
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToDelete)), 'object' => $oToDelete->GetHyperLink(), 'consequence' => $sConsequence);
             }
         }
         foreach ($oDeletionPlan->ListUpdates() as $sRemoteClass => $aToUpdate) {
             foreach ($aToUpdate as $iId => $aData) {
                 $oToUpdate = $aData['to_reset'];
                 if (array_key_exists('issue', $aData)) {
                     $sConsequence = Dict::Format('UI:Delete:CannotUpdateBecause_Issue', $aData['issue']);
                 } else {
                     $sConsequence = Dict::Format('UI:Delete:WillAutomaticallyUpdate_Fields', $aData['attributes_list']);
                 }
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToUpdate)), 'object' => $oToUpdate->GetHyperLink(), 'consequence' => $sConsequence);
             }
         }
         $iImpactedIndirectly = $oDeletionPlan->GetTargetCount() - count($aObjects);
         if ($iImpactedIndirectly > 0) {
             if (count($aObjects) == 1) {
                 $oObj = $aObjects[0];
                 $oP->p(Dict::Format('UI:Delete:Count_Objects/LinksReferencing_Object', $iImpactedIndirectly, $oObj->GetName()));
             } else {
                 $oP->p(Dict::Format('UI:Delete:Count_Objects/LinksReferencingTheObjects', $iImpactedIndirectly));
             }
             $oP->p(Dict::S('UI:Delete:ReferencesMustBeDeletedToEnsureIntegrity'));
         }
         if ($iImpactedIndirectly > 0 || $oDeletionPlan->FoundStopper()) {
             $aDisplayConfig = array();
             $aDisplayConfig['class'] = array('label' => 'Class', 'description' => '');
             $aDisplayConfig['object'] = array('label' => 'Object', 'description' => '');
             $aDisplayConfig['consequence'] = array('label' => 'Consequence', 'description' => Dict::S('UI:Delete:Consequence+'));
             $oP->table($aDisplayConfig, $aDisplayData);
         }
         if ($oDeletionPlan->FoundStopper()) {
             if ($oDeletionPlan->FoundSecurityIssue()) {
                 $oP->p(Dict::S('UI:Delete:SorryDeletionNotAllowed'));
             } elseif ($oDeletionPlan->FoundManualOperation()) {
                 $oP->p(Dict::S('UI:Delete:PleaseDoTheManualOperations'));
             } else {
                 $oP->p(Dict::S('UI:Delete:PleaseDoTheManualOperations'));
             }
             $oAppContext = new ApplicationContext();
             $oP->add("<form method=\"post\">\n");
             $oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"" . utils::ReadParam('transaction_id') . "\">\n");
             $oP->add("<input type=\"button\" onclick=\"window.history.back();\" value=\"" . Dict::S('UI:Button:Back') . "\">\n");
             $oP->add("<input DISABLED type=\"submit\" name=\"\" value=\"" . Dict::S('UI:Button:Delete') . "\">\n");
             $oP->add($oAppContext->GetForForm());
             $oP->add("</form>\n");
         } else {
             if (count($aObjects) == 1) {
                 $oObj = $aObjects[0];
                 $id = $oObj->GetKey();
                 $oP->p('<h1>' . Dict::Format('UI:Delect:Confirm_Object', $oObj->GetHyperLink()) . '</h1>');
             } else {
                 $oP->p('<h1>' . Dict::Format('UI:Delect:Confirm_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . '</h1>');
             }
             foreach ($aObjects as $oObj) {
                 $aKeys[] = $oObj->GetKey();
             }
             $oFilter = new DBObjectSearch($sClass);
             $oFilter->AddCondition('id', $aKeys, 'IN');
             $oSet = new CMDBobjectSet($oFilter);
             $oP->add('<div id="0">');
             CMDBAbstractObject::DisplaySet($oP, $oSet, array('display_limit' => false, 'menu' => false));
             $oP->add("</div>\n");
             $oP->add("<form method=\"post\">\n");
             foreach ($aContextData as $sKey => $value) {
                 $oP->add("<input type=\"hidden\" name=\"{$sKey}\" value=\"{$value}\">\n");
             }
             $oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"" . utils::GetNewTransactionId() . "\">\n");
             $oP->add("<input type=\"hidden\" name=\"operation\" value=\"{$sCustomOperation}\">\n");
             $oP->add("<input type=\"hidden\" name=\"filter\" value=\"" . $oFilter->Serialize() . "\">\n");
             $oP->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">\n");
             foreach ($aObjects as $oObj) {
                 $oP->add("<input type=\"hidden\" name=\"selectObject[]\" value=\"" . $oObj->GetKey() . "\">\n");
             }
             $oP->add("<input type=\"button\" onclick=\"window.history.back();\" value=\"" . Dict::S('UI:Button:Back') . "\">\n");
             $oP->add("<input type=\"submit\" name=\"\" value=\"" . Dict::S('UI:Button:Delete') . "\">\n");
             $oAppContext = new ApplicationContext();
             $oP->add($oAppContext->GetForForm());
             $oP->add("</form>\n");
         }
     } else {
         // Execute the deletion
         //
         if (count($aObjects) == 1) {
             $oObj = $aObjects[0];
             $oP->add("<h1>" . Dict::Format('UI:Title:DeletionOf_Object', $oObj->GetName()) . "</h1>\n");
         } else {
             $oP->add("<h1>" . Dict::Format('UI:Title:BulkDeletionOf_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . "</h1>\n");
         }
         // Security - do not allow the user to force a forbidden delete by the mean of page arguments...
         if ($oDeletionPlan->FoundSecurityIssue()) {
             throw new CoreException(Dict::S('UI:Error:NotEnoughRightsToDelete'));
         }
         if ($oDeletionPlan->FoundManualOperation()) {
             throw new CoreException(Dict::S('UI:Error:CannotDeleteBecauseManualOpNeeded'));
         }
         if ($oDeletionPlan->FoundManualDelete()) {
             throw new CoreException(Dict::S('UI:Error:CannotDeleteBecauseOfDepencies'));
         }
         // Report deletions
         //
         $aDisplayData = array();
         foreach ($oDeletionPlan->ListDeletes() as $sTargetClass => $aDeletes) {
             foreach ($aDeletes as $iId => $aData) {
                 $oToDelete = $aData['to_delete'];
                 if (isset($aData['requested_explicitely'])) {
                     $sMessage = Dict::S('UI:Delete:Deleted');
                 } else {
                     $sMessage = Dict::S('UI:Delete:AutomaticallyDeleted');
                 }
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToDelete)), 'object' => $oToDelete->GetName(), 'consequence' => $sMessage);
             }
         }
         // Report updates
         //
         foreach ($oDeletionPlan->ListUpdates() as $sTargetClass => $aToUpdate) {
             foreach ($aToUpdate as $iId => $aData) {
                 $oToUpdate = $aData['to_reset'];
                 $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToUpdate)), 'object' => $oToUpdate->GetHyperLink(), 'consequence' => Dict::Format('UI:Delete:AutomaticResetOf_Fields', $aData['attributes_list']));
             }
         }
         // Report automatic jobs
         //
         if ($oDeletionPlan->GetTargetCount() > 0) {
             if (count($aObjects) == 1) {
                 $oObj = $aObjects[0];
                 $oP->p(Dict::Format('UI:Delete:CleaningUpRefencesTo_Object', $oObj->GetName()));
             } else {
                 $oP->p(Dict::Format('UI:Delete:CleaningUpRefencesTo_Several_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)));
             }
             $aDisplayConfig = array();
             $aDisplayConfig['class'] = array('label' => 'Class', 'description' => '');
             $aDisplayConfig['object'] = array('label' => 'Object', 'description' => '');
             $aDisplayConfig['consequence'] = array('label' => 'Done', 'description' => Dict::S('UI:Delete:Done+'));
             $oP->table($aDisplayConfig, $aDisplayData);
         }
     }
 }
 /**
  * Search for objects to be linked to the current object (i.e "remote" objects)
  * @param WebPage $oP The page used for the output (usually an AjaxWebPage)
  * @param string $sRemoteClass Name of the "remote" class to perform the search on, must be a derived class of m_sRemoteClass
  * @param Array $aAlreadyLinkedIds List of IDs of objects of "remote" class already linked, to be filtered out of the search
  */
 public function SearchObjectsToAdd(WebPage $oP, $sRemoteClass = '', $aAlreadyLinkedIds = array())
 {
     if ($sRemoteClass != '') {
         // assert(MetaModel::IsParentClass($this->m_sRemoteClass, $sRemoteClass));
         $oFilter = new DBObjectSearch($sRemoteClass);
     } else {
         // No remote class specified use the one defined in the linkedset
         $oFilter = new DBObjectSearch($this->m_sRemoteClass);
     }
     if (!$this->m_bDuplicatesAllowed && count($aAlreadyLinkedIds) > 0) {
         // Positive IDs correspond to existing link records
         // negative IDs correspond to "remote" objects to be linked
         $aLinkIds = array();
         $aRemoteObjIds = array();
         foreach ($aAlreadyLinkedIds as $iId) {
             if ($iId > 0) {
                 $aLinkIds[] = $iId;
             } else {
                 $aRemoteObjIds[] = -$iId;
             }
         }
         if (count($aLinkIds) > 0) {
             // Search for the links to find to which "remote" object they are linked
             $oLinkFilter = new DBObjectSearch($this->m_sLinkedClass);
             $oLinkFilter->AddCondition('id', $aLinkIds, 'IN');
             $oLinkSet = new CMDBObjectSet($oLinkFilter);
             while ($oLink = $oLinkSet->Fetch()) {
                 $aRemoteObjIds[] = $oLink->Get($this->m_sExtKeyToRemote);
             }
         }
         $oFilter->AddCondition('id', $aRemoteObjIds, 'NOTIN');
     }
     $oSet = new CMDBObjectSet($oFilter);
     $oBlock = new DisplayBlock($oFilter, 'list', false);
     $oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount' => '#count_' . $this->m_sAttCode . $this->m_sNameSuffix, 'selection_mode' => true, 'table_id' => 'add_' . $this->m_sAttCode));
     // Don't display the 'Actions' menu on the results
 }