public static function GetProfileActionGrant($iProfileId, $sClass, $sAction)
 {
     $bLegacyBehavior = MetaModel::GetConfig()->Get('user_rights_legacy');
     // Search for a grant, stoping if any deny is encountered (allowance implies the verification of all paths)
     $bAllow = null;
     // 1 - The class itself
     //
     $sGrantKey = $iProfileId . '_' . $sClass . '_' . $sAction;
     if (isset(self::$aGRANTS[$sGrantKey])) {
         $bAllow = self::$aGRANTS[$sGrantKey];
         if ($bLegacyBehavior) {
             return $bAllow;
         }
         if (!$bAllow) {
             return false;
         }
     }
     // 2 - The parent classes, up to the root class
     //
     foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_EXCLUDELEAF, false) as $sParent) {
         $sGrantKey = $iProfileId . '_' . $sParent . '+_' . $sAction;
         if (isset(self::$aGRANTS[$sGrantKey])) {
             $bAllow = self::$aGRANTS[$sGrantKey];
             if ($bLegacyBehavior) {
                 return $bAllow;
             }
             if (!$bAllow) {
                 return false;
             }
         }
     }
     // 3 - The related classes (if the current is an N-N link with DEL_AUTO/DEL_SILENT)
     //
     $bGrant = self::GetLinkActionGrant($iProfileId, $sClass, $sAction);
     if (!is_null($bGrant)) {
         $bAllow = $bGrant;
         if ($bLegacyBehavior) {
             return $bAllow;
         }
         if (!$bAllow) {
             return false;
         }
     }
     // 4 - All
     //
     $sGrantKey = $iProfileId . '_*_' . $sAction;
     if (isset(self::$aGRANTS[$sGrantKey])) {
         $bAllow = self::$aGRANTS[$sGrantKey];
         if ($bLegacyBehavior) {
             return $bAllow;
         }
         if (!$bAllow) {
             return false;
         }
     }
     // null or true
     return $bAllow;
 }
 public static function MakeObjectURL($sClass, $iId)
 {
     if (strpos(MetaModel::GetConfig()->Get('portal_tickets'), $sClass) !== false) {
         $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
         $sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class={$sClass}&id={$iId}";
     } else {
         $sUrl = '';
     }
     return $sUrl;
 }
 public function GetURL()
 {
     $aOverloads = MetaModel::GetConfig()->Get('portal_dispatch_urls');
     if (array_key_exists($this->sPortalid, $aOverloads)) {
         $sRet = $aOverloads[$this->sPortalid];
     } else {
         $sRet = utils::GetAbsoluteUrlAppRoot() . $this->aData['url'];
     }
     return $sRet;
 }
 public function ComputeResults()
 {
     $this->m_iToDelete = 0;
     $this->m_iToUpdate = 0;
     foreach ($this->m_aToDelete as $sClass => $aToDelete) {
         foreach ($aToDelete as $iId => $aData) {
             $this->m_iToDelete++;
             if (isset($aData['issue'])) {
                 $this->m_bFoundStopper = true;
                 $this->m_bFoundManualOperation = true;
                 if (isset($aData['issue_security'])) {
                     $this->m_bFoundSecurityIssue = true;
                 }
             }
             if ($aData['mode'] == DEL_MANUAL) {
                 $this->m_aToDelete[$sClass][$iId]['issue'] = $sClass . '::' . $iId . ' ' . Dict::S('UI:Delete:MustBeDeletedManually');
                 $this->m_bFoundStopper = true;
                 $this->m_bFoundManualDelete = true;
             }
         }
     }
     // Getting and setting time limit are not symetric:
     // www.php.net/manual/fr/function.set-time-limit.php#72305
     $iPreviousTimeLimit = ini_get('max_execution_time');
     $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
     foreach ($this->m_aToUpdate as $sClass => $aToUpdate) {
         foreach ($aToUpdate as $iId => $aData) {
             set_time_limit($iLoopTimeLimit);
             $this->m_iToUpdate++;
             $oObject = $aData['to_reset'];
             $aExtKeyLabels = array();
             foreach ($aData['attributes'] as $sRemoteExtKey => $aRemoteAttDef) {
                 $oObject->Set($sRemoteExtKey, $aData['values'][$sRemoteExtKey]);
                 $aExtKeyLabels[] = $aRemoteAttDef->GetLabel();
             }
             $this->m_aToUpdate[$sClass][$iId]['attributes_list'] = implode(', ', $aExtKeyLabels);
             list($bRes, $aIssues, $bSecurityIssues) = $oObject->CheckToWrite();
             if (!$bRes) {
                 $this->m_aToUpdate[$sClass][$iId]['issue'] = implode(', ', $aIssues);
                 $this->m_bFoundStopper = true;
                 if ($bSecurityIssues) {
                     $this->m_aToUpdate[$sClass][$iId]['issue_security'] = true;
                     $this->m_bFoundSecurityIssue = true;
                 }
             }
         }
     }
     set_time_limit($iPreviousTimeLimit);
 }
예제 #5
0
/**
 * Get the related objects through the given relation, output in XML
 * @param DBObject $oObj The current object
 * @param string $sRelation The name of the relation to search with
 */
function GetRelatedObjectsAsXml(DBObject $oObj, $sRelationName, &$oLinks, &$oXmlDoc, &$oXmlNode, $iDepth = 0, $aExcludedClasses)
{
    global $G_aCachedObjects;
    $iMaxRecursionDepth = MetaModel::GetConfig()->Get('relations_max_depth', 20);
    $aResults = array();
    $bAddLinks = false;
    if ($iDepth > $iMaxRecursionDepth - 1) {
        return;
    }
    $sIdxKey = get_class($oObj) . ':' . $oObj->GetKey();
    if (!array_key_exists($sIdxKey, $G_aCachedObjects)) {
        $oObj->GetRelatedObjects($sRelationName, 1, $aResults);
        $G_aCachedObjects[$sIdxKey] = true;
    } else {
        return;
        //$aResults = $G_aCachedObjects[$sIdxKey];
    }
    foreach ($aResults as $sRelatedClass => $aObjects) {
        foreach ($aObjects as $id => $oTargetObj) {
            if (is_object($oTargetObj)) {
                if (in_array(get_class($oTargetObj), $aExcludedClasses)) {
                    GetRelatedObjectsAsXml($oTargetObj, $sRelationName, $oLinks, $oXmlDoc, $oXmlNode, $iDepth + 1, $aExcludedClasses);
                } else {
                    $oLinkingNode = $oXmlDoc->CreateElement('link');
                    $oLinkingNode->SetAttribute('relation', $sRelationName);
                    $oLinkingNode->SetAttribute('arrow', 1);
                    // Such relations have a direction, display an arrow
                    $oLinkedNode = $oXmlDoc->CreateElement('node');
                    $oLinkedNode->SetAttribute('id', $oTargetObj->GetKey());
                    $oLinkedNode->SetAttribute('obj_class', get_class($oTargetObj));
                    $oLinkedNode->SetAttribute('obj_class_name', htmlspecialchars(MetaModel::GetName(get_class($oTargetObj))));
                    $oLinkedNode->SetAttribute('name', htmlspecialchars($oTargetObj->GetRawName()));
                    // htmlentities is too much for XML
                    $oLinkedNode->SetAttribute('icon', BuildIconPath($oTargetObj->GetIcon(false)));
                    AddNodeDetails($oLinkedNode, $oTargetObj);
                    $oSubLinks = $oXmlDoc->CreateElement('links');
                    // Recurse
                    GetRelatedObjectsAsXml($oTargetObj, $sRelationName, $oSubLinks, $oXmlDoc, $oLinkedNode, $iDepth + 1, $aExcludedClasses);
                    $oLinkingNode->AppendChild($oLinkedNode);
                    $oLinks->AppendChild($oLinkingNode);
                    $bAddLinks = true;
                }
            }
        }
    }
    if ($bAddLinks) {
        $oXmlNode->AppendChild($oLinks);
    }
}
예제 #6
0
/**
 * Helper to determine the supported types of tickets
 */
