فهرست منبع

Experimental support of PDF output for iTop pages, provided that mPDF is installed in lib/MPDF [1876]

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1878 a333f486-631f-4898-b8df-5754b55c2be0
dflaven 13 سال پیش
والد
کامیت
10c4a132fe
2فایلهای تغییر یافته به همراه478 افزوده شده و 415 حذف شده
  1. 412 415
      application/itopwebpage.class.inc.php
  2. 66 0
      application/webpage.class.inc.php

+ 412 - 415
application/itopwebpage.class.inc.php

@@ -1,26 +1,26 @@
 <?php
 // Copyright (C) 2010 Combodo SARL
 //
-//   This program is free software; you can redistribute it and/or modify
-//   it under the terms of the GNU General Public License as published by
-//   the Free Software Foundation; version 3 of the License.
+//	 This program is free software; you can redistribute it and/or modify
+//	 it under the terms of the GNU General Public License as published by
+//	 the Free Software Foundation; version 3 of the License.
 //
-//   This program is distributed in the hope that it will be useful,
-//   but WITHOUT ANY WARRANTY; without even the implied warranty of
-//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//   GNU General Public License for more details.
+//	 This program is distributed in the hope that it will be useful,
+//	 but WITHOUT ANY WARRANTY; without even the implied warranty of
+//	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//	 GNU General Public License for more details.
 //
-//   You should have received a copy of the GNU General Public License
-//   along with this program; if not, write to the Free Software
-//   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//	 You should have received a copy of the GNU General Public License
+//	 along with this program; if not, write to the Free Software
+//	 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 /**
  * Class iTopWebPage
  *
- * @author      Erwan Taloc <erwan.taloc@combodo.com>
- * @author      Romain Quetiez <romain.quetiez@combodo.com>
- * @author      Denis Flaven <denis.flaven@combodo.com>
- * @license     http://www.opensource.org/licenses/gpl-3.0.html LGPL
+ * @author		Erwan Taloc <erwan.taloc@combodo.com>
+ * @author		Romain Quetiez <romain.quetiez@combodo.com>
+ * @author		Denis Flaven <denis.flaven@combodo.com>
+ * @license		http://www.opensource.org/licenses/gpl-3.0.html LGPL
  */
 
 require_once(APPROOT."/application/nicewebpage.class.inc.php");
