1<?php
2// Copyright (C) 2010-2016 Combodo SARL
3//
4//   This file is part of iTop.
5//
6//   iTop is free software; you can redistribute it and/or modify
7//   it under the terms of the GNU Affero General Public License as published by
8//   the Free Software Foundation, either version 3 of the License, or
9//   (at your option) any later version.
10//
11//   iTop is distributed in the hope that it will be useful,
12//   but WITHOUT ANY WARRANTY; without even the implied warranty of
13//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14//   GNU Affero General Public License for more details.
15//
16//   You should have received a copy of the GNU Affero General Public License
17//   along with iTop. If not, see <http://www.gnu.org/licenses/>
18
19
20/**
21 * Class NiceWebPage
22 *
23 * @copyright   Copyright (C) 2010-2016 Combodo SARL
24 * @license     http://opensource.org/licenses/AGPL-3.0
25 */
26
27require_once(APPROOT."/application/webpage.class.inc.php");
28/**
29 * Web page with some associated CSS and scripts (jquery) for a fancier display
30 */
31class NiceWebPage extends WebPage
32{
33	var $m_aReadyScripts;
34	var $m_sRootUrl;
35
36    public function __construct($s_title, $bPrintable = false)
37    {
38        parent::__construct($s_title, $bPrintable);
39		$this->m_aReadyScripts = array();
40		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-3.3.1.min.js');
41		if(utils::IsDevelopmentEnvironment()) // Needed since many other plugins still rely on oldies like $.browser
42		{
43			$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-migrate-3.0.1.dev.js');
44		}
45		else
46		{
47			$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-migrate-3.0.1.prod.min.js');
48		}
49		$this->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/ui-lightness/jquery-ui-1.11.4.custom.css');
50		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery-ui-1.11.4.custom.min.js');
51		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
52		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/hovertip.js');
53		// table sorting
54		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablesorter.js');
55		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablesorter.pager.js');
56		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.tablehover.js');
57	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/table-selectable-lines.js');
58		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/field_sorter.js');
59		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/datatable.js');
60		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.positionBy.js');
61		$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/jquery.popupmenu.js');
62	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/searchformforeignkeys.js');
63	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/latinise/latinise.min.js');
64	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_handler.js');
65	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_handler_history.js');
66	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria.js');
67	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_raw.js');
68	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_string.js');
69	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_external_field.js');
70	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_numeric.js');
71	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_enum.js');
72	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_tag_set.js');
73	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_external_key.js');
74	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_hierarchical_key.js');
75	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_date_abstract.js');
76	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_date.js');
77	    $this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/search/search_form_criteria_date_time.js');
78
79	    $this->add_dict_entries('UI:Combo');
80
81	    $this->add_ready_script(
82<<< EOF
83	//add new widget called TruncatedList to properly display truncated lists when they are sorted
84	$.tablesorter.addWidget({
85		// give the widget a id
86		id: "truncatedList",
87		// format is called when the on init and when a sorting has finished
88		format: function(table)
89		{
90			// Check if there is a "truncated" line
91			this.truncatedList = false;
92			if ($("tr td.truncated",table).length > 0)
93			{
94				this.truncatedList = true;
95			}
96			if (this.truncatedList)
97			{
98				$("tr td",table).removeClass('truncated');
99				$("tr:last td",table).addClass('truncated');
100			}
101		}
102	});
103
104	$.tablesorter.addWidget({
105		// give the widget a id
106		id: "myZebra",
107		// format is called when the on init and when a sorting has finished
108		format: function(table)
109		{
110			// Replace the 'red even' lines by 'red_even' since most browser do not support 2 classes selector in CSS, etc..
111			$("tbody tr:even",table).addClass('even');
112			$("tbody tr.red:even",table).removeClass('red').removeClass('even').addClass('red_even');
113			$("tbody tr.orange:even",table).removeClass('orange').removeClass('even').addClass('orange_even');
114			$("tbody tr.green:even",table).removeClass('green').removeClass('even').addClass('green_even');
115			// In case we sort again the table, we need to remove the added 'even' classes on odd rows
116			$("tbody tr:odd",table).removeClass('even');
117			$("tbody tr.red_even:odd",table).removeClass('even').removeClass('red_even').addClass('red');
118			$("tbody tr.orange_even:odd",table).removeClass('even').removeClass('orange_even').addClass('orange');
119			$("tbody tr.green_even:odd",table).removeClass('even').removeClass('green_even').addClass('green');
120		}
121	});
122	$("table.listResults").tableHover(); // hover tables
123EOF
124		);
125		$this->add_saas("css/light-grey.scss");
126
127		$this->m_sRootUrl = $this->GetAbsoluteUrlAppRoot();
128     	$sAbsURLAppRoot = addslashes($this->m_sRootUrl);
129    	$sAbsURLModulesRoot = addslashes($this->GetAbsoluteUrlModulesRoot());
130    	$sEnvironment = addslashes(utils::GetCurrentEnvironment());
131
132		$sAppContext = addslashes($this->GetApplicationContext());
133
134		$this->add_script(
135<<<EOF
136function GetAbsoluteUrlAppRoot()
137{
138	return '$sAbsURLAppRoot';
139}
140
141function GetAbsoluteUrlModulesRoot()
142{
143	return '$sAbsURLModulesRoot';
144}
145
146function GetAbsoluteUrlModulePage(sModule, sPage, aArguments)
147{
148	// aArguments is optional, it default to an empty hash
149	aArguments = typeof aArguments !== 'undefined' ? aArguments : {};
150
151	var sUrl = '$sAbsURLAppRoot'+'pages/exec.php?exec_module='+sModule+'&exec_page='+sPage+'&exec_env='+'$sEnvironment';
152	for (var sArgName in aArguments)
153	{
154		if (aArguments.hasOwnProperty(sArgName))
155		{
156			sUrl = sUrl + '&'+sArgName+'='+aArguments[sArgname];
157		}
158	}
159	return sUrl;
160}
161
162function AddAppContext(sURL)
163{
164	var sContext = '$sAppContext';
165	if (sContext.length > 0)
166	{
167		if (sURL.indexOf('?') == -1)
168		{
169			return sURL+'?'+sContext;
170		}
171		return sURL+'&'+sContext;
172	}
173	return sURL;
174}
175EOF
176		);
177	}
178
179    public function SetRootUrl($sRootUrl)
180    {
181    	$this->m_sRootUrl = $sRootUrl;
182    }
183
184	public function small_p($sText)
185	{
186		$this->add("<p style=\"font-size:smaller\">$sText</p>\n");
187	}
188
189	public function GetAbsoluteUrlAppRoot()
190	{
191		return utils::GetAbsoluteUrlAppRoot();
192	}
193
194	public function GetAbsoluteUrlModulesRoot()
195	{
196		return utils::GetAbsoluteUrlModulesRoot();
197	}
198
199	function GetApplicationContext()
200	{
201		$oAppContext = new ApplicationContext();
202		return $oAppContext->GetForLink();
203	}
204
205	// By Rom, used by CSVImport and Advanced search
206	public function MakeClassesSelect($sName, $sDefaultValue, $iWidthPx, $iActionCode = null)
207	{
208		// $aTopLevelClasses = array('bizService', 'bizContact', 'logInfra', 'bizDocument');
209		// These are classes wich root class is cmdbAbstractObject !
210		$this->add("<select id=\"select_$sName\" name=\"$sName\">");
211		$aValidClasses = array();
212		foreach(MetaModel::GetClasses('bizmodel') as $sClassName)
213		{
214			if (is_null($iActionCode) || UserRights::IsActionAllowed($sClassName, $iActionCode))
215			{
216				$sSelected = ($sClassName == $sDefaultValue) ? " SELECTED" : "";
217				$sDescription = MetaModel::GetClassDescription($sClassName);
218				$sDisplayName = MetaModel::GetName($sClassName);
219				$aValidClasses[$sDisplayName] = "<option style=\"width: ".$iWidthPx." px;\" title=\"$sDescription\" value=\"$sClassName\"$sSelected>$sDisplayName</option>";
220			}
221		}
222		ksort($aValidClasses);
223		$this->add(implode("\n", $aValidClasses));
224
225		$this->add("</select>");
226	}
227
228	// By Rom, used by Advanced search
229	public function add_select($aChoices, $sName, $sDefaultValue, $iWidthPx)
230	{
231		$this->add("<select id=\"select_$sName\" name=\"$sName\">");
232		foreach($aChoices as $sKey => $sValue)
233		{
234			$sSelected = ($sKey == $sDefaultValue) ? " SELECTED" : "";
235			$this->add("<option style=\"width: ".$iWidthPx." px;\" value=\"".htmlspecialchars($sKey)."\"$sSelected>".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."</option>");
236		}
237		$this->add("</select>");
238	}
239
240	public function add_ready_script($sScript)
241	{
242		$this->m_aReadyScripts[] = $sScript;
243	}
244
245		/**
246	 * Outputs (via some echo) the complete HTML page by assembling all its elements
247	 */
248    public function output()
249    {
250		//$this->set_base($this->m_sRootUrl.'pages/');
251        if (count($this->m_aReadyScripts)>0)
252        {
253			$this->add_script("\$(document).ready(function() {\n".implode("\n", $this->m_aReadyScripts)."\n});");
254		}
255		parent::output();
256	}
257}
258
259?>
260