function GetTicketClasses()
{
    $aClasses = array();
    foreach (explode(',', MetaModel::GetConfig()->Get('portal_tickets')) as $sRawClass) {
        $sRawClass = trim($sRawClass);
        if (!MetaModel::IsValidClass($sRawClass)) {
            throw new Exception("Class '{$sRawClass}' is not a valid class, please review your configuration (portal_tickets)");
        }
        if (!MetaModel::IsParentClass('Ticket', $sRawClass)) {
            throw new Exception("Class '{$sRawClass}' does not inherit from Ticket, please review your configuration (portal_tickets)");
        }
        $aClasses[] = $sRawClass;
    }
    return $aClasses;
}
예제 #7
0
function CronExec($oP, $aProcesses, $bVerbose)
{
    $iStarted = time();
    $iMaxDuration = MetaModel::GetConfig()->Get('cron_max_execution_time');
    $iTimeLimit = $iStarted + $iMaxDuration;
    if ($bVerbose) {
        $oP->p("Planned duration = {$iMaxDuration} seconds");
    }
    // Reset the next planned execution to take into account new settings
    $oSearch = new DBObjectSearch('BackgroundTask');
    $oTasks = new DBObjectSet($oSearch);
    while ($oTask = $oTasks->Fetch()) {
        $sTaskClass = $oTask->Get('class_name');
        $oRefClass = new ReflectionClass($sTaskClass);
        $oNow = new DateTime();
        if ($oRefClass->implementsInterface('iScheduledProcess') && ($oTask->Get('status') != 'active' || $oTask->Get('next_run_date') > $oNow->format('Y-m-d H:i:s'))) {
            if ($bVerbose) {
                $oP->p("Resetting the next run date for {$sTaskClass}");
            }
            $oProcess = $aProcesses[$sTaskClass];
            $oNextOcc = $oProcess->GetNextOccurrence();
            $oTask->Set('next_run_date', $oNextOcc->format('Y-m-d H:i:s'));
            $oTask->DBUpdate();
        }
    }
    $iCronSleep = MetaModel::GetConfig()->Get('cron_sleep');
    $oSearch = new DBObjectSearch('BackgroundTask');
    while (time() < $iTimeLimit) {
        $oTasks = new DBObjectSet($oSearch);
        $aTasks = array();
        while ($oTask = $oTasks->Fetch()) {
            $aTasks[$oTask->Get('class_name')] = $oTask;
        }
        foreach ($aProcesses as $oProcess) {
            $sTaskClass = get_class($oProcess);
            $oNow = new DateTime();
            if (!array_key_exists($sTaskClass, $aTasks)) {
                // New entry, let's create a new BackgroundTask record, and plan the first execution
                $oTask = new BackgroundTask();
                $oTask->Set('class_name', get_class($oProcess));
                $oTask->Set('total_exec_count', 0);
                $oTask->Set('min_run_duration', 99999.999);
                $oTask->Set('max_run_duration', 0);
                $oTask->Set('average_run_duration', 0);
                $oRefClass = new ReflectionClass($sTaskClass);
                if ($oRefClass->implementsInterface('iScheduledProcess')) {
                    $oNextOcc = $oProcess->GetNextOccurrence();
                    $oTask->Set('next_run_date', $oNextOcc->format('Y-m-d H:i:s'));
                } else {
                    // Background processes do start asap, i.e. "now"
                    $oTask->Set('next_run_date', $oNow->format('Y-m-d H:i:s'));
                }
                if ($bVerbose) {
                    $oP->p('Creating record for: ' . $sTaskClass);
                    $oP->p('First execution planned at: ' . $oTask->Get('next_run_date'));
                }
                $oTask->DBInsert();
                $aTasks[$oTask->Get('class_name')] = $oTask;
            }
            if ($aTasks[$sTaskClass]->Get('status') == 'active' && $aTasks[$sTaskClass]->Get('next_run_date') <= $oNow->format('Y-m-d H:i:s')) {
                // Run the task and record its next run time
                if ($bVerbose) {
                    $oP->p(">> === " . $oNow->format('Y-m-d H:i:s') . sprintf(" Starting:%-'=40s", ' ' . $sTaskClass . ' '));
                }
                $sMessage = RunTask($oProcess, $aTasks[$sTaskClass], $oNow, $iTimeLimit);
                if ($bVerbose) {
                    if (!empty($sMessage)) {
                        $oP->p("{$sTaskClass}: {$sMessage}");
                    }
                    $oEnd = new DateTime();
                    $oP->p("<< === " . $oEnd->format('Y-m-d H:i:s') . sprintf(" End of:  %-'=40s", ' ' . $sTaskClass . ' '));
                }
            } else {
                // will run later
                if ($aTasks[$sTaskClass]->Get('status') == 'active' && $bVerbose) {
                    $oP->p("Skipping asynchronous task: {$sTaskClass} until " . $aTasks[$sTaskClass]->Get('next_run_date'));
                }
            }
        }
        if ($bVerbose) {
            $oP->p("Sleeping");
        }
        sleep($iCronSleep);
    }
    if ($bVerbose) {
        $oP->p("Reached normal execution time limit (exceeded by " . (time() - $iTimeLimit) . "s)");
    }
}
예제 #8
0
 public static function GetDataModelSettings($aClassAliases, $bViewLink, $aDefaultLists)
 {
     $oSettings = new DataTableSettings($aClassAliases);
     // Retrieve the class specific settings for each class/alias based on the 'list' ZList
     //TODO let the caller pass some other default settings (another Zlist, extre fields...)
     $aColumns = array();
     foreach ($aClassAliases as $sAlias => $sClass) {
         if ($aDefaultLists == null) {
             $aList = cmdbAbstract::FlattenZList(MetaModel::GetZListItems($sClass, 'list'));
         } else {
             $aList = $aDefaultLists[$sAlias];
         }
         $aSortOrder = MetaModel::GetOrderByDefault($sClass);
         if ($bViewLink) {
             $sSort = 'none';
             if (array_key_exists('friendlyname', $aSortOrder)) {
                 $sSort = $aSortOrder['friendlyname'] ? 'asc' : 'desc';
             }
             $aColumns[$sAlias]['_key_'] = $oSettings->GetFieldData($sAlias, '_key_', null, true, $sSort);
         }
         foreach ($aList as $sAttCode) {
             $sSort = 'none';
             if (array_key_exists($sAttCode, $aSortOrder)) {
                 $sSort = $aSortOrder[$sAttCode] ? 'asc' : 'desc';
             }
             $oAttDef = Metamodel::GetAttributeDef($sClass, $sAttCode);
             $aFieldData = $oSettings->GetFieldData($sAlias, $sAttCode, $oAttDef, true, $sSort);
             if ($aFieldData) {
                 $aColumns[$sAlias][$sAttCode] = $aFieldData;
             }
         }
     }
     $iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
     $oSettings->Init($iDefaultPageSize, $aSortOrder, $aColumns);
     return $oSettings;
 }