@@ -32,13 +32,13 @@ require_once(APPROOT."/application/user.preferences.class.inc.php");
 class iTopWebPage extends NiceWebPage
 {
 	private $m_sMenu;
-//	private $m_currentOrganization;
+	//	private $m_currentOrganization;
 	private $m_aTabs;
 	private $m_sCurrentTabContainer;
 	private $m_sCurrentTab;
 	private $m_sMessage;
 	private $m_sInitScript;
-	
+
 	public function __construct($sTitle)
 	{
 		parent::__construct($sTitle);
@@ -83,46 +83,46 @@ class iTopWebPage extends NiceWebPage
 		// Layout
 		paneSize = GetUserPreference('menu_size', 300)
 		myLayout = $('body').layout({
-			west : 	{
+			west :	{
 						minSize: 200, size: paneSize, spacing_open: 16, spacing_close: 16, slideTrigger_open: "mouseover", hideTogglerOnSlide: true,
-					 	onclose_end: function(name, elt, state, options, layout)
-					 	{
-					 			if (state.isSliding == false)
-					 			{
-					 				SetUserPreference('menu_pane', 'closed', true);
-					 			}
-					 	},
-					 	onresize_end: function(name, elt, state, options, layout)
-					 	{
-					 			if (state.isSliding == false)
-					 			{
-					 				SetUserPreference('menu_size', state.size, true);
-					 			}
-					 	},
-					 				
-					 	onopen_end: function(name, elt, state, options, layout)
-					 	{
-					 		if (state.isSliding == false)
-					 		{
-					 			SetUserPreference('menu_pane', 'open', true);
-					 		}
-					 	}
+						onclose_end: function(name, elt, state, options, layout)
+						{
+								if (state.isSliding == false)
+								{
+									SetUserPreference('menu_pane', 'closed', true);
+								}
+						},
+						onresize_end: function(name, elt, state, options, layout)
+						{
+								if (state.isSliding == false)
+								{
+									SetUserPreference('menu_size', state.size, true);
+								}
+						},
+									
+						onopen_end: function(name, elt, state, options, layout)
+						{
+							if (state.isSliding == false)
+							{
+								SetUserPreference('menu_pane', 'open', true);
+							}
+						}
 					},
-			center:	{
-					 	onresize_end: function(name, elt, state, options, layout)
-					 	{
-					 			$('.v-resizable').each( function() {
-					 				var fixedWidth = $(this).parent().innerWidth() - 6;
-					 				$(this).width(fixedWidth);
-					 				// Make sure it cannot be resized horizontally
-									$(this).resizable('options', { minWidth: fixedWidth, maxWidth:  fixedWidth });
+			center: {
+						onresize_end: function(name, elt, state, options, layout)
+						{
+								$('.v-resizable').each( function() {
+									var fixedWidth = $(this).parent().innerWidth() - 6;
+									$(this).width(fixedWidth);
+									// Make sure it cannot be resized horizontally
+									$(this).resizable('options', { minWidth: fixedWidth, maxWidth:	fixedWidth });
 									// Now adjust all the child 'items'
-					 				var innerWidth = $(this).innerWidth() - 10;
-					 				$(this).find('.item').width(innerWidth);
-					 			});
-					 	}
+									var innerWidth = $(this).innerWidth() - 10;
+									$(this).find('.item').width(innerWidth);
+								});
+						}
 				
-				 	}
+					}
 		});
 		myLayout.addPinBtn( "#tPinMenu", "west" );
 		//myLayout.open( "west" );
@@ -138,7 +138,7 @@ class iTopWebPage extends NiceWebPage
 		// Tabs, using JQuery BBQ to store the history
 		// The "tab widgets" to handle.
 		var tabs = $('div[id^=tabbedContent]');
-		    
+			
 		// This selector will be reused when selecting actual tab widget A elements.
 		var tab_a_selector = 'ul.ui-tabs-nav a';
 		  
@@ -159,16 +159,16 @@ class iTopWebPage extends NiceWebPage
 		alert(err);
 	}
 EOF
-;
+		;
 		$this->add_ready_script(
 <<< EOF
 	//add new widget called TruncatedList to properly display truncated lists when they are sorted
 	$.tablesorter.addWidget({ 
-	    // give the widget a id 
-	    id: "truncatedList", 
-	    // format is called when the on init and when a sorting has finished 
-	    format: function(table)
-	    { 
+		// give the widget a id 
+		id: "truncatedList", 
+		// format is called when the on init and when a sorting has finished 
+		format: function(table)
+		{ 
 			// Check if there is a "truncated" line
 			this.truncatedList = false;  
 			if ($("tr td.truncated",table).length > 0)
@@ -180,17 +180,17 @@ EOF
 				$("tr td",table).removeClass('truncated');
 				$("tr:last td",table).addClass('truncated');
 			}
-	    } 
+		} 
 	});
 		
 	
 	$.tablesorter.addWidget({ 
-	    // give the widget a id 
-	    id: "myZebra", 
-	    // format is called when the on init and when a sorting has finished 
-	    format: function(table)
-	    {
-	    	// Replace the 'red even' lines by 'red_even' since most browser do not support 2 classes selector in CSS, etc..
+		// give the widget a id 
+		id: "myZebra", 
+		// format is called when the on init and when a sorting has finished 
+		format: function(table)
+		{
+			// Replace the 'red even' lines by 'red_even' since most browser do not support 2 classes selector in CSS, etc..
 			$("tbody tr:even",table).addClass('even');
 			$("tbody tr.red:even",table).removeClass('red').removeClass('even').addClass('red_even');
 			$("tbody tr.orange:even",table).removeClass('orange').removeClass('even').addClass('orange_even');
@@ -200,7 +200,7 @@ EOF
 			$("tbody tr.red_even:odd",table).removeClass('even').removeClass('red_even').addClass('red');
 			$("tbody tr.orange_even:odd",table).removeClass('even').removeClass('orange_even').addClass('orange');
 			$("tbody tr.green_even:odd",table).removeClass('even').removeClass('green_even').addClass('green');
-	    } 
+		} 
 	});
 
 	// Adjust initial size
@@ -238,7 +238,7 @@ EOF
 	// Tabs, using JQuery BBQ to store the history
 	// The "tab widgets" to handle.
 	var tabs = $('div[id^=tabbedContent]');
-	    
+		
 	// This selector will be reused when selecting actual tab widget A elements.
 	var tab_a_selector = 'ul.ui-tabs-nav a';
 	  
@@ -325,13 +325,13 @@ EOF
 		{
 			var aSerialized = sTemp.split(',');
 			var sortable = $(this);
-		    $.each(aSerialized, function(i,v) {
-		      var item = $('#menu_'+v);
-		      if (item.length >  0) // Check that the menu exists
-		      {
-		      		sortable.append(item);
-		      }
-		    });
+			$.each(aSerialized, function(i,v) {
+			  var item = $('#menu_'+v);
+			  if (item.length >  0) // Check that the menu exists
+			  {
+					sortable.append(item);
+			  }
+			});
 		}
 	});
 
