protected function _DoExecute($oTrigger, $aContextArgs, &$oLog) { $sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass(); try { $sScriptPath = $this->Get('script_path'); if (!is_executable($sScriptPath)) { throw new Exception('cannot execute script'); } $sCMD = ''; $aParams = explode("\n", $this->Get('params')); array_walk($aParams, function (&$aParam) { $aParam = explode('=', $aParam); $aParam = array_map('trim', $aParam); }); foreach ($aParams as $aParam) { if (count($aParam) == 2) { $sVarName = $aParam[0]; $sVarValue = MetaModel::ApplyParams($aParam[1], $aContextArgs); if ($sVarValue == $aParam[1]) { $sVarValue = ''; // Значит ApplyParams не нашел такого плейсхолдера if ($this->IsBeingTested() && !is_null($oLog)) { $oLog->Set('log', $oLog->Get('log') . "There is no value for placeholder: {$aParam['1']}\n"); } } } else { $sVarName = $aParam[0]; $sVarValue = MetaModel::ApplyParams($aParam[0], $aContextArgs); if ($sVarValue == $aParam[0]) { $sVarValue = ''; if ($this->IsBeingTested() && !is_null($oLog)) { $oLog->Set('log', $oLog->Get('log') . "There is no value for placeholder: {$aParam['0']}\n"); } } } $sVarName = str_replace('->', '_', $sVarName); $sVarName = str_replace('$', '', $sVarName); $sVarName = strtoupper($sVarName); $sCMD .= $sVarName . '="' . $sVarValue . '" '; } $sCMD .= ' ' . $sScriptPath; if ($this->IsBeingTested()) { if (!is_null($oLog)) { $oLog->Set('log', $oLog->Get('log') . "Start executing shell command:\n{$sCMD}"); } return "Script will be started."; } if (!is_null($oLog)) { $oLog->Set('log', shell_exec($sCMD)); } return "Script {$sScriptPath} successfully started."; } catch (Exception $e) { ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker); throw $e; // Ошибка выбрасывается на верхний уровень и записывается в лог оповещения. } ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker); }
ReportErrorAndExit("Invalid OQL query: '{$sExpression}'.\n" . $e->getMessage()); } catch (Exception $e) { ReportErrorAndExit($e->getMessage()); } exit; } ///////////////////////////////////////////////////////////////////////////// // // Web Server mode // ///////////////////////////////////////////////////////////////////////////// try { require_once APPROOT . '/application/loginwebpage.class.inc.php'; LoginWebPage::DoLogin(); // Check user rights and prompt if needed ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker'); // Main parameters $sExpression = utils::ReadParam('expression', null, true, 'raw_data'); $sQueryId = utils::ReadParam('query', null, true, 'raw_data'); $sFormat = utils::ReadParam('format', null, true); $sFileName = utils::ReadParam('filename', '', true, 'string'); $bInteractive = utils::ReadParam('interactive', false); $sMode = utils::ReadParam('mode', ''); if ($bInteractive) { InteractiveShell($sExpression, $sQueryId, $sFormat, $sFileName, $sMode); } else { $oExporter = CheckParameters($sExpression, $sQueryId, $sFormat); $sMimeType = $oExporter->GetMimeType(); if ($sMimeType == 'text/html') { $oP = new NiceWebPage('iTop export'); $oP->add_style("body { overflow: auto; }");
return $bRes; } /////////////////////////////////////////////////////////////////////////////// // // Main program // /////////////////////////////////////////////////////////////////////////////// try { require_once APPROOT . '/application/startup.inc.php'; require_once APPROOT . '/application/portalwebpage.class.inc.php'; $oAppContext = new ApplicationContext(); $sOperation = utils::ReadParam('operation', ''); require_once APPROOT . '/application/loginwebpage.class.inc.php'; LoginWebPage::DoLogin(false, true); // Check user rights and prompt if needed ApplicationContext::SetUrlMakerClass('MyPortalURLMaker'); $aClasses = explode(',', MetaModel::GetConfig()->Get('portal_tickets')); $sMainClass = trim(reset($aClasses)); if (!class_exists($sMainClass)) { $oP = new WebPage(Dict::S('Portal:Title')); $oP->p(dict::Format('Portal:NoRequestMgmt', UserRights::GetUserFriendlyName())); } else { $oUserOrg = GetUserOrg(); $sCode = $oUserOrg->Get('code'); $sAlternateStylesheet = ''; if (@file_exists("./{$sCode}/portal.css")) { $sAlternateStylesheet = "{$sCode}"; } $oP = new PortalWebPage(Dict::S('Portal:Title'), $sAlternateStylesheet); $oP->EnableDisconnectButton(utils::CanLogOff()); $oP->SetWelcomeMessage(Dict::Format('Portal:WelcomeUserOrg', UserRights::GetUserFriendlyName(), $oUserOrg->GetName()));
public function __construct($sTitle) { parent::__construct($sTitle); $this->m_oTabs = new TabManager(); ApplicationContext::SetUrlMakerClass('iTopStandardURLMaker'); $this->m_sMenu = ""; $this->m_sMessage = ''; $this->SetRootUrl(utils::GetAbsoluteUrlAppRoot()); $this->add_header("Content-type: text/html; charset=utf-8"); $this->add_header("Cache-control: no-cache"); $this->add_linked_stylesheet("../css/jquery.treeview.css"); $this->add_linked_stylesheet("../css/jquery.autocomplete.css"); $this->add_linked_stylesheet("../css/fg.menu.css"); $this->add_linked_stylesheet("../css/jquery.multiselect.css"); $this->add_linked_script('../js/jquery.layout.min.js'); $this->add_linked_script('../js/jquery.ba-bbq.min.js'); $this->add_linked_script("../js/jquery.treeview.js"); $this->add_linked_script("../js/jquery.autocomplete.js"); $this->add_linked_script("../js/date.js"); $this->add_linked_script("../js/jquery.blockUI.js"); $this->add_linked_script("../js/utils.js"); $this->add_linked_script("../js/swfobject.js"); $this->add_linked_script("../js/ckeditor/ckeditor.js"); $this->add_linked_script("../js/ckeditor/adapters/jquery.js"); $this->add_linked_script("../js/jquery.qtip-1.0.min.js"); $this->add_linked_script('../js/property_field.js'); $this->add_linked_script('../js/fg.menu.js'); $this->add_linked_script('../js/icon_select.js'); $this->add_linked_script('../js/raphael-min.js'); $this->add_linked_script('../js/g.raphael.js'); $this->add_linked_script('../js/g.pie.js'); $this->add_linked_script('../js/g.dot.js'); $this->add_linked_script('../js/charts.js'); $this->add_linked_script('../js/jquery.multiselect.min.js'); $this->add_linked_script('../js/ajaxfileupload.js'); $sSearchAny = addslashes(Dict::S('UI:SearchValue:Any')); $sSearchNbSelected = addslashes(Dict::S('UI:SearchValue:NbSelected')); $this->add_dict_entry('UI:FillAllMandatoryFields'); $this->add_dict_entry('UI:Button:Cancel'); $this->add_dict_entry('UI:Button:Done'); $bForceMenuPane = utils::ReadParam('force_menu_pane', null); $sInitClosed = ''; if ($bForceMenuPane !== null && $bForceMenuPane == 0) { $sInitClosed = 'initClosed: true,'; } $this->add_script(<<<EOF function ShowAboutBox() { \t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'about_box'}, function(data){ \t\t\$('body').append(data); \t}); \treturn false; } EOF ); if (MetaModel::GetConfig()->Get('demo_mode')) { // Leave the pane opened $sConfigureWestPane = ''; } else { $sConfigureWestPane = <<<EOF \t\t\t\tif (GetUserPreference('menu_pane', 'open') == 'closed') \t\t\t\t{ \t\t\t\t\tmyLayout.close('west'); \t\t\t\t} \t\t\t\tmyLayout.addPinBtn( "#tPinMenu", "west" ); EOF; } $sJSDisconnectedMessage = json_encode(Dict::S('UI:DisconnectedDlgMessage')); $sJSTitle = json_encode(Dict::S('UI:DisconnectedDlgTitle')); $sJSLoginAgain = json_encode(Dict::S('UI:LoginAgain')); $sJSStayOnThePage = json_encode(Dict::S('UI:StayOnThePage')); $sJSDaysMin = json_encode(array(Dict::S('DayOfWeek-Sunday-Min'), Dict::S('DayOfWeek-Monday-Min'), Dict::S('DayOfWeek-Tuesday-Min'), Dict::S('DayOfWeek-Wednesday-Min'), Dict::S('DayOfWeek-Thursday-Min'), Dict::S('DayOfWeek-Friday-Min'), Dict::S('DayOfWeek-Saturday-Min'))); $sJSMonthsShort = json_encode(array(Dict::S('Month-01-Short'), Dict::S('Month-02-Short'), Dict::S('Month-03-Short'), Dict::S('Month-04-Short'), Dict::S('Month-05-Short'), Dict::S('Month-06-Short'), Dict::S('Month-07-Short'), Dict::S('Month-08-Short'), Dict::S('Month-09-Short'), Dict::S('Month-10-Short'), Dict::S('Month-11-Short'), Dict::S('Month-12-Short'))); $iFirstDayOfWeek = (int) Dict::S('Calendar-FirstDayOfWeek'); $this->m_sInitScript = <<<EOF \ttry \t{ \t\tvar myLayout; // a var is required because this page utilizes: myLayout.allowOverflow() method \t \t\t// Layout \t\tpaneSize = GetUserPreference('menu_size', 300) \t\tmyLayout = \$('body').layout({ \t\t\twest :\t{ \t\t\t\t\t\t{$sInitClosed} minSize: 200, size: paneSize, spacing_open: 16, spacing_close: 16, slideTrigger_open: "mouseover", hideTogglerOnSlide: true, enableCursorHotkey: false, \t\t\t\t\t\tonclose_end: function(name, elt, state, options, layout) \t\t\t\t\t\t{ \t\t\t\t\t\t\t\tif (state.isSliding == false) \t\t\t\t\t\t\t\t{ \t\t\t\t\t\t\t\t\tSetUserPreference('menu_pane', 'closed', true); \t\t\t\t\t\t\t\t} \t\t\t\t\t\t}, \t\t\t\t\t\tonresize_end: function(name, elt, state, options, layout) \t\t\t\t\t\t{ \t\t\t\t\t\t\t\tif (state.isSliding == false) \t\t\t\t\t\t\t\t{ \t\t\t\t\t\t\t\t\tSetUserPreference('menu_size', state.size, true); \t\t\t\t\t\t\t\t} \t\t\t\t\t\t}, \t\t\t\t\t\t\t\t\t \t\t\t\t\t\tonopen_end: function(name, elt, state, options, layout) \t\t\t\t\t\t{ \t\t\t\t\t\t\tif (state.isSliding == false) \t\t\t\t\t\t\t{ \t\t\t\t\t\t\t\tSetUserPreference('menu_pane', 'open', true); \t\t\t\t\t\t\t} \t\t\t\t\t\t} \t\t\t\t\t}, \t\t\tcenter: { \t\t\t\t\t\tonresize_end: function(name, elt, state, options, layout) \t\t\t\t\t\t{ \t\t\t\t\t\t\t\t\$('.v-resizable').each( function() { \t\t\t\t\t\t\t\t\tvar fixedWidth = \$(this).parent().innerWidth() - 6; \t\t\t\t\t\t\t\t\t\$(this).width(fixedWidth); \t\t\t\t\t\t\t\t\t// Make sure it cannot be resized horizontally \t\t\t\t\t\t\t\t\t\$(this).resizable('options', { minWidth: fixedWidth, maxWidth:\tfixedWidth }); \t\t\t\t\t\t\t\t\t// Now adjust all the child 'items' \t\t\t\t\t\t\t\t\tvar innerWidth = \$(this).innerWidth() - 10; \t\t\t\t\t\t\t\t\t\$(this).find('.item').width(innerWidth); \t\t\t\t\t\t\t\t}); \t\t\t\t\t\t\t\t\$('.panel-resized').trigger('resized'); \t\t\t\t\t\t} \t\t\t\t \t\t\t\t\t} \t\t}); \t\twindow.clearTimeout(iPaneVisWatchDog); \t\t//myLayout.open( "west" ); \t\t\$('.ui-layout-resizer-west .ui-layout-toggler').css({background: 'transparent'}); \t\t{$sConfigureWestPane} \t\t \t\t\$('#left-pane').layout({ resizable: false, spacing_open: 0, south: { size: 94 }, enableCursorHotkey: false }); \t \t\t// Accordion Menu \t\t\$("#accordion").accordion({ header: "h3", navigation: true, heightStyle: "content", collapsible: false, icons: false }); // collapsible will be enabled once the item will be selected \t \t\t// Tabs, using JQuery BBQ to store the history \t\t// The "tab widgets" to handle. \t\tvar tabs = \$('div[id^=tabbedContent]'); \t\t\t \t\t// This selector will be reused when selecting actual tab widget A elements. \t\tvar tab_a_selector = 'ul.ui-tabs-nav a'; \t\t \t\t// Ugly patch for a change in the behavior of jQuery UI: \t\t// Before jQuery UI 1.9, tabs were always considered as "local" (opposed to Ajax) \t\t// when their href was beginning by #. Starting with 1.9, a <base> tag in the page \t\t// is taken into account and causes "local" tabs to be considered as Ajax \t\t// unless their URL is equal to the URL of the page... \t\t\$('div[id^=tabbedContent] > ul > li > a').each(function() { \t\t\tvar sHash = location.hash; \t\t\tvar sHref = \$(this).attr("href"); \t\t\tif (sHref.match(/^#/)) \t\t\t{ \t\t\t\tvar sCleanLocation = location.href.toString().replace(sHash, '').replace(/#\$/, ''); \t\t\t\t\$(this).attr("href", sCleanLocation+\$(this).attr("href")); \t\t\t} \t\t}); \t\t// Enable tabs on all tab widgets. The `event` property must be overridden so \t\t// that the tabs aren't changed on click, and any custom event name can be \t\t// specified. Note that if you define a callback for the 'select' event, it \t\t// will be executed for the selected tab whenever the hash changes. \t\ttabs.tabs({ \t\t\tevent: 'change', 'show': function(event, ui) { \t\t\t\t\$('.resizable', ui.panel).resizable(); // Make resizable everything that claims to be resizable ! \t\t\t}, \t\t\tbeforeLoad: function( event, ui ) { \t\t\t\tif ( ui.tab.data('loaded') && (ui.tab.attr('data-cache') == 'true')) { \t\t\t\t\tevent.preventDefault(); \t\t\t\t\treturn; \t\t\t\t} \t\t\t\tui.panel.html('<div><img src="../images/indicator.gif"></div>'); \t\t\t\tui.jqXHR.success(function() { \t\t\t\t\tui.tab.data( "loaded", true ); \t\t\t\t}); \t\t\t} \t\t}); \t\t\t\t\t \t\t\$('.resizable').filter(':visible').resizable(); \t} \tcatch(err) \t{ \t\t// Do something with the error ! \t\talert(err); \t} EOF; $this->add_ready_script(<<<EOF \t \t// Adjust initial size \t\$('.v-resizable').each( function() \t\t{ \t\t\tvar parent_id = \$(this).parent().id; \t\t\t// Restore the saved height \t\t\tvar iHeight = GetUserPreference(parent_id+'_'+this.id+'_height', undefined); \t\t\tif (iHeight != undefined) \t\t\t{ \t\t\t\t\$(this).height(parseInt(iHeight, 10)); // Parse in base 10 !); \t\t\t} \t\t\t// Adjust the child 'item''s height and width to fit \t\t\tvar container = \$(this); \t\t\tvar fixedWidth = container.parent().innerWidth() - 6; \t\t\t// Set the width to fit the parent \t\t\t\$(this).width(fixedWidth); \t\t\tvar headerHeight = \$(this).find('.drag_handle').height(); \t\t\t// Now adjust the width and height of the child 'item' \t\t\tcontainer.find('.item').height(container.innerHeight() - headerHeight - 12).width(fixedWidth - 10); \t\t} \t); \t// Make resizable, vertically only everything that claims to be v-resizable ! \t\$('.v-resizable').resizable( { handles: 's', minHeight: \$(this).find('.drag_handle').height(), minWidth: \$(this).parent().innerWidth() - 6, maxWidth: \$(this).parent().innerWidth() - 6, stop: function() \t\t{ \t\t\t// Adjust the content \t\t\tvar container = \$(this); \t\t\tvar headerHeight = \$(this).find('.drag_handle').height(); \t\t\tcontainer.find('.item').height(container.innerHeight() - headerHeight - 12);//.width(container.innerWidth()); \t\t\tvar parent_id = \$(this).parent().id; \t\t\tSetUserPreference(parent_id+'_'+this.id+'_height', \$(this).height(), true); // true => persistent \t\t} \t} ); \t\t \t// Tabs, using JQuery BBQ to store the history \t// The "tab widgets" to handle. \tvar tabs = \$('div[id^=tabbedContent]'); \t\t \t// This selector will be reused when selecting actual tab widget A elements. \tvar tab_a_selector = 'ul.ui-tabs-nav a'; \t \t// Define our own click handler for the tabs, overriding the default. \ttabs.find( tab_a_selector ).click(function() \t{ \t\tvar state = {}; \t\t\t\t \t\t// Get the id of this tab widget. \t\tvar id = \$(this).closest( 'div[id^=tabbedContent]' ).attr( 'id' ); \t\t \t\t// Get the index of this tab. \t\tvar idx = \$(this).parent().prevAll().length; \t\t \t\t// Set the state! \t\tstate[ id ] = idx; \t\t\$.bbq.pushState( state ); \t}); \t \t// refresh the hash when the tab is changed (from a JS script) \t\$('body').on( 'tabsactivate', '.ui-tabs', function(event, ui) { \t\tvar state = {}; \t\t\t \t\t// Get the id of this tab widget. \t\tvar id = \$(ui.newTab).closest( 'div[id^=tabbedContent]' ).attr( 'id' ); \t\t \t\t// Get the index of this tab. \t\tvar idx = \$(ui.newTab).prevAll().length; \t\t\t \t\t// Set the state! \t\tstate[ id ] = idx; \t\t\$.bbq.pushState( state ); \t}); \t \t// Bind an event to window.onhashchange that, when the history state changes, \t// iterates over all tab widgets, changing the current tab as necessary. \t\$(window).bind( 'hashchange', function(e) \t{ \t\t// Iterate over all tab widgets. \t\ttabs.each(function() \t\t{ \t\t\t// Get the index for this tab widget from the hash, based on the \t\t\t// appropriate id property. In jQuery 1.4, you should use e.getState() \t\t\t// instead of \$.bbq.getState(). The second, 'true' argument coerces the \t\t\t// string value to a number. \t\t\tvar idx = \$.bbq.getState( this.id, true ) || 0; \t\t\t \t\t\t// Select the appropriate tab for this tab widget by triggering the custom \t\t\t// event specified in the .tabs() init above (you could keep track of what \t\t\t// tab each widget is on using .data, and only select a tab if it has \t\t\t// changed). \t\t\t\$(this).find( tab_a_selector ).eq( idx ).triggerHandler( 'change' ); \t\t}); \t\t// Iterate over all truncated lists to find whether they are expanded or not \t\t\$('a.truncated').each(function() \t\t{ \t\t\tvar state = \$.bbq.getState( this.id, true ) || 'close'; \t\t\tif (state == 'open') \t\t\t{ \t\t\t\t\$(this).trigger('open'); \t\t\t} \t\t\telse \t\t\t{ \t\t\t\t\$(this).trigger('close');\t \t\t\t} \t\t}); \t}); \t \t// Shortcut menu actions \t\$('.actions_button a').click( function() { \t\taMatches = /#(.*)\$/.exec(window.location.href); \t\tif (aMatches != null) \t\t{ \t\t\tcurrentHash = aMatches[1]; \t\t\tif ( /#(.*)\$/.test(this.href)) \t\t\t{ \t\t\t\tthis.href = this.href.replace(/#(.*)\$/, '#'+currentHash); \t\t\t} \t\t} \t}); \t// End of Tabs handling \t\$(".date-pick").datepicker({ \t\t\tshowOn: 'button', \t\t\tbuttonImage: '../images/calendar.png', \t\t\tbuttonImageOnly: true, \t\t\tdateFormat: 'yy-mm-dd', \t\t\tconstrainInput: false, \t\t\tchangeMonth: true, \t\t\tchangeYear: true, \t\t\tdayNamesMin: {$sJSDaysMin}, \t\t\tmonthNamesShort: {$sJSMonthsShort}, \t\t\tfirstDay: {$iFirstDayOfWeek} \t\t}); \t\$(".datetime-pick").datepicker({ \t\t\tshowOn: 'button', \t\t\tbuttonImage: '../images/calendar.png', \t\t\tbuttonImageOnly: true, \t\t\tdateFormat: 'yy-mm-dd 00:00:00', \t\t\tconstrainInput: false, \t\t\tchangeMonth: true, \t\t\tchangeYear: true, \t\t\tdayNamesMin: {$sJSDaysMin}, \t\t\tmonthNamesShort: {$sJSMonthsShort}, \t\t\tfirstDay: {$iFirstDayOfWeek} \t\t}); \t// Make sortable, everything that claims to be sortable \t\$('.sortable').sortable( {axis: 'y', cursor: 'move', handle: '.drag_handle', stop: function() \t\t{ \t\t\tif (\$(this).hasClass('persistent')) \t\t\t{ \t\t\t\t// remember the sort order for next time the page is loaded... \t\t\t\tsSerialized = \$(this).sortable('serialize', {key: 'menu'}); \t\t\t\tvar sTemp = sSerialized.replace(/menu=/g, ''); \t\t\t\tSetUserPreference(this.id+'_order', sTemp.replace(/&/g, ','), true); // true => persistent ! \t\t\t} \t\t} \t}); \tdocWidth = \$(document).width(); \t\$('#ModalDlg').dialog({ autoOpen: false, modal: true, width: 0.8*docWidth }); // JQuery UI dialogs \tShowDebug(); \t\$('#logOffBtn>ul').popupmenu(); \t \t\$('.caselog_header').click( function () { \$(this).toggleClass('open').next('.caselog_entry').toggle(); }); \t \t\$(document).ajaxSend(function(event, jqxhr, options) { \t\tjqxhr.setRequestHeader('X-Combodo-Ajax', 'true'); \t}); \t\$(document).ajaxError(function(event, jqxhr, options) { \t\tif (jqxhr.status == 401) \t\t{ \t\t\t\$('<div>'+{$sJSDisconnectedMessage}+'</div>').dialog({ \t\t\t\tmodal:true, \t\t\t\ttitle: {$sJSTitle}, \t\t\t\tclose: function() { \$(this).remove(); }, \t\t\t\tminWidth: 400, \t\t\t\tbuttons: [ \t\t\t\t\t{ text: {$sJSLoginAgain}, click: function() { window.location.href= GetAbsoluteUrlAppRoot()+'pages/UI.php' } }, \t\t\t\t\t{ text: {$sJSStayOnThePage}, click: function() { \$(this).dialog('close'); } } \t\t\t\t] \t\t\t}); \t\t} \t}); \t\t\t EOF ); $sUserPrefs = appUserPreferences::GetAsJSON(); $this->add_script(<<<EOF //\t\t// for JQuery history //\t\tfunction history_callback(hash) //\t\t{ //\t\t\t// do stuff that loads page content based on hash variable //\t\t\tvar aMatches = /^tab_(.*)\$/.exec(hash); //\t\t\tif (aMatches != null) //\t\t\t{ //\t\t\t\tvar tab = \$('#'+hash); //\t\t\t\ttab.parents('div[id^=tabbedContent]:first').tabs('select', aMatches[1]); //\t\t\t} //\t\t} \t\tfunction goBack() \t\t{ \t\t\twindow.history.back(); \t\t} \t\t \t\tfunction BackToDetails(sClass, id, sDefaultUrl) \t\t{ \t\t\twindow.bInCancel = true; \t\t\tif (id > 0) \t\t\t{ \t\t\t\twindow.location.href = AddAppContext(GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=release_lock_and_details&class='+sClass+'&id='+id); \t\t\t} \t\t\telse \t\t\t{ \t\t\t\twindow.location.href = sDefaultUrl; // Already contains the context...\t\t\t\t \t\t\t} \t\t} \t\tfunction BackToList(sClass) \t\t{ \t\t\twindow.location.href = AddAppContext(GetAbsoluteUrlAppRoot()+'pages/UI.php?operation=search_oql&oql_class='+sClass+'&oql_clause=WHERE id=0'); \t\t} \t\t \t\tfunction ShowDebug() \t\t{ \t\t\tif (\$('#rawOutput > div').html() != '') \t\t\t{ \t\t\t\t\$('#rawOutput').dialog( {autoOpen: true, modal:false, width: '80%'}); \t\t\t} \t\t} \t\t \t\tvar oUserPreferences = {$sUserPrefs}; \t\t// For disabling the CKEditor at init time when the corresponding textarea is disabled ! \t\tCKEDITOR.plugins.add( 'disabler', \t\t{ \t\t\tinit : function( editor ) \t\t\t{ \t\t\t\teditor.on( 'instanceReady', function(e) \t\t\t\t{ \t\t\t\t\te.removeListener(); \t\t\t\t\t\$('#'+ editor.name).trigger('update'); \t\t\t\t}); \t\t\t} \t\t\t \t\t}); \t\t \t\tfunction FixPaneVis() \t\t{ \t\t\t\$('.ui-layout-center, .ui-layout-north, .ui-layout-south').css({display: 'block'}); \t\t} EOF ); }
protected function _DoExecute($oTrigger, $aContextArgs, &$oLog) { $sPreviousUrlMaker = ApplicationContext::SetUrlMakerClass(); try { $this->m_iRecipients = 0; $this->m_aMailErrors = array(); $bRes = false; // until we do succeed in sending the email // Determine recicipients // $sTo = $this->FindRecipients('to', $aContextArgs); $sCC = $this->FindRecipients('cc', $aContextArgs); $sBCC = $this->FindRecipients('bcc', $aContextArgs); $sFrom = MetaModel::ApplyParams($this->Get('from'), $aContextArgs); $sReplyTo = MetaModel::ApplyParams($this->Get('reply_to'), $aContextArgs); $sSubject = MetaModel::ApplyParams($this->Get('subject'), $aContextArgs); $sBody = MetaModel::ApplyParams($this->Get('body'), $aContextArgs); $oObj = $aContextArgs['this->object()']; $sMessageId = sprintf('iTop_%s_%d_%f@%s.openitop.org', get_class($oObj), $oObj->GetKey(), microtime(true), MetaModel::GetEnvironmentId()); $sReference = '<' . $sMessageId . '>'; } catch (Exception $e) { ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker); throw $e; } ApplicationContext::SetUrlMakerClass($sPreviousUrlMaker); if (!is_null($oLog)) { // Note: we have to secure this because those values are calculated // inside the try statement, and we would like to keep track of as // many data as we could while some variables may still be undefined if (isset($sTo)) { $oLog->Set('to', $sTo); } if (isset($sCC)) { $oLog->Set('cc', $sCC); } if (isset($sBCC)) { $oLog->Set('bcc', $sBCC); } if (isset($sFrom)) { $oLog->Set('from', $sFrom); } if (isset($sSubject)) { $oLog->Set('subject', $sSubject); } if (isset($sBody)) { $oLog->Set('body', $sBody); } } $oEmail = new EMail(); if ($this->IsBeingTested()) { $oEmail->SetSubject('TEST[' . $sSubject . ']'); $sTestBody = $sBody; $sTestBody .= "<div style=\"border: dashed;\">\n"; $sTestBody .= "<h1>Testing email notification " . $this->GetHyperlink() . "</h1>\n"; $sTestBody .= "<p>The email should be sent with the following properties\n"; $sTestBody .= "<ul>\n"; $sTestBody .= "<li>TO: {$sTo}</li>\n"; $sTestBody .= "<li>CC: {$sCC}</li>\n"; $sTestBody .= "<li>BCC: {$sBCC}</li>\n"; $sTestBody .= "<li>From: {$sFrom}</li>\n"; $sTestBody .= "<li>Reply-To: {$sReplyTo}</li>\n"; $sTestBody .= "<li>References: {$sReference}</li>\n"; $sTestBody .= "</ul>\n"; $sTestBody .= "</p>\n"; $sTestBody .= "</div>\n"; $oEmail->SetBody($sTestBody); $oEmail->SetRecipientTO($this->Get('test_recipient')); $oEmail->SetRecipientFrom($this->Get('test_recipient')); $oEmail->SetReferences($sReference); $oEmail->SetMessageId($sMessageId); } else { $oEmail->SetSubject($sSubject); $oEmail->SetBody($sBody); $oEmail->SetRecipientTO($sTo); $oEmail->SetRecipientCC($sCC); $oEmail->SetRecipientBCC($sBCC); $oEmail->SetRecipientFrom($sFrom); $oEmail->SetRecipientReplyTo($sReplyTo); $oEmail->SetReferences($sReference); $oEmail->SetMessageId($sMessageId); } if (isset($aContextArgs['attachments'])) { $aAttachmentReport = array(); foreach ($aContextArgs['attachments'] as $oDocument) { $oEmail->AddAttachment($oDocument->GetData(), $oDocument->GetFileName(), $oDocument->GetMimeType()); $aAttachmentReport[] = array($oDocument->GetFileName(), $oDocument->GetMimeType(), strlen($oDocument->GetData())); } $oLog->Set('attachments', $aAttachmentReport); } if (empty($this->m_aMailErrors)) { if ($this->m_iRecipients == 0) { return 'No recipient'; } else { $iRes = $oEmail->Send($aErrors, false, $oLog); // allow asynchronous mode switch ($iRes) { case EMAIL_SEND_OK: return "Sent"; case EMAIL_SEND_PENDING: return "Pending"; case EMAIL_SEND_ERROR: return "Errors: " . implode(', ', $aErrors); } } } else { if (is_array($this->m_aMailErrors) && count($this->m_aMailErrors) > 0) { $sError = implode(', ', $this->m_aMailErrors); } else { $sError = 'Unknown reason'; } return 'Notification was not sent: ' . $sError; } }