예제 #9
0
    /**
     * Outputs (via some echo) the complete HTML page by assembling all its elements
     */
    public function output()
    {
        $sAbsURLAppRoot = addslashes($this->m_sRootUrl);
        //$this->set_base($this->m_sRootUrl.'pages/');
        $sForm = $this->GetSiloSelectionForm();
        $this->DisplayMenu();
        // Compute the menu
        // Call the extensions to add content to the page, so that they can also add styles or scripts
        $sBannerExtraHtml = '';
        foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) {
            $sBannerExtraHtml .= $oExtensionInstance->GetBannerHtml($this);
        }
        $sNorthPane = '';
        foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) {
            $sNorthPane .= $oExtensionInstance->GetNorthPaneHtml($this);
        }
        if (UserRights::IsAdministrator() && ExecutionKPI::IsEnabled()) {
            $sNorthPane .= '<div id="admin-banner"><span style="padding:5px;">' . ExecutionKPI::GetDescription() . '<span></div>';
        }
        //$sSouthPane = '<p>Peak memory Usage: '.sprintf('%.3f MB', memory_get_peak_usage(true) / (1024*1024)).'</p>';
        $sSouthPane = '';
        foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) {
            $sSouthPane .= $oExtensionInstance->GetSouthPaneHtml($this);
        }
        // Put here the 'ready scripts' that must be executed after all others
        $aMultiselectOptions = 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);
        $sJSMultiselectOptions = json_encode($aMultiselectOptions);
        $this->add_ready_script(<<<EOF
\t\t// Since the event is only triggered when the hash changes, we need to trigger
\t\t// the event now, to handle the hash the page may have loaded with.
\t\t\$(window).trigger( 'hashchange' );
\t\t
\t\t// Some table are sort-able, some are not, let's fix this
\t\t\$('table.listResults').each( function() { FixTableSorter(\$(this)); } );
\t\t
\t\t\$('.multiselect').multiselect({$sJSMultiselectOptions});

\t\tFixSearchFormsDisposition();

EOF
);
        if ($this->GetOutputFormat() == 'html') {
            foreach ($this->a_headers as $s_header) {
                header($s_header);
            }
        }
        $s_captured_output = $this->ob_get_clean_safe();
        $sHtml = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
        $sHtml .= "<html>\n";
        $sHtml .= "<head>\n";
        // Make sure that Internet Explorer renders the page using its latest/highest/greatest standards !
        $sHtml .= "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n";
        $sHtml .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
        $sHtml .= "<title>" . htmlentities($this->s_title, ENT_QUOTES, 'UTF-8') . "</title>\n";
        $sHtml .= $this->get_base_tag();
        // Stylesheets MUST be loaded before any scripts otherwise
        // jQuery scripts may face some spurious problems (like failing on a 'reload')
        foreach ($this->a_linked_stylesheets as $a_stylesheet) {
            if ($a_stylesheet['condition'] != "") {
                $sHtml .= "<!--[if {$a_stylesheet['condition']}]>\n";
            }
            $sHtml .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n";
            if ($a_stylesheet['condition'] != "") {
                $sHtml .= "<![endif]-->\n";
            }
        }
        // special stylesheet for printing, hides the navigation gadgets
        $sHtml .= "<link rel=\"stylesheet\" media=\"print\" type=\"text/css\" href=\"../css/print.css\" />\n";
        if ($this->GetOutputFormat() == 'html') {
            $sHtml .= $this->output_dict_entries(true);
            // before any script so that they can benefit from the translations
            foreach ($this->a_linked_scripts as $s_script) {
                // Make sure that the URL to the script contains the application's version number
                // so that the new script do NOT get reloaded from the cache when the application is upgraded
                if (strpos($s_script, '?') === false) {
                    $s_script .= "?itopversion=" . ITOP_VERSION;
                } else {
                    $s_script .= "&itopversion=" . ITOP_VERSION;
                }
                $sHtml .= "<script type=\"text/javascript\" src=\"{$s_script}\"></script>\n";
            }
            $this->add_script("var iPaneVisWatchDog  = window.setTimeout('FixPaneVis()',5000);\n\$(document).ready(function() {\n{$this->m_sInitScript};\nwindow.setTimeout('onDelayedReady()',10)\n});");
            if (count($this->m_aReadyScripts) > 0) {
                $this->add_script("\nonDelayedReady = function() {\n" . implode("\n", $this->m_aReadyScripts) . "\n}\n");
            }
            if (count($this->a_scripts) > 0) {
                $sHtml .= "<script type=\"text/javascript\">\n";
                foreach ($this->a_scripts as $s_script) {
                    $sHtml .= "{$s_script}\n";
                }
                $sHtml .= "</script>\n";
            }
        }
        if (count($this->a_styles) > 0) {
            $sHtml .= "<style>\n";
            foreach ($this->a_styles as $s_style) {
                $sHtml .= "{$s_style}\n";
            }
            $sHtml .= "</style>\n";
        }
        $sHtml .= "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"" . utils::GetAbsoluteUrlAppRoot() . "pages/opensearch.xml.php\" />\n";
        $sHtml .= "<link rel=\"shortcut icon\" href=\"" . utils::GetAbsoluteUrlAppRoot() . "images/favicon.ico\" />\n";
        $sHtml .= "</head>\n";
        $sHtml .= "<body>\n";
        // Render the revision number
        if (ITOP_REVISION == '$WCREV$') {
            // This is NOT a version built using the buil system, just display the main version
            $sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_VERSION);
        } else {
            // This is a build made from SVN, let display the full information
            $sVersionString = Dict::Format('UI:iTopVersion:Long', ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE);
        }
        // Render the text of the global search form
        $sText = htmlentities(utils::ReadParam('text', '', false, 'raw_data'), ENT_QUOTES, 'UTF-8');
        $sOnClick = "";
        if (empty($sText)) {
            // if no search text is supplied then
            // 1) the search text is filled with "your search"
            // 2) clicking on it will erase it
            $sText = Dict::S("UI:YourSearch");
            $sOnClick = " onclick=\"this.value='';this.onclick=null;\"";
        }
        // Render the tabs in the page (if any)
        $this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content);
        if ($this->GetOutputFormat() == 'html') {
            $oAppContext = new ApplicationContext();
            $sUserName = UserRights::GetUser();
            $sIsAdmin = UserRights::IsAdministrator() ? '(Administrator)' : '';
            if (UserRights::IsAdministrator()) {
                $sLogonMessage = Dict::Format('UI:LoggedAsMessage+Admin', $sUserName);
            } else {
                $sLogonMessage = Dict::Format('UI:LoggedAsMessage', $sUserName);
            }
            $sLogOffMenu = "<span id=\"logOffBtn\"><ul><li><img src=\"../images/onOffBtn.png\"><ul>";
            $sLogOffMenu .= "<li><span>{$sLogonMessage}</span></li>\n";
            $aActions = array();
            $oPrefs = new URLPopupMenuItem('UI:Preferences', Dict::S('UI:Preferences'), utils::GetAbsoluteUrlAppRoot() . "pages/preferences.php?" . $oAppContext->GetForLink());
            $aActions[$oPrefs->GetUID()] = $oPrefs->GetMenuItem();
            if (utils::CanLogOff()) {
                $oLogOff = new URLPopupMenuItem('UI:LogOffMenu', Dict::S('UI:LogOffMenu'), utils::GetAbsoluteUrlAppRoot() . 'pages/logoff.php?operation=do_logoff');
                $aActions[$oLogOff->GetUID()] = $oLogOff->GetMenuItem();
            }
            if (UserRights::CanChangePassword()) {
                $oChangePwd = new URLPopupMenuItem('UI:ChangePwdMenu', Dict::S('UI:ChangePwdMenu'), utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=change_pwd');
                $aActions[$oChangePwd->GetUID()] = $oChangePwd->GetMenuItem();
            }
            utils::GetPopupMenuItems($this, iPopupMenuExtension::MENU_USER_ACTIONS, null, $aActions);
            $oAbout = new JSPopupMenuItem('UI:AboutBox', Dict::S('UI:AboutBox'), 'return ShowAboutBox();');
            $aActions[$oAbout->GetUID()] = $oAbout->GetMenuItem();
            $sLogOffMenu .= $this->RenderPopupMenuItems($aActions);
            $sRestrictions = '';
            if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) {
                if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) {
                    $sRestrictions = Dict::S('UI:AccessRO-All');
                }
            } elseif (!MetaModel::DBHasAccess(ACCESS_USER_WRITE)) {
                $sRestrictions = Dict::S('UI:AccessRO-Users');
            }
            $sApplicationBanner = '';
            if (strlen($sRestrictions) > 0) {
                $sAdminMessage = trim(MetaModel::GetConfig()->Get('access_message'));
                $sApplicationBanner .= '<div id="admin-banner">';
                $sApplicationBanner .= '<img src="../images/locked.png" style="vertical-align:middle;">';
                $sApplicationBanner .= '&nbsp;<b>' . $sRestrictions . '</b>';
                if (strlen($sAdminMessage) > 0) {
                    $sApplicationBanner .= '&nbsp;<b>' . $sAdminMessage . '</b>';
                }
                $sApplicationBanner .= '</div>';
            }
            if (strlen($this->m_sMessage)) {
                $sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">' . $this->m_sMessage . '<span></div>';
            }
            $sApplicationBanner .= $sBannerExtraHtml;
            if (!empty($sNorthPane)) {
                $sNorthPane = '<div id="bottom-pane" class="ui-layout-north">' . $sNorthPane . '</div>';
            }
            if (!empty($sSouthPane)) {
                $sSouthPane = '<div id="bottom-pane" class="ui-layout-south">' . $sSouthPane . '</div>';
            }
            $sIconUrl = Utils::GetConfig()->Get('app_icon_url');
            $sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help');
            //$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>";
            $sDisplayIcon = utils::GetAbsoluteUrlAppRoot() . 'images/itop-logo.png';
            if (file_exists(MODULESROOT . 'branding/main-logo.png')) {
                $sDisplayIcon = utils::GetAbsoluteUrlModulesRoot() . 'branding/main-logo.png';
            }
            $sHtml .= $sNorthPane;
            $sHtml .= '<div id="left-pane" class="ui-layout-west">';
            $sHtml .= '<!-- Beginning of the left pane -->';
            $sHtml .= ' <div class="ui-layout-north">';
            $sHtml .= ' <div id="header-logo">';
            $sHtml .= ' <div id="top-left"></div><div id="logo"><a href="' . htmlentities($sIconUrl, ENT_QUOTES, 'UTF-8') . '"><img src="' . $sDisplayIcon . '" title="' . htmlentities($sVersionString, ENT_QUOTES, 'UTF-8') . '" style="border:0; margin-top:16px; margin-right:40px;"/></a></div>';
            $sHtml .= ' </div>';
            $sHtml .= ' <div class="header-menu">';
            if (!MetaModel::GetConfig()->Get('demo_mode')) {
                $sHtml .= '		<div class="icon ui-state-default ui-corner-all"><span id="tPinMenu" class="ui-icon ui-icon-pin-w">pin</span></div>';
            }
            $sHtml .= '		<div style="text-align:center;">' . self::FilterXSS($sForm) . '</div>';
            $sHtml .= ' </div>';
            $sHtml .= ' </div>';
            $sHtml .= ' <div id="menu" class="ui-layout-center">';
            $sHtml .= '		<div id="inner_menu">';
            $sHtml .= '			<div id="accordion">';
            $sHtml .= self::FilterXSS($this->m_sMenu);
            $sHtml .= '			<!-- Beginning of the accordion menu -->';
            $sHtml .= '			<!-- End of the accordion menu-->';
            $sHtml .= '			</div>';
            $sHtml .= '		</div> <!-- /inner menu -->';
            $sHtml .= ' </div> <!-- /menu -->';
            $sHtml .= ' <div class="footer ui-layout-south"><div id="combodo_logo"><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logo-combodo.png"/></a></div></div>';
            $sHtml .= '<!-- End of the left pane -->';
            $sHtml .= '</div>';
            $sHtml .= '<div class="ui-layout-center">';
            $sHtml .= ' <div id="top-bar" style="width:100%">';
            $sHtml .= self::FilterXSS($sApplicationBanner);
            $sHtml .= '		<div id="global-search"><form action="' . utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php"><table><tr><td></td><td id="g-search-input"><input type="text" name="text" value="' . $sText . '"' . $sOnClick . '/></td>';
            $sHtml .= '<td><input type="image" src="../images/searchBtn.png"/></a></td>';
            $sHtml .= '<td><a style="background:transparent;" href="' . $sOnlineHelpUrl . '" target="_blank"><img style="border:0;padding-left:20px;padding-right:10px;" title="' . Dict::S('UI:Help') . '" src="../images/help.png"/></td>';
            $sHtml .= '<td style="padding-right:20px;padding-left:10px;">' . self::FilterXSS($sLogOffMenu) . '</td><td><input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>';
            //echo '<td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>';
            $sHtml .= ' </div>';
            $sHtml .= ' <div class="ui-layout-content" style="overflow:auto;">';
            $sHtml .= ' <!-- Beginning of page content -->';
            $sHtml .= self::FilterXSS($this->s_content);
            $sHtml .= ' <!-- End of page content -->';
            $sHtml .= ' </div>';
            $sHtml .= '</div>';
            $sHtml .= $sSouthPane;
            // Add the captured output
            if (trim($s_captured_output) != "") {
                $sHtml .= "<div id=\"rawOutput\" title=\"Debug Output\"><div style=\"height:500px; overflow-y:auto;\">" . self::FilterXSS($s_captured_output) . "</div></div>\n";
            }
            $sHtml .= "<div id=\"at_the_end\">" . self::FilterXSS($this->s_deferred_content) . "</div>";
            $sHtml .= "<div style=\"display:none\" title=\"ex2\" id=\"ex2\">Please wait...</div>\n";
            // jqModal Window
            $sHtml .= "<div style=\"display:none\" title=\"dialog\" id=\"ModalDlg\"></div>";
            $sHtml .= "<div style=\"display:none\" id=\"ajax_content\"></div>";
        } else {
            $sHtml .= self::FilterXSS($this->s_content);
        }
        $sHtml .= "</body>\n";
        $sHtml .= "</html>\n";
        if ($this->GetOutputFormat() == 'html') {
            $oKPI = new ExecutionKPI();
            echo $sHtml;
            $oKPI->ComputeAndReport('Echoing (' . round(strlen($sHtml) / 1024) . ' Kb)');
        } else {
            if ($this->GetOutputFormat() == 'pdf' && $this->IsOutputFormatAvailable('pdf')) {
                if (@is_readable(APPROOT . 'lib/MPDF/mpdf.php')) {
                    require_once APPROOT . 'lib/MPDF/mpdf.php';
                    $oMPDF = new mPDF('c');
                    $oMPDF->mirroMargins = false;
                    if ($this->a_base['href'] != '') {
                        $oMPDF->setBasePath($this->a_base['href']);
                        // Seems that the <BASE> tag is not recognized by mPDF...
                    }
                    $oMPDF->showWatermarkText = true;
                    if ($this->GetOutputOption('pdf', 'template_path')) {
                        $oMPDF->setImportUse();
                        // Allow templates
                        $oMPDF->SetDocTemplate($this->GetOutputOption('pdf', 'template_path'), 1);
                    }
                    $oMPDF->WriteHTML($sHtml);
                    $sOutputName = $this->s_title . '.pdf';
                    if ($this->GetOutputOption('pdf', 'output_name')) {
                        $sOutputName = $this->GetOutputOption('pdf', 'output_name');
                    }
                    $oMPDF->Output($sOutputName, 'I');
                }
            }
        }
        DBSearch::RecordQueryTrace();
        ExecutionKPI::ReportStats();
    }