@@ -354,7 +354,7 @@ EOF
 	
 	$('.caselog_header').click( function () { $(this).toggleClass('open').next('.caselog_entry').toggle(); });
 EOF
-);
+		);
 		$sUserPrefs = appUserPreferences::GetAsJSON();
 		$this->add_script(
 <<<EOF
@@ -399,12 +399,12 @@ EOF
 			if ($('#rawOutput > div').html() != '')
 			{
 				$('#rawOutput').dialog( {autoOpen: true, modal:false});
-			}
-		}
-		
-		function AddAppContext(sURL)
-		{
-			var sContext = '$sAppContext';
+						}
+				}
+				
+				function AddAppContext(sURL)
+				{
+						var sContext = '$sAppContext';
 			if (sContext.length > 0)
 			{
 				if (sURL.indexOf('?') == -1)
@@ -421,22 +421,22 @@ EOF
 		// For disabling the CKEditor at init time when the corresponding textarea is disabled !
 		CKEDITOR.plugins.add( 'disabler',
 		{
-		    init : function( editor )
-		    {
-		        editor.on( 'instanceReady', function(e)
-		        {
-		        	e.removeListener();
-			        $('#'+ editor.name).trigger('update');
-                });
-		    }
-		    
+			init : function( editor )
+			{
+				editor.on( 'instanceReady', function(e)
+				{
+					e.removeListener();
+					$('#'+ editor.name).trigger('update');
+				});
+			}
+			
 		});
 
 EOF
-);
-		
-    	// Build menus from module handlers
-    	//
+		);
+
+		// Build menus from module handlers
+		//
 		foreach(get_declared_classes() as $sPHPClass)
 		{
 			if (is_subclass_of($sPHPClass, 'ModuleHandlerAPI'))
@@ -446,7 +446,7 @@ EOF
 			}
 		}
 	}
-	
+
 	public function AddToMenu($sHtml)
 	{
 		$this->m_sMenu .= $sHtml;
@@ -465,7 +465,7 @@ EOF
 			$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
 			$oSet = new CMDBObjectSet($oSearchFilter);
 			$iCount = $oSet->Count(); // total number of existing Orgs
-			
+				
 			// Now get the list of Orgs to be displayed in the menu
 			$oSearchFilter = DBObjectSearch::FromOQL(ApplicationMenu::GetFavoriteSiloQuery());
 			$oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true);
@@ -481,39 +481,21 @@ EOF
 			// No such dimension/silo => nothing to select
 			$sHtml = '<div id="SiloSelection"><!-- nothing to select --></div>';
 			break;
-			
+					
 			case 1:
 			// Only one possible choice... no selection, but display the value
 			$oOrg = $oSet->Fetch();
 			$sHtml = '<div id="SiloSelection">'.$oOrg->GetName().'</div>';
 			$sHtml .= '';
 			break;
-			
+					
 			default:
 			$sHtml = '';
 			$oAppContext = new ApplicationContext();
 			$iCurrentOrganization = $oAppContext->GetCurrentValue('org_id');
 			$sHtml = '<div id="SiloSelection">';
 			$sHtml .= '<form style="display:inline" action="'.utils::GetAbsoluteUrlAppRoot().'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">';
-/*
-			$sSelected = ($iCurrentOrganization == '') ? ' selected' : '';
-			$sHtml .= '<option value=""'.$sSelected.'>'.Dict::S('UI:AllOrganizations').'</option>';
-			while($oOrg = $oSet->Fetch())
-			{
-				if ($iCurrentOrganization == $oOrg->GetKey())
-				{
-//					$oCurrentOrganization = $oOrg;
-					$sSelected = " selected";
-			
-				}
-				else
-				{
-					$sSelected = "";
-				}
-				$sHtml .= '<option title="'.$oOrg->GetName().'" value="'.$oOrg->GetKey().'"'.$sSelected.'>'.$oOrg->GetName().'</option>';
-			}
-			$sHtml .= '</select>';
-*/
+
 			$sFavoriteOrgs = '';
 			$oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true /* search mode */);
 			$sHtml .= $oWidget->Display($this, 50, false, '', $oSet, $iCurrentOrganization, 'org_id', false, 'c[org_id]', '', array('iFieldSize' => 20, 'iMinChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'), 'sDefaultValue' => Dict::S('UI:AllOrganizations')));
@@ -526,25 +508,25 @@ EOF
 			$sHtml .= '</form>';
 			$sHtml .= '</div>';
 		}
-		return $sHtml;		
+		return $sHtml;
 	}
