function DisplayForm(WebPage $oP, $sAction = '', $sExpression = '', $sQueryId = '', $sFormat = null) { $oExportSearch = null; $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/tabularfieldsselector.js'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.dragtable.js'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/dragtable.css'); $oP->add('<form id="export-form" action="' . $sAction . '" method="post" data-state="not-yet-started">'); $bExpressionIsValid = true; $sExpressionError = ''; if ($sExpression === null && $sQueryId === null) { $bExpressionIsValid = false; } else { if ($sExpression !== '') { try { $oExportSearch = DBObjectSearch::FromOQL($sExpression); } catch (OQLException $e) { $bExpressionIsValid = false; $sExpressionError = $e->getMessage(); } } } if (!$bExpressionIsValid) { DisplayExpressionForm($oP, $sAction, $sExpression, $sExpressionError); return; } if ($sExpression !== '') { $oP->add('<input type="hidden" name="expression" value="' . htmlentities($sExpression, ENT_QUOTES, 'UTF-8') . '">'); $oExportSearch = DBObjectSearch::FromOQL($sExpression); } else { $oQuery = MetaModel::GetObject('QueryOQL', $sQueryId); $oExportSearch = DBObjectSearch::FromOQL($oQuery->Get('oql')); $oP->add('<input type="hidden" name="query" value="' . htmlentities($sQueryId, ENT_QUOTES, 'UTF-8') . '">'); } $aFormPartsByFormat = array(); $aAllFormParts = array(); if ($sFormat == null) { // No specific format chosen $sDefaultFormat = utils::ReadParam('format', 'xlsx'); $oP->add('<p>' . Dict::S('Core:BulkExport:ExportFormatPrompt') . ' <select name="format" id="format_selector">'); $aSupportedFormats = BulkExport::FindSupportedFormats(); asort($aSupportedFormats); foreach ($aSupportedFormats as $sFormatCode => $sLabel) { $sSelected = $sFormatCode == $sDefaultFormat ? 'selected' : ''; $oP->add('<option value="' . $sFormatCode . '" ' . $sSelected . '>' . htmlentities($sLabel, ENT_QUOTES, 'UTF-8') . '</option>'); $oExporter = BulkExport::FindExporter($sFormatCode); $oExporter->SetObjectList($oExportSearch); $aParts = $oExporter->EnumFormParts(); foreach ($aParts as $sPartId => $void) { $aAllFormParts[$sPartId] = $oExporter; } $aFormPartsByFormat[$sFormatCode] = array_keys($aParts); } $oP->add('</select></p>'); } else { // One specific format was chosen $oP->add('<input type="hidden" name="format" value="' . htmlentities($sFormat, ENT_QUOTES, 'UTF-8') . '">'); $oExporter = BulkExport::FindExporter($sFormat, $oExportSearch); $aParts = $oExporter->EnumFormParts(); foreach ($aParts as $sPartId => $void) { $aAllFormParts[$sPartId] = $oExporter; } $aFormPartsByFormat[$sFormat] = array_keys($aAllFormParts); } foreach ($aAllFormParts as $sPartId => $oExport) { $oP->add('<div class="form_part" id="form_part_' . $sPartId . '">'); $oExport->DisplayFormPart($oP, $sPartId); $oP->add('</div>'); } $oP->add('</form>'); $oP->add('<div id="export-feedback" style="display:none;"><p class="export-message" style="text-align:center;">' . Dict::S('ExcelExport:PreparingExport') . '</p><div class="export-progress-bar" style="max-width:30em; margin-left:auto;margin-right:auto;"><div class="export-progress-message" style="text-align:center;"></div></div></div>'); $oP->add('<button type="button" id="export-btn">' . Dict::S('UI:Button:Export') . '</button>'); $oP->add('<div id="export_text_result" style="display:none;">'); $oP->add('<div>' . Dict::S('Core:BulkExport:ExportResult') . '</div>'); $oP->add('<textarea id="export_content" style="width:100%;min-height:15em;"></textarea>'); $oP->add('</div>'); $sJSParts = json_encode($aFormPartsByFormat); $sJSCancel = json_encode(Dict::S('UI:Button:Cancel')); $sJSClose = json_encode(Dict::S('UI:Button:Done')); $oP->add_ready_script(<<<EOF window.aFormParts = {$sJSParts}; \$('#format_selector').on('change init', function() { \tExportToggleFormat(\$(this).val()); }).trigger('init'); \t\t \$('.export-progress-bar').progressbar({ \t value: 0, \t change: function() { \t\t\$('.export-progress-message').text( \$(this).progressbar( "value" ) + "%" ); \t }, \t complete: function() { \t\t \$('.export-progress-message').text( '100 %' ); \t } }); ExportInitButton('#export-btn'); EOF ); }
public function DisplayAttachments($oObject, WebPage $oPage, $bEditMode = false) { // Exit here if the class is not allowed if (!$this->IsTargetObject($oObject)) { return; } $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id"); $oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey())); if ($this->GetAttachmentsPosition() == 'relations') { $sTitle = $oSet->Count() > 0 ? Dict::Format('Attachments:TabTitle_Count', $oSet->Count()) : Dict::S('Attachments:EmptyTabTitle'); $oPage->SetCurrentTab($sTitle); } $oPage->add_style(<<<EOF .attachment { \tdisplay: inline-block; \ttext-align:center; \tfloat:left; \tpadding:5px;\t } .attachment:hover { \tbackground-color: #e0e0e0; } .attachment img { \tborder: 0; } .attachment a { \ttext-decoration: none; \tcolor: #1C94C4; } .btn_hidden { \tdisplay: none; } .drag_in { \t-webkit-box-shadow:inset 0 0 10px 2px #1C94C4; \tbox-shadow:inset 0 0 10px 2px #1C94C4; } #history .attachment-history-added { \tpadding: 0; \tfloat: none; } EOF ); $oPage->add('<fieldset>'); $oPage->add('<legend>' . Dict::S('Attachments:FieldsetTitle') . '</legend>'); if ($bEditMode) { $sIsDeleteEnabled = $this->m_bDeleteEnabled ? 'true' : 'false'; $iTransactionId = $oPage->GetTransactionId(); $sClass = get_class($oObject); $sTempId = session_id() . '_' . $iTransactionId; $sDeleteBtn = Dict::S('Attachments:DeleteBtn'); $oPage->add_script(<<<EOF \tfunction RemoveAttachment(att_id) \t{ \t\t\$('#attachment_'+att_id).attr('name', 'removed_attachments[]'); \t\t\$('#display_attachment_'+att_id).hide(); \t\t\$('#attachment_plugin').trigger('remove_attachment', [att_id]); \t\treturn false; // Do not submit the form ! \t} EOF ); $oPage->add('<span id="attachments">'); while ($oAttachment = $oSet->Fetch()) { $iAttId = $oAttachment->GetKey(); $oDoc = $oAttachment->Get('contents'); $sFileName = $oDoc->GetFileName(); $sIcon = utils::GetAbsoluteUrlAppRoot() . AttachmentPlugIn::GetFileIcon($sFileName); $sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false'; $sDownloadLink = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=download_document&class=Attachment&id=' . $iAttId . '&field=contents'; $oPage->add('<div class="attachment" id="display_attachment_' . $iAttId . '"><a data-preview="' . $sPreview . '" href="' . $sDownloadLink . '"><img src="' . $sIcon . '"><br/>' . $sFileName . '<input id="attachment_' . $iAttId . '" type="hidden" name="attachments[]" value="' . $iAttId . '"/></a><br/> <input id="btn_remove_' . $iAttId . '" type="button" class="btn_hidden" value="Delete" onClick="RemoveAttachment(' . $iAttId . ');"/> </div>'); } // Suggested attachments are listed here but treated as temporary $aDefault = utils::ReadParam('default', array(), false, 'raw_data'); if (array_key_exists('suggested_attachments', $aDefault)) { $sSuggestedAttachements = $aDefault['suggested_attachments']; if (is_array($sSuggestedAttachements)) { $sSuggestedAttachements = implode(',', $sSuggestedAttachements); } $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE id IN({$sSuggestedAttachements})"); $oSet = new DBObjectSet($oSearch, array()); if ($oSet->Count() > 0) { while ($oAttachment = $oSet->Fetch()) { // Mark the attachments as temporary attachments for the current object/form $oAttachment->Set('temp_id', $sTempId); $oAttachment->DBUpdate(); // Display them $iAttId = $oAttachment->GetKey(); $oDoc = $oAttachment->Get('contents'); $sFileName = $oDoc->GetFileName(); $sIcon = utils::GetAbsoluteUrlAppRoot() . AttachmentPlugIn::GetFileIcon($sFileName); $sDownloadLink = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=download_document&class=Attachment&id=' . $iAttId . '&field=contents'; $sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false'; $oPage->add('<div class="attachment" id="display_attachment_' . $iAttId . '"><a data-preview="' . $sPreview . '" href="' . $sDownloadLink . '"><img src="' . $sIcon . '"><br/>' . $sFileName . '<input id="attachment_' . $iAttId . '" type="hidden" name="attachments[]" value="' . $iAttId . '"/></a><br/> <input id="btn_remove_' . $iAttId . '" type="button" class="btn_hidden" value="Delete" onClick="RemoveAttachment(' . $iAttId . ');"/> </div>'); $oPage->add_ready_script("\$('#attachment_plugin').trigger('add_attachment', [{$iAttId}, '" . addslashes($sFileName) . "']);"); } } } $oPage->add('</span>'); $oPage->add('<div style="clear:both"></div>'); $sMaxUpload = $this->GetMaxUpload(); $oPage->p(Dict::S('Attachments:AddAttachment') . '<input type="file" name="file" id="file"><span style="display:none;" id="attachment_loading"> <img src="../images/indicator.gif"></span> ' . $sMaxUpload); $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.iframe-transport.js'); $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.fileupload.js'); $oPage->add_ready_script(<<<EOF \$('#file').fileupload({ \t\turl: GetAbsoluteUrlModulesRoot()+'itop-attachments/ajax.attachment.php', \t\tformData: { operation: 'add', temp_id: '{$sTempId}', obj_class: '{$sClass}' }, dataType: 'json', \t\tpasteZone: null, // Don't accept files via Chrome's copy/paste done: function (e, data) { \t\t\tif(typeof(data.result.error) != 'undefined') \t\t\t{ \t\t\t\tif(data.result.error != '') \t\t\t\t{ \t\t\t\t\talert(data.result.error); \t\t\t\t} \t\t\t\telse \t\t\t\t{ \t\t\t\t\tvar sDownloadLink = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=download_document&class=Attachment&id='+data.result.att_id+'&field=contents'; \t\t\t\t\t\$('#attachments').append('<div class="attachment" id="display_attachment_'+data.result.att_id+'"><a data-preview="'+data.result.preview+'" href="'+sDownloadLink+'"><img src="'+data.result.icon+'"><br/>'+data.result.msg+'<input id="attachment_'+data.result.att_id+'" type="hidden" name="attachments[]" value="'+data.result.att_id+'"/></a><br/><input type="button" class="btn_hidden" value="{$sDeleteBtn}" onClick="RemoveAttachment('+data.result.att_id+');"/></div>'); \t\t\t\t\tif({$sIsDeleteEnabled}) \t\t\t\t\t{ \t\t\t\t\t\t\$('#display_attachment_'+data.result.att_id).hover( function() { \$(this).children(':button').toggleClass('btn_hidden'); } ); \t\t\t\t\t} \t\t\t\t\t\$('#attachment_plugin').trigger('add_attachment', [data.result.att_id, data.result.msg]); \t\t\t\t} \t\t\t} }, start: function() { \t\$('#attachment_loading').show(); \t\t}, stop: function() { \t\$('#attachment_loading').hide(); \t\t} }); \t\$(document).bind('dragover', function (e) { \t\tvar bFiles = false; \t\tif (e.dataTransfer && e.dataTransfer.types) \t\t{ \t\t\tfor (var i = 0; i < e.dataTransfer.types.length; i++) \t\t\t{ \t\t\t\tif (e.dataTransfer.types[i] == "application/x-moz-nativeimage") \t\t\t\t{ \t\t\t\t\tbFiles = false; // mozilla contains "Files" in the types list when dragging images inside the page, but it also contains "application/x-moz-nativeimage" before \t\t\t\t\tbreak; \t\t\t\t} \t\t\t\t \t\t\t\tif (e.dataTransfer.types[i] == "Files") \t\t\t\t{ \t\t\t\t\tbFiles = true; \t\t\t\t\tbreak; \t\t\t\t} \t\t\t} \t\t} \t \t\tif (!bFiles) return; // Not dragging files \t\t \t\tvar dropZone = \$('#file').closest('fieldset'); \t\tif (!dropZone.is(':visible')) \t\t{ \t\t\t// Hidden, but inside an inactive tab? Higlight the tab \t\t\tvar sTabId = dropZone.closest('.ui-tabs-panel').attr('aria-labelledby'); \t\t\tdropZone = \$('#'+sTabId).closest('li'); \t\t} \t timeout = window.dropZoneTimeout; \t if (!timeout) { \t dropZone.addClass('drag_in'); \t } else { \t clearTimeout(timeout); \t } \t window.dropZoneTimeout = setTimeout(function () { \t window.dropZoneTimeout = null; \t dropZone.removeClass('drag_in'); \t }, 300); \t}); EOF ); $oPage->p('<span style="display:none;" id="attachment_loading">Loading, please wait...</span>'); $oPage->p('<input type="hidden" id="attachment_plugin" name="attachment_plugin"/>'); if ($this->m_bDeleteEnabled) { $oPage->add_ready_script('$(".attachment").hover( function() {$(this).children(":button").toggleClass("btn_hidden"); } );'); } } else { $oPage->add('<span id="attachments">'); if ($oSet->Count() == 0) { $oPage->add(Dict::S('Attachments:NoAttachment')); } else { while ($oAttachment = $oSet->Fetch()) { $iAttId = $oAttachment->GetKey(); $oDoc = $oAttachment->Get('contents'); $sFileName = $oDoc->GetFileName(); $sIcon = utils::GetAbsoluteUrlAppRoot() . AttachmentPlugIn::GetFileIcon($sFileName); $sPreview = $oDoc->IsPreviewAvailable() ? 'true' : 'false'; $sDownloadLink = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=download_document&class=Attachment&id=' . $iAttId . '&field=contents'; $oPage->add('<div class="attachment" id="attachment_' . $iAttId . '"><a data-preview="' . $sPreview . '" href="' . $sDownloadLink . '"><img src="' . $sIcon . '"><br/>' . $sFileName . '</a><input type="hidden" name="attachments[]" value="' . $iAttId . '"/><br/> </div>'); } } $oPage->add('</span>'); } $oPage->add('</fieldset>'); $sPreviewNotAvailable = addslashes(Dict::S('Attachments:PreviewNotAvailable')); $iMaxWidth = MetaModel::GetModuleSetting('itop-attachments', 'preview_max_width', 290); $oPage->add_ready_script("\$(document).tooltip({ items: '.attachment a', position: { my: 'left top', at: 'right top', using: function( position, feedback ) { \$( this ).css( position ); }}, content: function() { if (\$(this).attr('data-preview') == 'true') { return('<img style=\"max-width:{$iMaxWidth}px\" src=\"'+\$(this).attr('href')+'\"></img>');} else { return '{$sPreviewNotAvailable}'; }}});"); }
/** * Display the graph inside the given page, with the "filter" drawer above it * @param WebPage $oP * @param hash $aResults * @param string $sRelation * @param ApplicationContext $oAppContext * @param array $aExcludedObjects */ function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects = array(), $sObjClass = null, $iObjKey = null, $sContextKey, $aContextParams = array()) { $aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams); $aExcludedByClass = array(); foreach ($aExcludedObjects as $oObj) { if (!array_key_exists(get_class($oObj), $aExcludedByClass)) { $aExcludedByClass[get_class($oObj)] = array(); } $aExcludedByClass[get_class($oObj)][] = $oObj->GetKey(); } $oP->add("<div class=\"not-printable\">\n"); $oP->add("<div id=\"ds_flash\" class=\"SearchDrawer\" style=\"display:none;\">\n"); if (!$oP->IsPrintableVersion()) { $oP->add_ready_script(<<<EOF \t\$( "#tabbedContent_0" ).tabs({ heightStyle: "fill" }); EOF ); } $oP->add_ready_script(<<<EOF \t\$("#dh_flash").click( function() { \t\t\$("#ds_flash").slideToggle('normal', function() { \$("#ds_flash").parent().resize(); \$("#dh_flash").trigger('toggle_complete'); } ); \t\t\$("#dh_flash").toggleClass('open'); \t}); \$('#ReloadMovieBtn').button().button('disable'); EOF ); $aSortedElements = array(); foreach ($aResults as $sClassIdx => $aObjects) { foreach ($aObjects as $oCurrObj) { $sSubClass = get_class($oCurrObj); $aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass); } } asort($aSortedElements); $idx = 0; foreach ($aSortedElements as $sSubClass => $sClassName) { $oP->add("<span style=\"padding-right:2em; white-space:nowrap;\"><input type=\"checkbox\" id=\"exclude_{$idx}\" name=\"excluded[]\" value=\"{$sSubClass}\" checked onChange=\"\$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_{$idx}\"> " . MetaModel::GetClassIcon($sSubClass) . " {$sClassName}</label></span> "); $idx++; } $oP->add("<p style=\"text-align:right\"><button type=\"button\" id=\"ReloadMovieBtn\" onClick=\"DoReload()\">" . Dict::S('UI:Button:Refresh') . "</button></p>"); $oP->add("</div>\n"); $oP->add("<div class=\"HRDrawer\"></div>\n"); $oP->add("<div id=\"dh_flash\" class=\"DrawerHandle\">" . Dict::S('UI:ElementsDisplayed') . "</div>\n"); $oP->add("</div>\n"); // class="not-printable" $aAdditionalContexts = array(); foreach ($aContextDefs as $sKey => $aDefinition) { $aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => array_key_exists('default', $aDefinition) && $aDefinition['default'] == 'yes'); } $sDirection = utils::ReadParam('d', 'horizontal'); $iGroupingThreshold = utils::ReadParam('g', 5); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/fraphael.js'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/jquery.contextMenu.css'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.contextMenu.js'); $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/simple_graph.js'); try { $this->InitFromGraphviz(); $sExportAsPdfURL = ''; $sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_pdf&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up'); $oAppcontext = new ApplicationContext(); $sContext = $oAppContext->GetForLink(); $sDrillDownURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=details&class=%1$s&id=%2$s&' . $sContext; $sExportAsDocumentURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_attachment&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up'); $sLoadFromURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_json&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up'); $sAttachmentExportTitle = ''; if ($sObjClass != null && $iObjKey != null) { $oTargetObj = MetaModel::GetObject($sObjClass, $iObjKey, false); if ($oTargetObj) { $sAttachmentExportTitle = Dict::Format('UI:Relation:AttachmentExportOptions_Name', $oTargetObj->GetName()); } } $sId = 'graph'; $sStyle = ''; if ($oP->IsPrintableVersion()) { // Optimize for printing on A4/Letter vertically $sStyle = 'margin-left:auto; margin-right:auto;'; $oP->add_ready_script("\$('.simple-graph').width(18/2.54*96).resizable({ stop: function() { \$(window).trigger('resized'); }});"); // Default width about 18 cm, since most browsers assume 96 dpi } $oP->add('<div id="' . $sId . '" class="simple-graph" style="' . $sStyle . '"></div>'); $aParams = array('source_url' => $sLoadFromURL, 'sources' => $this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects, 'excluded' => $aExcludedByClass, 'grouping_threshold' => $iGroupingThreshold, 'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')), 'export_as_attachment' => array('url' => $sExportAsDocumentURL, 'label' => Dict::S('UI:Relation:ExportAsAttachment'), 'obj_class' => $sObjClass, 'obj_key' => $iObjKey), 'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')), 'labels' => array('export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'), 'export_as_attachment_title' => $sAttachmentExportTitle, 'export' => Dict::S('UI:Button:Export'), 'cancel' => Dict::S('UI:Button:Cancel'), 'title' => Dict::S('UI:RelationOption:Title'), 'untitled' => Dict::S('UI:RelationOption:Untitled'), 'include_list' => Dict::S('UI:RelationOption:IncludeList'), 'comments' => Dict::S('UI:RelationOption:Comments'), 'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'), 'refresh' => Dict::S('UI:Button:Refresh'), 'check_all' => Dict::S('UI:SearchValue:CheckAll'), 'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'), 'none_selected' => Dict::S('UI:Relation:NoneSelected'), 'nb_selected' => Dict::S('UI:SearchValue:NbSelected'), 'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'), 'zoom' => Dict::S('UI:Relation:Zoom'), 'loading' => Dict::S('UI:Loading')), 'page_format' => array('label' => Dict::S('UI:Relation:PDFExportPageFormat'), 'values' => array('A3' => Dict::S('UI:PageFormat_A3'), 'A4' => Dict::S('UI:PageFormat_A4'), 'Letter' => Dict::S('UI:PageFormat_Letter'))), 'page_orientation' => array('label' => Dict::S('UI:Relation:PDFExportPageOrientation'), 'values' => array('P' => Dict::S('UI:PageOrientation_Portrait'), 'L' => Dict::S('UI:PageOrientation_Landscape'))), 'additional_contexts' => $aAdditionalContexts, 'context_key' => $sContextKey); if (!extension_loaded('gd')) { // PDF export requires GD unset($aParams['export_as_pdf']); } if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey)) { // Export as Attachment requires GD (for building the PDF) AND a valid objclass/objkey couple unset($aParams['export_as_attachment']); } $oP->add_ready_script("\$('#{$sId}').simple_graph(" . json_encode($aParams) . ");"); } catch (Exception $e) { $oP->add('<div>' . $e->getMessage() . '</div>'); } $oP->add_script(<<<EOF \t\t \tfunction DoReload() \t{ \t\t\$('#ReloadMovieBtn').button('disable'); \t\ttry \t\t{ \t\t\tvar aExcluded = []; \t\t\t\$('input[name^=excluded]').each( function() { \t\t\t\tif (!\$(this).prop('checked')) \t\t\t\t{ \t\t\t\t\taExcluded.push(\$(this).val()); \t\t\t\t} \t\t\t} ); \t\t\t\$('#graph').simple_graph('option', {excluded_classes: aExcluded}); \t\t\t\$('#graph').simple_graph('reload'); \t\t} \t\tcatch(err) \t\t{ \t\t\talert(err); \t\t} \t} EOF ); }
/** * Get the HTML fragment corresponding to the ext key editing widget * @param WebPage $oP The web page used for all the output * @param Hash $aArgs Extra context arguments * @return string The HTML fragment to be inserted into the page */ public function Display(WebPage $oPage, $iMaxComboLength, $bAllowTargetCreation, $sTitle, $oAllowedValues, $value, $iInputId, $bMandatory, $sFieldName, $sFormPrefix = '', $aArgs = array(), $bSearchMode = null, $sDisplayStyle = 'select', $bSearchMultiple = true) { if (!is_null($bSearchMode)) { $this->bSearchMode = $bSearchMode; } $sTitle = addslashes($sTitle); $oPage->add_linked_script('../js/extkeywidget.js'); $oPage->add_linked_script('../js/forms-json-utils.js'); $bCreate = !$this->bSearchMode && !MetaModel::IsAbstract($this->sTargetClass) && (UserRights::IsActionAllowed($this->sTargetClass, UR_ACTION_BULK_MODIFY) && $bAllowTargetCreation); $bExtensions = true; $sMessage = Dict::S('UI:Message:EmptyList:UseSearchForm'); $sAttrFieldPrefix = $this->bSearchMode ? '' : 'attr_'; $sHTMLValue = "<span style=\"white-space:nowrap\">"; // no wrap $sFilter = addslashes($oAllowedValues->GetFilter()->ToOQL()); if ($this->bSearchMode) { $sWizHelper = 'null'; $sWizHelperJSON = "''"; $sJSSearchMode = 'true'; } else { if (isset($aArgs['wizHelper'])) { $sWizHelper = $aArgs['wizHelper']; } else { $sWizHelper = 'oWizardHelper' . $sFormPrefix; } $sWizHelperJSON = $sWizHelper . '.UpdateWizardToJSON()'; $sJSSearchMode = 'false'; } if (is_null($oAllowedValues)) { throw new Exception('Implementation: null value for allowed values definition'); } elseif ($oAllowedValues->Count() < $iMaxComboLength) { // Discrete list of values, use a SELECT or RADIO buttons depending on the config switch ($sDisplayStyle) { case 'radio': case 'radio_horizontal': case 'radio_vertical': $sValidationField = "<span id=\"v_{$this->iId}\"></span>"; $sHTMLValue = ''; $bVertical = $sDisplayStyle != 'radio_horizontal'; $bExtensions = false; $oAllowedValues->Rewind(); $aAllowedValues = array(); while ($oObj = $oAllowedValues->Fetch()) { $aAllowedValues[$oObj->GetKey()] = $oObj->GetName(); } $sHTMLValue = $oPage->GetRadioButtons($aAllowedValues, $value, $this->iId, "{$sAttrFieldPrefix}{$sFieldName}", $bMandatory, $bVertical, $sValidationField); $aEventsList[] = 'change'; break; case 'select': case 'list': default: $sSelectMode = 'true'; $sHelpText = ''; //$this->oAttDef->GetHelpOnEdition(); if ($this->bSearchMode) { if ($bSearchMultiple) { $sHTMLValue = "<select class=\"multiselect\" multiple title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}[]\" id=\"{$this->iId}\">\n"; } else { $sHTMLValue = "<select title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"{$this->iId}\">\n"; $sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : Dict::S('UI:SearchValue:Any'); $sHTMLValue .= "<option value=\"\">{$sDisplayValue}</option>\n"; } } else { $sHTMLValue = "<select title=\"{$sHelpText}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" id=\"{$this->iId}\">\n"; $sHTMLValue .= "<option value=\"\">" . Dict::S('UI:SelectOne') . "</option>\n"; } $oAllowedValues->Rewind(); while ($oObj = $oAllowedValues->Fetch()) { $key = $oObj->GetKey(); $display_value = $oObj->GetName(); if ($oAllowedValues->Count() == 1 && $bMandatory == 'true') { // When there is only once choice, select it by default $sSelected = ' selected'; } else { $sSelected = is_array($value) && in_array($key, $value) || $value == $key ? ' selected' : ''; } $sHTMLValue .= "<option value=\"{$key}\"{$sSelected}>{$display_value}</option>\n"; } $sHTMLValue .= "</select>\n"; if ($this->bSearchMode && $bSearchMultiple) { $aOptions = array('header' => true, 'checkAllText' => Dict::S('UI:SearchValue:CheckAll'), 'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'), 'noneSelectedText' => Dict::S('UI:SearchValue:Any'), 'selectedText' => Dict::S('UI:SearchValue:NbSelected'), 'selectedList' => 1); $sJSOptions = json_encode($aOptions); $oPage->add_ready_script("\$('.multiselect').multiselect({$sJSOptions});"); } $oPage->add_ready_script(<<<EOF \t\toACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '{$sFilter}', '{$sTitle}', true, {$sWizHelper}, '{$this->sAttCode}', {$sJSSearchMode}); \t\toACWidget_{$this->iId}.emptyHtml = "<div style=\\"background: #fff; border:0; text-align:center; vertical-align:middle;\\"><p>{$sMessage}</p></div>"; \t\t\$('#{$this->iId}').bind('update', function() { oACWidget_{$this->iId}.Update(); } ); \t\t\$('#{$this->iId}').bind('change', function() { \$(this).trigger('extkeychange') } ); EOF ); } // Switch } else { // Too many choices, use an autocomplete $sSelectMode = 'false'; // Check that the given value is allowed $oSearch = $oAllowedValues->GetFilter(); $oSearch->AddCondition('id', $value); $oSet = new DBObjectSet($oSearch); if ($oSet->Count() == 0) { $value = null; } if (is_null($value) || $value == 0) { $sDisplayValue = isset($aArgs['sDefaultValue']) ? $aArgs['sDefaultValue'] : ''; } else { $sDisplayValue = $this->GetObjectName($value); } $iMinChars = isset($aArgs['iMinChars']) ? $aArgs['iMinChars'] : 3; //@@@ $this->oAttDef->GetMinAutoCompleteChars(); $iFieldSize = isset($aArgs['iFieldSize']) ? $aArgs['iFieldSize'] : 30; //@@@ $this->oAttDef->GetMaxSize(); // the input for the auto-complete $sHTMLValue = "<input count=\"" . $oAllowedValues->Count() . "\" type=\"text\" id=\"label_{$this->iId}\" size=\"{$iFieldSize}\" value=\"{$sDisplayValue}\"/> "; $sHTMLValue .= "<img id=\"mini_search_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_search.gif\" onClick=\"oACWidget_{$this->iId}.Search();\"/> "; // another hidden input to store & pass the object's Id $sHTMLValue .= "<input type=\"hidden\" id=\"{$this->iId}\" name=\"{$sAttrFieldPrefix}{$sFieldName}\" value=\"" . htmlentities($value, ENT_QUOTES, 'UTF-8') . "\" />\n"; $JSSearchMode = $this->bSearchMode ? 'true' : 'false'; // Scripts to start the autocomplete and bind some events to it $oPage->add_ready_script(<<<EOF \t\toACWidget_{$this->iId} = new ExtKeyWidget('{$this->iId}', '{$this->sTargetClass}', '{$sFilter}', '{$sTitle}', false, {$sWizHelper}, '{$this->sAttCode}', {$sJSSearchMode}); \t\toACWidget_{$this->iId}.emptyHtml = "<div style=\\"background: #fff; border:0; text-align:center; vertical-align:middle;\\"><p>{$sMessage}</p></div>"; \t\t\$('#label_{$this->iId}').autocomplete(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', { scroll:true, minChars:{$iMinChars}, autoFill:false, matchContains:true, mustMatch: true, keyHolder:'#{$this->iId}', extraParams:{operation:'ac_extkey', sTargetClass:'{$this->sTargetClass}',sFilter:'{$sFilter}',bSearchMode:{$JSSearchMode}, json: function() { return {$sWizHelperJSON}; } }}); \t\t\$('#label_{$this->iId}').keyup(function() { if (\$(this).val() == '') { \$('#{$this->iId}').val(''); } } ); // Useful for search forms: empty value in the "label", means no value, immediatly ! \t\t\$('#label_{$this->iId}').result( function(event, data, formatted) { OnAutoComplete('{$this->iId}', event, data, formatted); } ); \t\t\$('#{$this->iId}').bind('update', function() { oACWidget_{$this->iId}.Update(); } ); \t\tif (\$('#ac_dlg_{$this->iId}').length == 0) \t\t{ \t\t\t\$('body').append('<div id="ac_dlg_{$this->iId}"></div>'); \t\t} EOF ); } if ($bExtensions && MetaModel::IsHierarchicalClass($this->sTargetClass) !== false) { $sHTMLValue .= "<img id=\"mini_tree_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_tree.gif\" onClick=\"oACWidget_{$this->iId}.HKDisplay();\"/> "; $oPage->add_ready_script(<<<EOF \t\t\tif (\$('#ac_tree_{$this->iId}').length == 0) \t\t\t{ \t\t\t\t\$('body').append('<div id="ac_tree_{$this->iId}"></div>'); \t\t\t}\t\t EOF ); } if ($bCreate && $bExtensions) { $sHTMLValue .= "<img id=\"mini_add_{$this->iId}\" style=\"border:0;vertical-align:middle;cursor:pointer;\" src=\"../images/mini_add.gif\" onClick=\"oACWidget_{$this->iId}.CreateObject();\"/> "; $oPage->add_ready_script(<<<EOF \t\tif (\$('#ajax_{$this->iId}').length == 0) \t\t{ \t\t\t\$('body').append('<div id="ajax_{$this->iId}"></div>'); \t\t} EOF ); } if ($sDisplayStyle == 'select' || $sDisplayStyle == 'list') { $sHTMLValue .= "<span id=\"v_{$this->iId}\"></span>"; } $sHTMLValue .= "</span>"; // end of no wrap return $sHTMLValue; }
public function Display(WebPage $oPage) { $oPage->add_style(<<<EOF #params_summary { \theight: 200px; \toverflow: auto; } #params_summary div { \twidth:100%; \tmargin-top:0; \tpadding-top: 0.5em; \tpadding-left: 0; } #params_summary div ul { \tmargin-left:0; \tpadding-left: 20px; } #params_summary div.closed ul { \tdisplay:none; } #params_summary div li { \tlist-style: none; \twidth: 100%; \tmargin-left:0; \tpadding-left: 0em; } .title { \tpadding-left: 20px; \tfont-weight: bold; \tcursor: pointer; \tbackground: url(../images/minus.gif) 2px 2px no-repeat; } #params_summary div.closed .title { \tbackground: url(../images/plus.gif) 2px 2px no-repeat; } #progress_content { \theight: 200px; \toverflow: auto; \ttext-align: center; } #installation_progress { \tdisplay: none; } EOF ); $aInstallParams = $this->BuildConfig(); $sMode = $aInstallParams['mode']; $sPreinstallationPhase = ''; $sDestination = ITOP_APPLICATION . ($sMode == 'install' ? ' version ' . ITOP_VERSION . ' is about to be installed ' : ' is about to be upgraded '); $sDBDescription = ' <b>existing</b> database <b>' . $aInstallParams['database']['name'] . '</b>'; if ($sMode == 'install' && $this->oWizard->GetParameter('create_db') == 'yes') { $sDBDescription = ' <b>new</b> database <b>' . $aInstallParams['database']['name'] . '</b>'; } $sDestination .= 'into the ' . $sDBDescription . ' on the server <b>' . $aInstallParams['database']['server'] . '</b>.'; $oPage->add('<h2>' . $sDestination . '</h2>'); $oPage->add('<fieldset id="summary"><legend>Installation Parameters</legend>'); $oPage->add('<div id="params_summary">'); $oPage->add('<div class="closed"><span class="title">Database Parameters</span><ul>'); $oPage->add('<li>Server Name: ' . $aInstallParams['database']['server'] . '</li>'); $oPage->add('<li>DB User Name: ' . $aInstallParams['database']['user'] . '</li>'); $oPage->add('<li>DB user password: '******'database']['pwd'] . '</li>'); if ($sMode == 'install' && $this->oWizard->GetParameter('create_db') == 'yes') { $oPage->add('<li>Database Name: ' . $aInstallParams['database']['name'] . ' (will be created)</li>'); } else { $oPage->add('<li>Database Name: ' . $aInstallParams['database']['name'] . '</li>'); } if ($aInstallParams['database']['prefix'] != '') { $oPage->add('<li>Prefix for the ' . ITOP_APPLICATION . ' tables: ' . $aInstallParams['database']['prefix'] . '</li>'); } else { $oPage->add('<li>Prefix for the ' . ITOP_APPLICATION . ' tables: none</li>'); } $oPage->add('</ul></div>'); $oPage->add('<div><span class="title">Data Model Configuration</span>'); $oPage->add($this->oWizard->GetParameter('display_choices')); $oPage->add('</div>'); $oPage->add('<div class="closed"><span class="title">Other Parameters</span><ul>'); if ($sMode == 'install') { $oPage->add('<li>Default language: ' . $aInstallParams['language'] . '</li>'); } $oPage->add('<li>URL to access the application: ' . $aInstallParams['url'] . '</li>'); if ($aInstallParams['sample_data'] == 'yes') { $oPage->add('<li>Sample data will be loaded into the database.</li>'); } if ($aInstallParams['old_addon']) { $oPage->add('<li>Compatibility mode: Using the version 1.2 of the UserRightsProfiles add-on.</li>'); } $oPage->add('</ul></div>'); if ($sMode == 'install') { $oPage->add('<div class="closed"><span class="title">Admininistrator Account</span><ul>'); $oPage->add('<li>Login: '******'admin_account']['user'] . '</li>'); $oPage->add('<li>Password: '******'admin_account']['pwd'] . '</li>'); $oPage->add('<li>Language: ' . $aInstallParams['admin_account']['language'] . '</li>'); $oPage->add('</ul></div>'); } $aMiscOptions = $aInstallParams['options']; if (count($aMiscOptions) > 0) { $oPage->add('<div class="closed"><span class="title">Miscellaneous Options</span><ul>'); foreach ($aMiscOptions as $sKey => $sValue) { $oPage->add('<li>' . $sKey . ': ' . $sValue . '</li>'); } $oPage->add('</ul></div>'); } $aSelectedModules = $aInstallParams['selected_modules']; if (isset($aMiscOptions['generate_config'])) { $oDoc = new DOMDocument('1.0', 'UTF-8'); $oDoc->preserveWhiteSpace = false; $oDoc->formatOutput = true; $oParams = new PHPParameters(); $oParams->LoadFromHash($aInstallParams); $oParams->ToXML($oDoc, null, 'installation'); $sXML = $oDoc->saveXML(); $oPage->add('<div class="closed"><span class="title">XML Config file</span><ul><pre>'); $oPage->add(htmlentities($sXML, ENT_QUOTES, 'UTF-8')); $oPage->add('</pre></ul></div>'); } $oPage->add('</div>'); // params_summary $oPage->add('</fieldset>'); $oPage->add('<fieldset id="installation_progress"><legend>Progress of the installation</legend>'); $oPage->add('<div id="progress_content">'); $oPage->add_linked_script('../setup/jquery.progression.js'); $oPage->add('<p class="center"><span id="setup_msg">Ready to start...</span></p><div style="display:block;margin-left: auto; margin-right:auto;" id="progress">0%</div>'); $oPage->add('</div>'); // progress_content $oPage->add('</fieldset>'); $sJSONData = json_encode($aInstallParams); $oPage->add('<input type="hidden" id="installer_parameters" value="' . htmlentities($sJSONData, ENT_QUOTES, 'UTF-8') . '"/>'); if (!$this->CheckDependencies()) { $oPage->error($this->sDependencyIssue); } $oPage->add_ready_script(<<<EOF \t\$("#params_summary div").addClass('closed'); \t\$("#params_summary .title").click(function() { \$(this).parent().toggleClass('closed'); } ); \t\$("#btn_next").bind("click.install", function(event) { \t\t\t\$('#summary').hide(); \t\t\t\$('#installation_progress').show(); \t\t\t\$(this).attr("disabled", "disabled"); event.preventDefault(); ExecuteStep(""); \t}); \t\$("#wiz_form").data("installation_status", "not started") EOF ); }