예제 #10
0
 public function Send(&$aIssues, $bForceSynchronous = false, $oLog = null)
 {
     if ($bForceSynchronous) {
         return $this->SendSynchronous($aIssues, $oLog);
     } else {
         $bConfigASYNC = MetaModel::GetConfig()->Get('email_asynchronous');
         if ($bConfigASYNC) {
             return $this->SendAsynchronous($aIssues, $oLog);
         } else {
             return $this->SendSynchronous($aIssues, $oLog);
         }
     }
 }
예제 #11
0
 public static function ReportStats()
 {
     if (!self::IsEnabled()) {
         return;
     }
     global $fItopStarted;
     $sExecId = microtime();
     // id to differentiate the hrefs!
     $aBeginTimes = array();
     foreach (self::$m_aExecData as $aOpStats) {
         $aBeginTimes[] = $aOpStats['time_begin'];
     }
     array_multisort($aBeginTimes, self::$m_aExecData);
     $sTableStyle = 'background-color: #ccc; margin: 10px;';
     self::Report("<hr/>");
     self::Report("<div style=\"background-color: grey; padding: 10px;\">");
     self::Report("<h3><a name=\"" . md5($sExecId) . "\">KPIs</a> - " . $_SERVER['REQUEST_URI'] . " (" . $_SERVER['REQUEST_METHOD'] . ")</h3>");
     self::Report("<p>" . date('Y-m-d H:i:s', $fItopStarted) . "</p>");
     self::Report("<p>log_kpi_user_id: " . MetaModel::GetConfig()->Get('log_kpi_user_id') . "</p>");
     self::Report("<div>");
     self::Report("<table border=\"1\" style=\"{$sTableStyle}\">");
     self::Report("<thead>");
     self::Report("   <th>Operation</th><th>Begin</th><th>End</th><th>Duration</th><th>Memory start</th><th>Memory end</th><th>Memory peak</th>");
     self::Report("</thead>");
     foreach (self::$m_aExecData as $aOpStats) {
         $sOperation = $aOpStats['op'];
         $sBegin = $sEnd = $sDuration = $sMemBegin = $sMemEnd = $sMemPeak = '?';
         $sBegin = round($aOpStats['time_begin'], 3);
         $sEnd = round($aOpStats['time_end'], 3);
         $fDuration = $aOpStats['time_end'] - $aOpStats['time_begin'];
         $sDuration = round($fDuration, 3);
         if (isset($aOpStats['mem_begin'])) {
             $sMemBegin = self::MemStr($aOpStats['mem_begin']);
             $sMemEnd = self::MemStr($aOpStats['mem_end']);
             if (isset($aOpStats['mem_peak'])) {
                 $sMemPeak = self::MemStr($aOpStats['mem_peak']);
             }
         }
         self::Report("<tr>");
         self::Report("   <td>{$sOperation}</td><td>{$sBegin}</td><td>{$sEnd}</td><td>{$sDuration}</td><td>{$sMemBegin}</td><td>{$sMemEnd}</td><td>{$sMemPeak}</td>");
         self::Report("</tr>");
     }
     self::Report("</table>");
     self::Report("</div>");
     $aConsolidatedStats = array();
     foreach (self::$m_aStats as $sOperation => $aOpStats) {
         $fTotalOp = 0;
         $iTotalOp = 0;
         $fMinOp = null;
         $fMaxOp = 0;
         $sMaxOpArguments = null;
         foreach ($aOpStats as $sArguments => $aEvents) {
             foreach ($aEvents as $aEventData) {
                 $fDuration = $aEventData['time'];
                 $fTotalOp += $fDuration;
                 $iTotalOp++;
                 $fMinOp = is_null($fMinOp) ? $fDuration : min($fMinOp, $fDuration);
                 if ($fDuration > $fMaxOp) {
                     $sMaxOpArguments = $sArguments;
                     $fMaxOp = $fDuration;
                 }
             }
         }
         $aConsolidatedStats[$sOperation] = array('count' => $iTotalOp, 'duration' => $fTotalOp, 'min' => $fMinOp, 'max' => $fMaxOp, 'avg' => $fTotalOp / $iTotalOp, 'max_args' => $sMaxOpArguments);
     }
     self::Report("<div>");
     self::Report("<table border=\"1\" style=\"{$sTableStyle}\">");
     self::Report("<thead>");
     self::Report("   <th>Operation</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th><th>Avg</th>");
     self::Report("</thead>");
     foreach ($aConsolidatedStats as $sOperation => $aOpStats) {
         $sOperation = '<a href="#' . md5($sExecId . $sOperation) . '">' . $sOperation . '</a>';
         $sCount = $aOpStats['count'];
         $sDuration = round($aOpStats['duration'], 3);
         $sMin = round($aOpStats['min'], 3);
         $sMax = '<a href="#' . md5($sExecId . $aOpStats['max_args']) . '">' . round($aOpStats['max'], 3) . '</a>';
         $sAvg = round($aOpStats['avg'], 3);
         self::Report("<tr>");
         self::Report("   <td>{$sOperation}</td><td>{$sCount}</td><td>{$sDuration}</td><td>{$sMin}</td><td>{$sMax}</td><td>{$sAvg}</td>");
         self::Report("</tr>");
     }
     self::Report("</table>");
     self::Report("</div>");
     self::Report("</div>");
     // Report operation details
     foreach (self::$m_aStats as $sOperation => $aOpStats) {
         $sOperationHtml = '<a name="' . md5($sExecId . $sOperation) . '">' . $sOperation . '</a>';
         self::Report("<h4>{$sOperationHtml}</h4>");
         self::Report("<p><a href=\"#" . md5($sExecId) . "\">Back to page stats</a></p>");
         self::Report("<table border=\"1\" style=\"{$sTableStyle}\">");
         self::Report("<thead>");
         self::Report("   <th>Operation details (+ blame caller if log_kpi_duration = 2)</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th>");
         self::Report("</thead>");
         foreach ($aOpStats as $sArguments => $aEvents) {
             $sHtmlArguments = '<a name="' . md5($sExecId . $sArguments) . '"><div style="white-space: pre-wrap;">' . $sArguments . '</div></a>';
             if ($aConsolidatedStats[$sOperation]['max_args'] == $sArguments) {
                 $sHtmlArguments = '<span style="color: red;">' . $sHtmlArguments . '</span>';
             }
             if (isset($aEvents[0]['callers'])) {
                 $sHtmlArguments .= '<div style="padding: 10px;">';
                 $sHtmlArguments .= '<table border="1" bgcolor="#cfc">';
                 $sHtmlArguments .= '<tr><td colspan="2" bgcolor="#e9b96">Call stack for the <b>FIRST</b> caller</td></tr>';
                 foreach ($aEvents[0]['callers'] as $aCall) {
                     $sHtmlArguments .= '<tr>';
                     $sHtmlArguments .= '<td>' . $aCall['Function'] . '</td>';
                     $sHtmlArguments .= '<td>' . $aCall['File'] . ':' . $aCall['Line'] . '</td>';
                     $sHtmlArguments .= '</tr>';
                 }
                 $sHtmlArguments .= '</table>';
                 $sHtmlArguments .= '</div>';
             }
             $fTotalInter = 0;
             $fMinInter = null;
             $fMaxInter = 0;
             foreach ($aEvents as $aEventData) {
                 $fDuration = $aEventData['time'];
                 $fTotalInter += $fDuration;
                 $fMinInter = is_null($fMinInter) ? $fDuration : min($fMinInter, $fDuration);
                 $fMaxInter = max($fMaxInter, $fDuration);
             }
             $iCountInter = count($aEvents);
             $sTotalInter = round($fTotalInter, 3);
             $sMinInter = round($fMinInter, 3);
             $sMaxInter = round($fMaxInter, 3);
             self::Report("<tr>");
             self::Report("   <td>{$sHtmlArguments}</td><td>{$iCountInter}</td><td>{$sTotalInter}</td><td>{$sMinInter}</td><td>{$sMaxInter}</td>");
             self::Report("</tr>");
         }
         self::Report("</table>");
     }
 }