-	
-    public function DisplayMenu()
-    {
+
+	public function DisplayMenu()
+	{
 		// Display the menu
 		$oAppContext = new ApplicationContext();
 		$iAccordionIndex = 0;
 
 		ApplicationMenu::DisplayMenu($this, $oAppContext->GetAsHash());
-    }
+	}
 
 	/**
 	 * Outputs (via some echo) the complete HTML page by assembling all its elements
 	 */
-    public function output()
-    {
-    	$sAbsURLAppRoot = addslashes($this->m_sRootUrl);
-    	$sAbsURLModulesRoot = addslashes(utils::GetAbsoluteUrlModulesRoot());
+	public function output()
+	{
+		$sAbsURLAppRoot = addslashes($this->m_sRootUrl);
+		$sAbsURLModulesRoot = addslashes(utils::GetAbsoluteUrlModulesRoot());
 		$this->add_script(
 <<<EOF
 function GetAbsoluteUrlAppRoot()
@@ -562,88 +544,96 @@ EOF
 		$this->DisplayMenu(); // Compute the menu
 
 		// Put here the 'ready scripts' that must be executed after all others
-    	$this->add_ready_script(
+		$this->add_ready_script(
 <<<EOF
-	// Since the event is only triggered when the hash changes, we need to trigger
-	// the event now, to handle the hash the page may have loaded with.
-	$(window).trigger( 'hashchange' );
-	
-	// Some table are sort-able, some are not, let's fix this
-	$('table.listResults').each( function() { FixTableSorter($(this)); } );
-
+		// Since the event is only triggered when the hash changes, we need to trigger
+		// the event now, to handle the hash the page may have loaded with.
+		$(window).trigger( 'hashchange' );
+		
+		// Some table are sort-able, some are not, let's fix this
+		$('table.listResults').each( function() { FixTableSorter($(this)); } );
 EOF
-);
-        foreach($this->a_headers as $s_header)
-        {
-            header($s_header);
-        }
-        $s_captured_output = ob_get_contents();
-        ob_end_clean();
-        echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
-        echo "<html>\n";
-        echo "<head>\n";
-        // Make sure that Internet Explorer renders the page using its latest/highest/greatest standards !
-        echo "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n";
-        echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
-        echo "<title>".htmlentities($this->s_title, ENT_QUOTES, 'UTF-8')."</title>\n";
-        echo $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 ($this->GetOutputFormat() == 'html')
+		{
+			foreach($this->a_headers as $s_header)
+			{
+				header($s_header);
+			}
+		}
+		$s_captured_output = ob_get_contents();
+		ob_end_clean();
+		$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'] != "")
 			{
-				echo "<!--[if {$a_stylesheet['condition']}]>\n";
+				$sHtml .= "<!--[if {$a_stylesheet['condition']}]>\n";
 			}
-            echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n";
+			$sHtml .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n";
 			if ($a_stylesheet['condition'] != "")
 			{
-				echo "<![endif]-->\n";
+				$sHtml .= "<![endif]-->\n";
 			}
-        }
-        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;
-        	}
-            echo "<script type=\"text/javascript\" src=\"$s_script\"></script>\n";
-        }
-		$this->add_script("\$(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)
-        {
-            echo "<script type=\"text/javascript\">\n";
-            foreach($this->a_scripts as $s_script)
-            {
-                echo "$s_script\n";
-            }
-            echo "</script>\n";
-        }
-        
-        if (count($this->a_styles)>0)
-        {
-            echo "<style>\n";
-            foreach($this->a_styles as $s_style)
-            {
-                echo "$s_style\n";
-            }
-            echo "</style>\n";
-        }
-		echo "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"".utils::GetAbsoluteUrlAppRoot()."pages/opensearch.xml.php\" />\n";
-		echo "<link rel=\"shortcut icon\" href=\"".utils::GetAbsoluteUrlAppRoot()."images/favicon.ico\" />\n";
-		
-        echo "</head>\n";
-        echo "<body>\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')
+		{
+			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("\$(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";
 
 
 
@@ -673,7 +663,7 @@ EOF
 			// 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)
 		foreach($this->m_aTabs as $sTabContainerName => $m_aTabs)
 		{
@@ -681,159 +671,189 @@ EOF
 			$container_index = 0;
 			if (count($m_aTabs) > 0)
 			{
-			  $sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$container_index}\" class=\"light\">\n";
-			  $sTabs .= "<ul>\n";
-			  // Display the unordered list that will be rendered as the tabs
-	          $i = 0;
-			  foreach($m_aTabs as $sTabName => $sTabContent)
-			  {
-			      $sTabs .= "<li><a href=\"#tab_$i\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
-			      $i++;
-	          }
-			  $sTabs .= "</ul>\n";
-			  // Now add the content of the tabs themselves
-			  $i = 0;
-			  foreach($m_aTabs as $sTabName => $sTabContent)
-			  {
-			      $sTabs .= "<div id=\"tab_$i\">".$sTabContent."</div>\n";
-			      $i++;
-	          }
-			  $sTabs .= "</div>\n<!-- end of tabs-->\n";
-	        }
+				$sTabs = "<!-- tabs -->\n<div id=\"tabbedContent_{$container_index}\" class=\"light\">\n";
+				$sTabs .= "<ul>\n";
+				// Display the unordered list that will be rendered as the tabs
+				$i = 0;
+				foreach($m_aTabs as $sTabName => $sTabContent)
+				{
+					$sTabs .= "<li><a href=\"#tab_$i\" class=\"tab\"><span>".htmlentities($sTabName, ENT_QUOTES, 'UTF-8')."</span></a></li>\n";
+					$i++;
+				}
+				$sTabs .= "</ul>\n";
+				// Now add the content of the tabs themselves
+				$i = 0;
+				foreach($m_aTabs as $sTabName => $sTabContent)
+				{
+					$sTabs .= "<div id=\"tab_$i\">".$sTabContent."</div>\n";
+					$i++;
+				}
+				$sTabs .= "</div>\n<!-- end of tabs-->\n";
+			}
 			$this->s_content = str_replace("\$Tabs:$sTabContainerName\$", $sTabs, $this->s_content);
 			$container_index++;
 		}
-		$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";
-		$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/preferences.php\">".Dict::S('UI:Preferences')."</a></li>\n";
-		
-		if (utils::CanLogOff())
-		{
-			//$sLogOffMenu .= "<li><a href=\"../pages/UI.php?loginop=logoff\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
-			$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
-		}
-		if (UserRights::CanChangePassword())
-		{
-			$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?loginop=change_pwd\">".Dict::S('UI:ChangePwdMenu')."</a></li>\n";
-		}
-		$sLogOffMenu .= "</ul>\n</li>\n</ul></span>\n";
 
-		$sRestrictions = '';
-		if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE))
+		if ($this->GetOutputFormat() == 'html')
 		{
+			$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";
+			$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/preferences.php\">".Dict::S('UI:Preferences')."</a></li>\n";
+				
+			if (utils::CanLogOff())
+			{
+				//$sLogOffMenu .= "<li><a href=\"../pages/UI.php?loginop=logoff\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
+				$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/logoff.php\">".Dict::S('UI:LogOffMenu')."</a></li>\n";
+			}
+			if (UserRights::CanChangePassword())
+			{
+				$sLogOffMenu .= "<li><a href=\"".utils::GetAbsoluteUrlAppRoot()."pages/UI.php?loginop=change_pwd\">".Dict::S('UI:ChangePwdMenu')."</a></li>\n";
+			}
+			$sLogOffMenu .= "</ul>\n</li>\n</ul></span>\n";
+
+			$sRestrictions = '';
 			if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE))
 			{
-				$sRestrictions = Dict::S('UI:AccessRO-All');
+				if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE))
+				{
+					$sRestrictions = Dict::S('UI:AccessRO-All');
+				}
 			}
-		}
-		elseif (!MetaModel::DBHasAccess(ACCESS_USER_WRITE))
-		{
+			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 = '';
+			if (strlen($sRestrictions) > 0)
 			{
-				$sApplicationBanner .= '&nbsp;<b>'.$sAdminMessage.'</b>';
+				$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>';
 			}
-			$sApplicationBanner .= '</div>';
-		}
 
-		if(strlen($this->m_sMessage))
-		{
-			$sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">'.$this->m_sMessage.'<span></div>';
-		}
+			if(strlen($this->m_sMessage))
+			{
+				$sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">'.$this->m_sMessage.'<span></div>';
+			}
 
-		$sEnvironment = utils::GetCurrentEnvironment();
-		$sBackButton = utils::GetEnvironmentBackButton();
-		if($sEnvironment != 'production')
-		{
-			$sEnvLabel = trim(MetaModel::GetConfig()->Get('app_env_label'));
-			if (strlen($sEnvLabel) == 0)
+			$sEnvironment = utils::GetCurrentEnvironment();
+			$sBackButton = utils::GetEnvironmentBackButton();
+			if($sEnvironment != 'production')
 			{
-				$sEnvLabel = $sEnvironment;
+				$sEnvLabel = trim(MetaModel::GetConfig()->Get('app_env_label'));
+				if (strlen($sEnvLabel) == 0)
+				{
+						$sEnvLabel = $sEnvironment;
+				}
+				$sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">'.Dict::Format('UI:ApplicationEnvironment', $sEnvLabel).$sBackButton.'<span></div>';
 			}
-			$sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">'.Dict::Format('UI:ApplicationEnvironment', $sEnvLabel).$sBackButton.'<span></div>';
-		}
 