예제 #12
0
 public function CreateZip($sZipFile, $sSourceConfigFile = null)
 {
     // Note: the file is created by tempnam and might not be writeable by another process (Windows/IIS)
     // (delete it before spawning a process)
     $sDataFile = tempnam(SetupUtils::GetTmpDir(), 'itop-');
     $this->LogInfo("Data file: '{$sDataFile}'");
     $aContents = array();
     $aContents[] = array('source' => $sDataFile, 'dest' => 'itop-dump.sql');
     if (is_null($sSourceConfigFile)) {
         $sSourceConfigFile = MetaModel::GetConfig()->GetLoadedFile();
     }
     if (!empty($sSourceConfigFile)) {
         $aContents[] = array('source' => $sSourceConfigFile, 'dest' => 'config-itop.php');
     }
     $this->DoBackup($sDataFile);
     $sDeltaFile = APPROOT . 'data/' . utils::GetCurrentEnvironment() . '.delta.xml';
     if (file_exists($sDeltaFile)) {
         $aContents[] = array('source' => $sDeltaFile, 'dest' => 'delta.xml');
     }
     $sExtraDir = APPROOT . 'data/' . utils::GetCurrentEnvironment() . '-modules/';
     if (is_dir($sExtraDir)) {
         $aContents[] = array('source' => $sExtraDir, 'dest' => utils::GetCurrentEnvironment() . '-modules/');
     }
     $this->DoZip($aContents, $sZipFile);
     // Windows/IIS: the data file has been created by the spawned process...
     //   trying to delete it will issue a warning, itself stopping the setup abruptely
     @unlink($sDataFile);
 }
예제 #13
0
 private function MakeDeletionPlan(&$oDeletionPlan, $aVisited = array(), $iDeleteOption = null)
 {
     static $iLoopTimeLimit = null;
     if ($iLoopTimeLimit == null) {
         $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
     }
     $sClass = get_class($this);
     $iThisId = $this->GetKey();
     $iDeleteOption = $oDeletionPlan->AddToDelete($this, $iDeleteOption);
     if (array_key_exists($sClass, $aVisited)) {
         if (in_array($iThisId, $aVisited[$sClass])) {
             return;
         }
     }
     $aVisited[$sClass] = $iThisId;
     if ($iDeleteOption == DEL_MANUAL) {
         // Stop the recursion here
         return;
     }
     // Check the node itself
     $this->DoCheckToDelete($oDeletionPlan);
     $oDeletionPlan->SetDeletionIssues($this, $this->m_aDeleteIssues, $this->m_bSecurityIssue);
     $aDependentObjects = $this->GetReferencingObjects(true);
     // Getting and setting time limit are not symetric:
     // www.php.net/manual/fr/function.set-time-limit.php#72305
     $iPreviousTimeLimit = ini_get('max_execution_time');
     foreach ($aDependentObjects as $sRemoteClass => $aPotentialDeletes) {
         foreach ($aPotentialDeletes as $sRemoteExtKey => $aData) {
             set_time_limit($iLoopTimeLimit);
             $oAttDef = $aData['attribute'];
             $iDeletePropagationOption = $oAttDef->GetDeletionPropagationOption();
             $oDepSet = $aData['objects'];
             $oDepSet->Rewind();
             while ($oDependentObj = $oDepSet->fetch()) {
                 $iId = $oDependentObj->GetKey();
                 if ($oAttDef->IsNullAllowed()) {
                     // Optional external key, list to reset
                     if ($iDeletePropagationOption == DEL_MOVEUP && $oAttDef->IsHierarchicalKey()) {
                         // Move the child up one level i.e. set the same parent as the current object
                         $iParentId = $this->Get($oAttDef->GetCode());
                         $oDeletionPlan->AddToUpdate($oDependentObj, $oAttDef, $iParentId);
                     } else {
                         $oDeletionPlan->AddToUpdate($oDependentObj, $oAttDef);
                     }
                 } else {
                     // Mandatory external key, list to delete
                     $oDependentObj->MakeDeletionPlan($oDeletionPlan, $aVisited, $iDeletePropagationOption);
                 }
             }
         }
     }
     set_time_limit($iPreviousTimeLimit);
 }
예제 #14
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;
 }