-		$sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help');
-		//$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>";
+			$sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help');
+			//$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>";
 
-		echo '<div id="left-pane" class="ui-layout-west">';
-		echo '<!-- Beginning of the left pane -->';
-		echo '	<div id="header-logo">';
-		echo '	<div id="top-left"></div><div id="logo"><a href="http://www.combodo.com/itop"><img src="../images/itop-logo.png" title="'.htmlentities($sVersionString, ENT_QUOTES, 'UTF-8').'" style="border:0; margin-top:16px; margin-right:40px;"/></a></div>';
-		echo '	</div>';
-		echo '	<div class="header-menu">';
-		echo '		<div class="icon ui-state-default ui-corner-all"><span id="tPinMenu" class="ui-icon ui-icon-pin-w">pin</span></div>';
-		echo '		<div style="text-align:center;">'.self::FilterXSS($sForm).'</div>';
-		echo '	</div>';
-		echo '	<div id="menu" class="ui-layout-content">';
-		echo '		<div id="inner_menu">';
-		echo '			<div id="accordion">';
-		echo self::FilterXSS($this->m_sMenu);
-		echo '			<!-- Beginning of the accordion menu -->';
-		echo '			<!-- End of the accordion menu-->';
-		echo '			</div>';
-		echo '		</div> <!-- /inner menu -->';
-		echo '	</div> <!-- /menu -->';
-		echo '	<div class="footer"><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logo-combodo.png"/></a></div>';
-		echo '<!-- End of the left pane -->';
-		echo '</div>';
+			$sHtml .= '<div id="left-pane" class="ui-layout-west">';
+			$sHtml .= '<!-- Beginning of the left pane -->';
+			$sHtml .= ' <div id="header-logo">';
+			$sHtml .= ' <div id="top-left"></div><div id="logo"><a href="http://www.combodo.com/itop"><img src="../images/itop-logo.png" 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">';
+			$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 id="menu" class="ui-layout-content">';
+			$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"><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logo-combodo.png"/></a></div>';
+			$sHtml .= '<!-- End of the left pane -->';
+			$sHtml .= '</div>';
 
-		echo '<div class="ui-layout-center">';
-		echo '	<div id="top-bar" style="width:100%">';
-		echo self::FilterXSS($sApplicationBanner);
-		echo '		<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>';
-		echo '<td><input type="image" src="../images/searchBtn.png"/></a></td>';
-		echo '<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>';
-		echo '<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>';
-		echo '	</div>';
-		echo '	<div class="ui-layout-content">';
-		echo '	<!-- Beginning of page content -->';
-		echo self::FilterXSS($this->s_content);
-		echo '	<!-- End of page content -->';
-		echo '	</div>';
-		echo '</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">';
+			$sHtml .= ' <!-- Beginning of page content -->';
+			$sHtml .= self::FilterXSS($this->s_content);
+			$sHtml .= ' <!-- End of page content -->';
+			$sHtml .= ' </div>';
+			$sHtml .= '</div>';
+				
+			// 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);
+		}
 
-        // Add the captured output
-        if (trim($s_captured_output) != "")
-        {
-            echo "<div id=\"rawOutput\" title=\"Debug Output\"><div style=\"height:500px; overflow-y:auto;\">".self::FilterXSS($s_captured_output)."</div></div>\n";
-        }
-		echo "<div id=\"at_the_end\">".self::FilterXSS($this->s_deferred_content)."</div>";
-//		echo $this->s_deferred_content;
-		echo "<div style=\"display:none\" title=\"ex2\" id=\"ex2\">Please wait...</div>\n"; // jqModal Window
-		echo "<div style=\"display:none\" title=\"dialog\" id=\"ModalDlg\"></div>";
-		echo "<div style=\"display:none\" id=\"ajax_content\"></div>";
+		$sHtml .= "</body>\n";
+		$sHtml .= "</html>\n";
+
+		if ($this->GetOutputFormat() == 'html')
+		{
+				echo $sHtml;
+		}
+		else if ($this->GetOutputFormat() == 'pdf' && $this->IsOutputFormatAvailable('pdf') )
+		{
+			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);
+			$oMPDF->Output();
+		}
+	}
 
-		echo "</body>\n";
-        echo "</html>\n";
-    }
-	
 	public function AddTabContainer($sTabContainer)
 	{
 		$this->m_aTabs[$sTabContainer] = array();
 		$this->add("\$Tabs:$sTabContainer\$");
 	}
-	
+
 	public function AddToTab($sTabContainer, $sTabLabel, $sHtml)
 	{
 		if (!isset($this->m_aTabs[$sTabContainer][$sTabLabel]))
@@ -861,12 +881,12 @@ EOF
 		$this->m_sCurrentTab = $sTabLabel;
 		return $sPreviousTab;
 	}
-	
+
 	public function GetCurrentTab()
 	{
 		return $this->m_sCurrentTab;
 	}
-	
+
 	public function RemoveTab($sTabLabel, $sTabContainer = null)
 	{
 		if ($sTabContainer == null)
@@ -877,7 +897,7 @@ EOF
 		{
 			// Delete the content of the tab
 			unset($this->m_aTabs[$sTabContainer][$sTabLabel]);
-			
+				
 			// If we just removed the active tab, let's reset the active tab
 			if (($this->m_sCurrentTabContainer == $sTabContainer) &&  ($this->m_sCurrentTab == $sTabLabel))
 			{
@@ -907,7 +927,7 @@ EOF
 		}
 		return $result;
 	}
-	
+
 	/**
 	 * Make the given tab the active one, as if it were clicked
 	 * DOES NOT WORK: apparently in the *old* version of jquery
@@ -929,7 +949,7 @@ EOF
 						break;
 					}
 					$tab_index++;
-				}	
+				}
 				break;
 			}
 			$container_index++;
@@ -937,7 +957,7 @@ EOF
 		$sSelector = '#tabbedContent_'.$container_index.' > ul';
 		$this->add_ready_script("$('$sSelector').tabs('select', $tab_index);");
 	}
-	
+
 	public function StartCollapsibleSection($sSectionLabel, $bOpen = false)
 	{
 		$this->add($this->GetStartCollapsibleSection($sSectionLabel, $bOpen));
@@ -967,91 +987,68 @@ EOF
 		return "</div>";
 	}
 
-    public function add($sHtml)
-    {
-        if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
-        {
-            $this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
-        }
-        else
-        {
-            parent::add($sHtml);
-        }
-    }
-    
+	public function add($sHtml)
+	{
+		if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
+		{
+			$this->AddToTab($this->m_sCurrentTabContainer, $this->m_sCurrentTab, $sHtml);
+		}
+		else
+		{
+			parent::add($sHtml);
+		}
+	}
+
 	/**
 	 * Records the current state of the 'html' part of the page output
 	 * @return mixed The current state of the 'html' output
-	 */    
-    public function start_capture()
-    {
-        if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
-        {
-        	$iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]): 0;
-            return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset);
-        }
-        else
-        {
-            return parent::start_capture();
-        }
-    }
+	 */
+	public function start_capture()
+	{
+		if (!empty($this->m_sCurrentTabContainer) && !empty($this->m_sCurrentTab))
+		{
+			$iOffset = isset($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]) ? strlen($this->m_aTabs[$this->m_sCurrentTabContainer][$this->m_sCurrentTab]): 0;
+			return array('tc' => $this->m_sCurrentTabContainer, 'tab' => $this->m_sCurrentTab, 'offset' => $iOffset);
+		}
+		else
+		{
+			return parent::start_capture();
+		}
+	}
 
-    /**
-     * Returns the part of the html output that occurred since the call to start_capture
-     * and removes this part from the current html output
-     * @param $offset mixed The value returned by start_capture
-     * @return string The part of the html output that was added since the call to start_capture
-     */    
-    public function end_capture($offset)
-    {
-    	if (is_array($offset))
-    	{
-    		if (isset($this->m_aTabs[$offset['tc']][$offset['tab']]))
-    		{
-		    	$sCaptured = substr($this->m_aTabs[$offset['tc']][$offset['tab']], $offset['offset']);
-		    	$this->m_aTabs[$offset['tc']][$offset['tab']] = substr($this->m_aTabs[$offset['tc']][$offset['tab']], 0, $offset['offset']);
-    		}
-    		else
-    		{
-    			$sCaptured = '';
-    		}
-    	}
-    	else
-    	{
-    		$sCaptured = parent::end_capture($offset);
-    	}
-    	return $sCaptured;
-    }
-        
-    /**
-     * Set the message to be displayed in the 'admin-banner' section at the top of the page
-     */
-    public function SetMessage($sMessage)
-    {
-    	$this->m_sMessage = $sMessage;	
-    }
-    
-    /*
-    public function AddSearchForm($sClassName, $bOpen = false)
-    {
-    	$iSearchSectionId = 0;
-    	
-		$sStyle = $bOpen ? 'SearchDrawer' : 'SearchDrawer DrawerClosed';
-		$this->add("<div id=\"Search_$iSearchSectionId\" class=\"$sStyle\">\n");
-		$this->add("<h1>Search form for ".Metamodel::GetName($sClassName)."</h1>\n");
-		$this->add_ready_script("\$(\"#LnkSearch_$iSearchSectionId\").click(function() {\$(\"#Search_$iSearchSectionId\").slideToggle('normal'); $(\"#LnkSearch_$iSearchSectionId\").toggleClass('open');});");
-		$oFilter = new DBObjectSearch($sClassName);
-		$sFilter = $oFilter->serialize();
-		$oSet = new CMDBObjectSet($oFilter);
-		cmdbAbstractObject::DisplaySearchForm($this, $oSet, array('operation' => 'search', 'filter' => $sFilter, 'search_form' => true));
- 		$this->add("</div>\n");
- 		$this->add("<div class=\"HRDrawer\"/></div>\n");
- 		$this->add("<div id=\"LnkSearch_$iSearchSectionId\" class=\"DrawerHandle\">Search</div>\n");
+	/**
+	 * Returns the part of the html output that occurred since the call to start_capture
+	 * and removes this part from the current html output
+	 * @param $offset mixed The value returned by start_capture
+	 * @return string The part of the html output that was added since the call to start_capture
+	 */
+	public function end_capture($offset)
+	{
+		if (is_array($offset))
+		{
+			if (isset($this->m_aTabs[$offset['tc']][$offset['tab']]))
+			{
+				$sCaptured = substr($this->m_aTabs[$offset['tc']][$offset['tab']], $offset['offset']);
+				$this->m_aTabs[$offset['tc']][$offset['tab']] = substr($this->m_aTabs[$offset['tc']][$offset['tab']], 0, $offset['offset']);
+			}
+			else
+			{
+				$sCaptured = '';
+			}
+		}
+		else
+		{
+			$sCaptured = parent::end_capture($offset);
+		}
+		return $sCaptured;
+	}
 