예제 #15
0
 // Build the ordered list of classes to search into
 //
 if (empty($sClassName)) {
     $aSearchClasses = MetaModel::GetClasses('searchable');
 } else {
     // Search is limited to a given class and its subclasses
     $aSearchClasses = MetaModel::EnumChildClasses($sClassName, ENUM_CHILD_CLASSES_ALL);
 }
 // Skip abstract classes, since we search in all the child classes anyway
 foreach ($aSearchClasses as $idx => $sClass) {
     if (MetaModel::IsAbstract($sClass)) {
         unset($aSearchClasses[$idx]);
     }
 }
 $sMaxChunkDuration = MetaModel::GetConfig()->Get('full_text_chunk_duration');
 $aAccelerators = MetaModel::GetConfig()->Get('full_text_accelerators');
 foreach (array_reverse($aAccelerators) as $sClass => $aRestriction) {
     $bSkip = false;
     $iPos = array_search($sClass, $aSearchClasses);
     if ($iPos !== false) {
         unset($aSearchClasses[$iPos]);
     } else {
         $bSkip = true;
     }
     $bSkip |= array_key_exists('skip', $aRestriction) ? $aRestriction['skip'] : false;
     if (!in_array($sClass, $aSearchClasses)) {
         if ($sClass == $sClassName) {
             // Class explicitely requested, do NOT skip it
             // beware: there may not be a 'query' defined for a skipped class !
             $bSkip = false;
         }
예제 #16
0
 /**
  * Applies the defined parameters into the SQL query
  * @return string the SQL query to execute
  */
 public function BuildQuery()
 {
     $oAppContext = new ApplicationContext();
     $sQuery = $this->m_sQuery;
     $sQuery = str_replace('$DB_PREFIX$', MetaModel::GetConfig()->GetDBSubname(), $sQuery);
     // put the tables DB prefix (if any)
     foreach ($this->m_aParams as $sName => $aParam) {
         if ($aParam['type'] == 'context') {
             $sSearchPattern = '/\\$CONDITION\\(' . $sName . ',([^\\)]+)\\)\\$/';
             $value = $oAppContext->GetCurrentValue($aParam['mapping']);
             if (empty($value)) {
                 $sSQLExpr = '(1)';
             } else {
                 // Special case for managing the hierarchy of organizations
                 if ($aParam['mapping'] == 'org_id' && MetaModel::IsValidClass('Organization')) {
                     $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
                     if ($sHierarchicalKeyCode != false) {
                         // organizations are in hierarchy... gather all the orgs below the given one...
                         $sOQL = "SELECT Organization AS node JOIN Organization AS root ON node.{$sHierarchicalKeyCode} BELOW root.id WHERE root.id = :value";
                         $oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('value' => $value));
                         $aOrgIds = array();
                         while ($oOrg = $oSet->Fetch()) {
                             $aOrgIds[] = $oOrg->GetKey();
                         }
                         $sSQLExpr = '($1 IN(' . implode(',', $aOrgIds) . '))';
                     } else {
                         $sSQLExpr = '($1 = ' . CMDBSource::Quote($value) . ')';
                     }
                 } else {
                     $sSQLExpr = '($1 = ' . CMDBSource::Quote($value) . ')';
                 }
             }
             $sQuery = preg_replace($sSearchPattern, $sSQLExpr, $sQuery);
         }
     }
     return $sQuery;
 }
예제 #17
0
파일: audit.php 프로젝트: henryavila/itop
 // Therefore we don't use the standard "search_oql" operation of UI.php to display the CSV
 $iCategory = utils::ReadParam('category', '');
 $iRuleIndex = utils::ReadParam('rule', 0);
 $oAuditCategory = MetaModel::GetObject('AuditCategory', $iCategory);
 $oDefinitionFilter = DBObjectSearch::FromOQL($oAuditCategory->Get('definition_set'));
 FilterByContext($oDefinitionFilter, $oAppContext);
 $oDefinitionSet = new CMDBObjectSet($oDefinitionFilter);
 $oFilter = GetRuleResultFilter($iRuleIndex, $oDefinitionFilter, $oAppContext);
 $oErrorObjectSet = new CMDBObjectSet($oFilter);
 $oAuditRule = MetaModel::GetObject('AuditRule', $iRuleIndex);
 $sFileName = utils::ReadParam('filename', null, true, 'string');
 $bAdvanced = utils::ReadParam('advanced', false);
 $sAdvanced = $bAdvanced ? '&advanced=1' : '';
 if ($sFileName != null) {
     $oP = new CSVPage("iTop - Export");
     $sCharset = MetaModel::GetConfig()->Get('csv_file_default_charset');
     $sCSVData = cmdbAbstractObject::GetSetAsCSV($oErrorObjectSet, array('localize_values' => true, 'fields_advanced' => $bAdvanced), $sCharset);
     if ($sCharset == 'UTF-8') {
         $sOutputData = UTF8_BOM . $sCSVData;
     } else {
         $sOutputData = $sCSVData;
     }
     if ($sFileName == '') {
         // Plain text => Firefox will NOT propose to download the file
         $oP->add_header("Content-type: text/plain; charset={$sCharset}");
     } else {
         $oP->add_header("Content-type: text/csv; charset={$sCharset}");
     }
     $oP->add($sOutputData);
     $oP->TrashUnexpectedOutput();
     $oP->output();
예제 #18
0
 public function GetNextChunk(&$aStatus)
 {
     $sRetCode = 'run';
     $iPercentage = 0;
     $oSet = new DBObjectSet($this->oSearch);
     $aSelectedClasses = $this->oSearch->GetSelectedClasses();
     $aAliases = array_keys($aSelectedClasses);
     $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']);
     $aAliasByField = array();
     $aColumnsToLoad = array();
     // Prepare the list of aliases / columns to load
     foreach ($this->aStatusInfo['fields'] as $sExtendedAttCode) {
         if (preg_match('/^([^\\.]+)\\.(.+)$/', $sExtendedAttCode, $aMatches)) {
             $sAlias = $aMatches[1];
             $sAttCode = $aMatches[2];
         } else {
             $sAlias = reset($aAliases);
             $sAttCode = $sExtendedAttCode;
         }
         if (!in_array($sAlias, $aAliases)) {
             throw new Exception("Invalid alias '{$sAlias}' for the column '{$sExtendedAttCode}'. Availables aliases: '" . implode("', '", $aAliases) . "'");
         }
         if (!array_key_exists($sAlias, $aColumnsToLoad)) {
             $aColumnsToLoad[$sAlias] = array();
         }
         if ($sAttCode != 'id') {
             // id is not a real attribute code and, moreover, is always loaded
             $aColumnsToLoad[$sAlias][] = $sAttCode;
         }
         $aAliasByField[$sExtendedAttCode] = array('alias' => $sAlias, 'attcode' => $sAttCode);
     }
     $iCount = 0;
     $sData = '';
     $oSet->OptimizeColumnLoad($aColumnsToLoad);
     $iPreviousTimeLimit = ini_get('max_execution_time');
     $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
     while ($aRow = $oSet->FetchAssoc()) {
         set_time_limit($iLoopTimeLimit);
         $sFirstAlias = reset($aAliases);
         $sHilightClass = $aRow[$sFirstAlias]->GetHilightClass();
         if ($sHilightClass != '') {
             $sData .= "<tr class=\"{$sHilightClass}\">";
         } else {
             $sData .= "<tr>";
         }
         foreach ($aAliasByField as $aAttCode) {
             $sField = '';
             switch ($aAttCode['attcode']) {
                 case 'id':
                     $sField = $aRow[$aAttCode['alias']]->GetHyperlink();
                     break;
                 default:
                     $sField = $aRow[$aAttCode['alias']]->GetAsHtml($aAttCode['attcode']);
             }
             $sValue = $sField === '' ? '&nbsp;' : $sField;
             $sData .= "<td>{$sValue}</td>";
         }
         $sData .= "</tr>";
         $iCount++;
     }
     set_time_limit($iPreviousTimeLimit);
     $this->aStatusInfo['position'] += $this->iChunkSize;
     if ($this->aStatusInfo['total'] == 0) {
         $iPercentage = 100;
     } else {
         $iPercentage = floor(min(100.0, 100.0 * $this->aStatusInfo['position'] / $this->aStatusInfo['total']));
     }
     if ($iCount < $this->iChunkSize) {
         $sRetCode = 'done';
     }
     $aStatus = array('code' => $sRetCode, 'message' => Dict::S('Core:BulkExport:RetrievingData'), 'percentage' => $iPercentage);
     return $sData;
 }
예제 #19
0
}
if ($bPortal) {
    $sUrl .= 'portal/';
} else {
    $sUrl .= 'pages/UI.php';
}
if (isset($_SESSION['auth_user'])) {
    $sAuthUser = $_SESSION['auth_user'];
    UserRights::Login($sAuthUser);
    // Set the user's language
}
$sLoginMode = isset($_SESSION['login_mode']) ? $_SESSION['login_mode'] : '';
LoginWebPage::ResetSession();
switch ($sLoginMode) {
    case 'cas':
        $sCASLogoutUrl = MetaModel::GetConfig()->Get('cas_logout_redirect_service');
        if (empty($sCASLogoutUrl)) {
            $sCASLogoutUrl = $sUrl;
        }
        utils::InitCASClient();
        phpCAS::logoutWithRedirectService($sCASLogoutUrl);
        // Redirects to the CAS logout page
        break;
}
$oPage = LoginWebPage::NewLoginWebPage();
$oPage->no_cache();
$oPage->DisplayLoginHeader();
$oPage->add("<div id=\"login\">\n");
$oPage->add("<h1>" . Dict::S('UI:LogOff:ThankYou') . "</h1>\n");
$oPage->add("<p><a href=\"{$sUrl}\">" . Dict::S('UI:LogOff:ClickHereToLoginAgain') . "</a></p>");
$oPage->add("</div>\n");
 /**
  * Returns the set of flags (OPT_ATT_HIDDEN, OPT_ATT_READONLY, OPT_ATT_MANDATORY...)
  * for the given attribute in the current state of the object
  * @param $sAttCode string $sAttCode The code of the attribute
  * @param $aReasons array To store the reasons why the attribute is read-only (info about the synchro replicas)
  * @param $sTargetState string The target state in which to evalutate the flags, if empty the current state will be used
  * @return integer Flags: the binary combination of the flags applicable to this attribute
  */
 public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState = '')
 {
     $iFlags = parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
     if (MetaModel::GetConfig()->Get('demo_mode')) {
         $aReasons[] = 'Sorry, profiles are read-only in the demonstration mode!';
         $iFlags |= OPT_ATT_READONLY;
     }
     return $iFlags;
 }