-    	
-    	$iSearchSectionId++;
+	/**
+	 * Set the message to be displayed in the 'admin-banner' section at the top of the page
+	 */
+	public function SetMessage($sMessage)
+	{
+			$this->m_sMessage = $sMessage;
 	}
-	*/
 }
-
-?>
+?>

+ 66 - 0
application/webpage.class.inc.php

@@ -50,6 +50,8 @@ class WebPage
 	protected $sContentType;
 	protected $sContentDisposition;
 	protected $sContentFileName;
+	protected $s_sOutputFormat;
+	protected $a_OutputOptions;
 	    
     public function __construct($s_title)
     {
@@ -67,6 +69,8 @@ class WebPage
         $this->sContentType = '';
         $this->sContentDisposition = '';
         $this->sContentFileName = '';
+		$this->s_OutputFormat = utils::ReadParam('output_format', 'html');
+		$this->a_OutputOptions = array();
         ob_start(); // Start capturing the output
     }
 	
@@ -515,5 +519,67 @@ class WebPage
 	{
 		return str_ireplace('<script', '&lt;script', $sHTML);
 	}
+	
+	/**
+	 * What is the currently selected output format
+	 * @return string The selected output format: html, pdf...
+	 */
+	public function GetOutputFormat()
+	{
+		return $this->s_OutputFormat;
+	}
+
+	/**
+	 * Check whether the desired output format is possible or not
+	 * @param string $sOutputFormat The desired output format: html, pdf...
+	 * @return bool True if the format is Ok, false otherwise
+	 */
+	function IsOutputFormatAvailable($sOutputFormat)
+	{
+		$bResult = false;
+		switch($sOutputFormat)
+		{
+			case 'html':
+			$bResult = true; // Always supported
+			break;
+			
+			case 'pdf':
+			$bResult = @is_readable(APPROOT.'lib/MPDF/mpdf.php');
+			break;
+		}
+		return $bResult;
+	}
+	
+	/** 
+	 * Retrieves the value of a named output option for the given format
+	 * @param string $sFormat The format: html or pdf
+	 * @param string $sOptionName The name of the option
+	 * @return mixed false if the option was never set or the options's value
+	 */
+	public function GetOutputOption($sFormat, $sOptionName)
+	{
+		if (isset($this->a_OutputOptions[$sFormat][$sOptionName]))
+		{
+			return $this->a_OutputOptions[$sFormat][$sOptionName];
+		}
+		return false;
+	}
+	/**
+	 * Sets a named output option for the given format
+	 * @param string $sFormat The format for which to set the option: html or pdf
+	 * @param string $sOptionName the name of the option
+	 * @param mixed $sValue The value of the option
+	 */
+	public function SetOutputOption($sFormat, $sOptionName, $sValue)
+	{
+		if (!isset($this->a_OutputOptions[$sFormat]))
+		{
+			$this->a_OutputOptions[$sFormat] = array($sOptionName => $sValue);
+		}
+		else
+		{
+			$this->a_OutputOptions[$sFormat][$sOptionName] = $sValue;
+		}
+	}
 }
 ?>