예제 #21
0
 public function GetMaxRetries()
 {
     $iMaxRetries = 0;
     $aRetries = MetaModel::GetConfig()->Get('async_task_retries', array());
     if (is_array($aRetries) && array_key_exists(get_class($this), $aRetries)) {
         $aConfig = $aRetries[get_class($this)];
         $iMaxRetries = $aConfig['max_retries'];
     }
 }
    /**
     * Generates the javascript code handle the "watchdog" associated with the concurrent access locking mechanism
     * @param Webpage $oPage
     * @param string $sOwnershipToken
     */
    protected function GetOwnershipJSHandler($oPage, $sOwnershipToken)
    {
        $iInterval = max(MIN_WATCHDOG_INTERVAL, MetaModel::GetConfig()->Get('concurrent_lock_expiration_delay')) * 1000 / 2;
        // Minimum interval for the watchdog is MIN_WATCHDOG_INTERVAL
        $sJSClass = json_encode(get_class($this));
        $iKey = (int) $this->GetKey();
        $sJSToken = json_encode($sOwnershipToken);
        $sJSTitle = json_encode(Dict::S('UI:DisconnectedDlgTitle'));
        $sJSOk = json_encode(Dict::S('UI:Button:Ok'));
        $oPage->add_ready_script(<<<EOF
\t\twindow.setInterval(function() {
\t\t\tif (window.bInSubmit || window.bInCancel) return;
\t\t\t
\t\t\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'extend_lock', obj_class: {$sJSClass}, obj_key: {$iKey}, token: {$sJSToken} }, function(data) {
\t\t\t\tif (!data.status)
\t\t\t\t{
\t\t\t\t\tif (\$('.lock_owned').length == 0)
\t\t\t\t\t{
\t\t\t\t\t\t\$('.ui-layout-content').prepend('<div class="header_message message_error lock_owned">'+data.message+'</div>');
\t\t\t\t\t\t\$('<div>'+data.popup_message+'</div>').dialog({title: {$sJSTitle}, modal: true, autoOpen: true, buttons:[ {text: {$sJSOk}, click: function() { \$(this).dialog('close'); } }], close: function() { \$(this).remove(); }});
\t\t\t\t\t}
\t\t\t\t\t\$('.wizContainer form button.action:not(.cancel)').attr('disabled', 'disabled');
\t\t\t\t}
\t\t\t\telse if ((data.operation == 'lost') || (data.operation == 'expired'))
\t\t\t\t{
\t\t\t\t\tif (\$('.lock_owned').length == 0)
\t\t\t\t\t{
\t\t\t\t\t\t\$('.ui-layout-content').prepend('<div class="header_message message_error lock_owned">'+data.message+'</div>');
\t\t\t\t\t\t\$('<div>'+data.popup_message+'</div>').dialog({title: {$sJSTitle}, modal: true, autoOpen: true, buttons:[ {text: {$sJSOk}, click: function() { \$(this).dialog('close'); } }], close: function() { \$(this).remove(); }});
\t\t\t\t\t}
\t\t\t\t\t\$('.wizContainer form button.action:not(.cancel)').attr('disabled', 'disabled');
\t\t\t\t}
\t\t\t}, 'json');
\t\t}, {$iInterval});
EOF
);
    }
 protected static function Write($sText)
 {
     $bLogEnabled = MetaModel::GetConfig()->Get('log_transactions');
     if ($bLogEnabled) {
         $hLogFile = @fopen(APPROOT . 'log/transactions.log', 'a');
         if ($hLogFile !== false) {
             flock($hLogFile, LOCK_EX);
             $sDate = date('Y-m-d H:i:s');
             fwrite($hLogFile, "{$sDate} | {$sText}\n");
             fflush($hLogFile);
             flock($hLogFile, LOCK_UN);
             fclose($hLogFile);
         }
     }
 }
예제 #24
0
        }
    }
}
/////////////////////////////////////////////////////////////////////
// Main program
//
LoginWebPage::DoLogin(true);
// Check user rights and prompt if needed (must be admin)
//$sOperation = utils::ReadParam('operation', 'menu');
//$oAppContext = new ApplicationContext();
$oP = new iTopWebPage(Dict::S('config-edit-title'));
$oP->set_base(utils::GetAbsoluteUrlAppRoot() . 'pages/');
try {
    $sOperation = utils::ReadParam('operation', '');
    $oP->add("<h1>" . Dict::S('config-edit-title') . "</h1>");
    if (MetaModel::GetConfig()->Get('demo_mode')) {
        $oP->add("<div class=\"header_message message_info\">Sorry, iTop is in <b>demonstration mode</b>: the configuration file cannot be edited.</div>");
    } else {
        $oP->add_style(<<<EOF
textarea {
\t-webkit-box-sizing: border-box;
\t-moz-box-sizing: border-box;
\tbox-sizing: border-box;

\twidth: 100%;
\theight: 550px;
}
.current_line {
\tdisplay: none;
\tmargin-left: 20px;
}
 protected static function HandleOperations($operation)
 {
     $sMessage = '';
     // most of the operations never return, but some can return a message to be displayed
     if ($operation == 'logoff') {
         if (isset($_SESSION['login_mode'])) {
             $sLoginMode = $_SESSION['login_mode'];
         } else {
             $aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes();
             if (count($aAllowedLoginTypes) > 0) {
                 $sLoginMode = $aAllowedLoginTypes[0];
             } else {
                 $sLoginMode = 'form';
             }
         }
         self::ResetSession();
         $oPage = self::NewLoginWebPage();
         $oPage->DisplayLoginForm($sLoginMode, false);
         $oPage->output();
         exit;
     } else {
         if ($operation == 'forgot_pwd') {
             $oPage = self::NewLoginWebPage();
             $oPage->DisplayForgotPwdForm();
             $oPage->output();
             exit;
         } else {
             if ($operation == 'forgot_pwd_go') {
                 $oPage = self::NewLoginWebPage();
                 $oPage->ForgotPwdGo();
                 $oPage->output();
                 exit;
             } else {
                 if ($operation == 'reset_pwd') {
                     $oPage = self::NewLoginWebPage();
                     $oPage->DisplayResetPwdForm();
                     $oPage->output();
                     exit;
                 } else {
                     if ($operation == 'do_reset_pwd') {
                         $oPage = self::NewLoginWebPage();
                         $oPage->DoResetPassword();
                         $oPage->output();
                         exit;
                     } else {
                         if ($operation == 'change_pwd') {
                             $sAuthUser = $_SESSION['auth_user'];
                             UserRights::Login($sAuthUser);
                             // Set the user's language
                             $oPage = self::NewLoginWebPage();
                             $oPage->DisplayChangePwdForm();
                             $oPage->output();
                             exit;
                         }
                     }
                 }
             }
         }
     }
     if ($operation == 'do_change_pwd') {
         $sAuthUser = $_SESSION['auth_user'];
         UserRights::Login($sAuthUser);
         // Set the user's language
         $sOldPwd = utils::ReadPostedParam('old_pwd', '', false, 'raw_data');
         $sNewPwd = utils::ReadPostedParam('new_pwd', '', false, 'raw_data');
         if (UserRights::CanChangePassword() && (!UserRights::CheckCredentials($sAuthUser, $sOldPwd) || !UserRights::ChangePassword($sOldPwd, $sNewPwd))) {
             $oPage = self::NewLoginWebPage();
             $oPage->DisplayChangePwdForm(true);
             // old pwd was wrong
             $oPage->output();
             exit;
         }
         $sMessage = Dict::S('UI:Login:PasswordChanged');
     }
     return $sMessage;
 }
 /**
  * Get the context definitions from the parameters / configuration. The format of the "key" string is:
  * <module>/relation_context/<class>/<relation>/<direction>
  * The values will be retrieved for the given class and all its parents and merged together as a single array.
  * Entries with an invalid query are removed from the list.
  * @param string $sContextKey The key to fetch the queries in the configuration. Example: itop-tickets/relation_context/UserRequest/impacts/down
  * @param bool $bDevelopParams Whether or not to substitute the parameters inside the queries with the supplied "context params"
  * @param array $aContextParams Arguments for the queries (via ToArgs()) if $bDevelopParams == true
  * @return multitype:multitype:string
  */
 public static function GetContextDefinitions($sContextKey, $bDevelopParams = true, $aContextParams = array())
 {
     $aContextDefs = array();
     $aLevels = explode('/', $sContextKey);
     if (count($aLevels) < 5) {
         IssueLog::Warning("GetContextDefinitions: invalid 'sContextKey' = '{$sContextKey}'. 5 levels of / are expected !");
     } else {
         $sLeafClass = $aLevels[2];
         if (!MetaModel::IsValidClass($sLeafClass)) {
             IssueLog::Warning("GetContextDefinitions: invalid 'sLeafClass' = '{$sLeafClass}'. A valid class name is expected in 3rd position inside '{$sContextKey}' !");
         } else {
             $aRelationContext = MetaModel::GetConfig()->GetModuleSetting($aLevels[0], $aLevels[1], array());
             foreach (MetaModel::EnumParentClasses($sLeafClass, ENUM_PARENT_CLASSES_ALL) as $sClass) {
                 if (isset($aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items'])) {
                     $aContextDefs = array_merge($aContextDefs, $aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items']);
                 }
             }
             // Check if the queries are valid
             foreach ($aContextDefs as $sKey => $sDefs) {
                 $sOQL = $aContextDefs[$sKey]['oql'];
                 try {
                     // Expand the parameters. If anything goes wrong, then the query is considered as invalid and removed from the list
                     $oSearch = DBObjectSearch::FromOQL($sOQL);
                     $aContextDefs[$sKey]['oql'] = $oSearch->ToOQL($bDevelopParams, $aContextParams);
                 } catch (Exception $e) {
                     IssueLog::Warning('Invalid OQL query: ' . $sOQL . ' in the parameter ' . $sContextKey);
                     unset($aContextDefs[$sKey]);
                 }
             }
         }
     }
     return $aContextDefs;
 }
 /**
  * Updates the object form POSTED arguments, and writes it into the DB (applies a stimuli if requested)
  * @param DBObject $oObj The object to update
  * $param array $aAttList If set, this will limit the list of updated attributes	 
  * @return void
  */
 public function DoUpdateObjectFromPostedForm(DBObject $oObj, $aAttList = null)
 {
     $sTransactionId = utils::ReadPostedParam('transaction_id', '');
     if (!utils::IsTransactionValid($sTransactionId)) {
         throw new TransactionException();
     }
     $sClass = get_class($oObj);
     $sStimulus = trim(utils::ReadPostedParam('apply_stimulus', ''));
     $sTargetState = '';
     if (!empty($sStimulus)) {
         // Compute the target state
         $aTransitions = $oObj->EnumTransitions();
         if (!isset($aTransitions[$sStimulus])) {
             throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel()));
         }
         $sTargetState = $aTransitions[$sStimulus]['target_state'];
     }
     $oObj->UpdateObjectFromPostedForm('', $aAttList, $sTargetState);
     // Optional: apply a stimulus
     //
     if (!empty($sStimulus)) {
         if (!$oObj->ApplyStimulus($sStimulus)) {
             throw new Exception("Cannot apply stimulus '{$sStimulus}' to {$oObj->GetName()}");
         }
     }
     if ($oObj->IsModified()) {
         // Record the change
         //
         $oObj->DBUpdate();
         // Trigger ?
         //
         $aClasses = MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL);
         $sClassList = implode(", ", CMDBSource::Quote($aClasses));
         $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnPortalUpdate AS t WHERE t.target_class IN ({$sClassList})"));
         while ($oTrigger = $oSet->Fetch()) {
             $oTrigger->DoActivate($oObj->ToArgs('this'));
         }
         $this->p("<h1>" . Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName()) . "</h1>\n");
     }
     $bLockEnabled = MetaModel::GetConfig()->Get('concurrent_lock_enabled');
     if ($bLockEnabled) {
         // Release the concurrent lock, if any
         $sOwnershipToken = utils::ReadPostedParam('ownership_token', null, false, 'raw_data');
         if ($sOwnershipToken !== null) {
             // We're done, let's release the lock
             iTopOwnershipLock::ReleaseLock(get_class($oObj), $oObj->GetKey(), $sOwnershipToken);
         }
     }
 }
 public function AllowTargetCreation()
 {
     return $this->GetOptional('allow_target_creation', MetaModel::GetConfig()->Get('allow_target_creation'));
 }
 public function GetNextChunk(&$aStatus)
 {
     $sRetCode = 'run';
     $iPercentage = 0;
     $oSet = new DBObjectSet($this->oSearch);
     $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']);
     $this->OptimizeColumnLoad($oSet);
     $iCount = 0;
     $sData = '';
     $iPreviousTimeLimit = ini_get('max_execution_time');
     $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
     while ($aRow = $oSet->FetchAssoc()) {
         set_time_limit($iLoopTimeLimit);
         $aData = array();
         foreach ($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) {
             $sAlias = $aFieldSpec['sAlias'];
             $sAttCode = $aFieldSpec['sAttCode'];
             $sField = '';
             $oObj = $aRow[$sAlias];
             if ($oObj != null) {
                 switch ($sAttCode) {
                     case 'id':
                         $sField = $oObj->GetKey();
                         break;
                     default:
                         $sField = $oObj->GetAsCSV($sAttCode, $this->aStatusInfo['separator'], $this->aStatusInfo['text_qualifier'], $this->bLocalizeOutput);
                 }
             }
             if ($this->aStatusInfo['charset'] != 'UTF-8') {
                 // Note: due to bugs in the glibc library it's safer to call iconv on the smallest possible string
                 // and thus to convert field by field and not the whole row or file at once (see ticket #991)
                 $aData[] = iconv('UTF-8', $this->aStatusInfo['charset'] . '//IGNORE//TRANSLIT', $sField);
             } else {
                 $aData[] = $sField;
             }
         }
         $sData .= implode($this->aStatusInfo['separator'], $aData) . "\n";
         $iCount++;
     }
     set_time_limit($iPreviousTimeLimit);
     $this->aStatusInfo['position'] += $this->iChunkSize;
     if ($this->aStatusInfo['total'] == 0) {
         $iPercentage = 100;
     } else {
         $iPercentage = floor(min(100.0, 100.0 * $this->aStatusInfo['position'] / $this->aStatusInfo['total']));
     }
     if ($iCount < $this->iChunkSize) {
         $sRetCode = 'done';
     }
     $aStatus = array('code' => $sRetCode, 'message' => Dict::S('Core:BulkExport:RetrievingData'), 'percentage' => $iPercentage);
     return $sData;
 }
 /**
  * Do the synchronization job #1: Obsolete replica "untouched" for some time
  * @param integer $iMaxReplica Limit the number of replicas to process 
  * @param integer $iCurrPos Current position where to resume the processing 
  * @return true if the process must be continued
  */
 protected function DoJob1($iMaxReplica = null, $iCurrPos = -1)
 {
     $sLimitDate = $this->m_oLastFullLoadStartDate->Format('Y-m-d H:i:s');
     // Get all the replicas that were not seen in the last import and mark them as obsolete
     $sDeletePolicy = $this->m_oDataSource->Get('delete_policy');
     if ($sDeletePolicy != 'ignore') {
         $sSelectToObsolete = "SELECT SynchroReplica WHERE id > :curr_pos AND sync_source_id = :source_id AND status IN ('new', 'synchronized', 'modified', 'orphan') AND status_last_seen < :last_import";
         $oSetScope = new DBObjectSet(DBObjectSearch::FromOQL($sSelectToObsolete), array(), array('source_id' => $this->m_oDataSource->GetKey(), 'last_import' => $sLimitDate, 'curr_pos' => $iCurrPos));
         $iCountScope = $oSetScope->Count();
         if ($this->m_iCountAllReplicas > 10 && $this->m_iCountAllReplicas == $iCountScope && MetaModel::GetConfig()->Get('synchro_prevent_delete_all')) {
             throw new SynchroExceptionNotStarted(Dict::S('Core:SyncTooManyMissingReplicas'));
         }
         if ($iMaxReplica) {
             // Consider a given subset, starting from replica iCurrPos, limited to the count of iMaxReplica
             // The replica have to be ordered by id
             $oSetToProcess = new DBObjectSet(DBObjectSearch::FromOQL($sSelectToObsolete), array('id' => true), array('source_id' => $this->m_oDataSource->GetKey(), 'last_import' => $sLimitDate, 'curr_pos' => $iCurrPos));
             $oSetToProcess->SetLimit($iMaxReplica);
         } else {
             $oSetToProcess = $oSetScope;
         }
         $iLastReplicaProcessed = -1;
         while ($oReplica = $oSetToProcess->Fetch()) {
             $iLastReplicaProcessed = $oReplica->GetKey();
             switch ($sDeletePolicy) {
                 case 'update':
                 case 'update_then_delete':
                     $this->m_oStatLog->AddTrace("Destination object to be updated", $oReplica);
                     $aToUpdate = array();
                     $aToUpdateSpec = explode(';', $this->m_oDataSource->Get('delete_policy_update'));
                     //ex: 'status:obsolete;description:stopped',
                     foreach ($aToUpdateSpec as $sUpdateSpec) {
                         $aUpdateSpec = explode(':', $sUpdateSpec);
                         if (count($aUpdateSpec) == 2) {
                             $sAttCode = $aUpdateSpec[0];
                             $sValue = $aUpdateSpec[1];
                             $aToUpdate[$sAttCode] = $sValue;
                         }
                     }
                     $oReplica->Set('status_last_error', '');
                     if ($oReplica->Get('dest_id') == '') {
                         $oReplica->Set('status', 'obsolete');
                         $this->m_oStatLog->Inc('stats_nb_replica_disappeared_no_action');
                     } else {
                         $oReplica->UpdateDestObject($aToUpdate, $this->m_oChange, $this->m_oStatLog);
                         if ($oReplica->Get('status_last_error') == '') {
                             // Change the status of the replica IIF
                             $oReplica->Set('status', 'obsolete');
                         }
                     }
                     $oReplica->DBUpdateTracked($this->m_oChange);
                     break;
                 case 'delete':
                 default:
                     $this->m_oStatLog->AddTrace("Destination object to be DELETED", $oReplica);
                     $oReplica->DeleteDestObject($this->m_oChange, $this->m_oStatLog);
             }
         }
         if ($iMaxReplica) {
             if ($iMaxReplica < $iCountScope) {
                 // Continue with this job!
                 $this->m_oStatLog->Set('status_curr_pos', $iLastReplicaProcessed);
                 return true;
             }
         }
     }
     // if ($sDeletePolicy != 'ignore'
     //Count "seen" objects
     $sSelectSeen = "SELECT SynchroReplica WHERE sync_source_id = :source_id AND status IN ('new', 'synchronized', 'modified', 'orphan') AND status_last_seen >= :last_import";
     $oSetSeen = new DBObjectSet(DBObjectSearch::FromOQL($sSelectSeen), array(), array('source_id' => $this->m_oDataSource->GetKey(), 'last_import' => $sLimitDate));
     $this->m_oStatLog->Set('stats_nb_replica_seen', $oSetSeen->Count());
     // Job complete!
     $this->m_oStatLog->Set('status_curr_job', 2);
     $this->m_oStatLog->Set('status_curr_pos', -1);
     return false;
 }