Переглянути джерело

#485 Export for MS Excel web queries: format=spreadsheet

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@1711 a333f486-631f-4898-b8df-5754b55c2be0
romainq 13 роки тому
батько
коміт
b1ac10a93a

+ 140 - 0
application/cmdbabstract.class.inc.php

@@ -1172,6 +1172,146 @@ EOF
 		return $sHtml;
 	}
 	
+	static function DisplaySetAsHTMLSpreadsheet(WebPage $oPage, CMDBObjectSet $oSet, $aParams = array())
+	{
+		$oPage->add(self::GetSetAsHTMLSpreadsheet($oSet, $aParams));
+	}
+	
+	static function GetSetAsHTMLSpreadsheet(DBObjectSet $oSet, $aParams = array())
+	{
+		$aFields = null;
+		if (isset($aParams['fields']) && (strlen($aParams['fields']) > 0))
+		{
+			$aFields = explode(',', $aParams['fields']);
+		}
+
+		$aList = array();
+
+		$oAppContext = new ApplicationContext();
+		$aClasses = $oSet->GetFilter()->GetSelectedClasses();
+		$aAuthorizedClasses = array();
+		foreach($aClasses as $sAlias => $sClassName)
+		{
+			if (UserRights::IsActionAllowed($sClassName, UR_ACTION_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS))
+			{
+				$aAuthorizedClasses[$sAlias] = $sClassName;
+			}
+		}
+		$aAttribs = array();
+		$aHeader = array();
+		foreach($aAuthorizedClasses as $sAlias => $sClassName)
+		{
+			foreach(MetaModel::ListAttributeDefs($sClassName) as $sAttCode => $oAttDef)
+			{
+				if (is_null($aFields) || (count($aFields) == 0))
+				{
+					// Standard list of attributes (no link sets)
+					if ($oAttDef->IsScalar() && ($oAttDef->IsWritable() || $oAttDef->IsExternalField()))
+					{
+						$aList[$sClassName][$sAttCode] = $oAttDef;
+					}
+				}
+				else
+				{
+					// User defined list of attributes
+					if (in_array($sAttCode, $aFields))
+					{
+						$aList[$sClassName][$sAttCode] = $oAttDef;
+					}
+				}
+			}
+			$aHeader[] = 'id';
+			foreach($aList[$sClassName] as $sAttCode => $oAttDef)
+			{
+				$sStar = '';
+				if ($oAttDef->IsExternalField())
+				{
+					$sExtKeyLabel = MetaModel::GetLabel($sClassName, $oAttDef->GetKeyAttCode());
+					$oExtKeyAttDef = MetaModel::GetAttributeDef($sClassName, $oAttDef->GetKeyAttCode());
+					if (!$oExtKeyAttDef->IsNullAllowed() && isset($aParams['showMandatoryFields']))
+					{
+						$sStar = '*';
+					}
+					$sRemoteAttLabel = MetaModel::GetLabel($oAttDef->GetTargetClass(), $oAttDef->GetExtAttCode());
+					$oTargetAttDef = MetaModel::GetAttributeDef($oAttDef->GetTargetClass(), $oAttDef->GetExtAttCode());
+					$sSuffix = '';
+					if ($oTargetAttDef->IsExternalKey())
+					{
+						$sSuffix = '->id';
+					}
+					$sColLabel = $sExtKeyLabel.'->'.$sRemoteAttLabel.$sSuffix.$sStar;
+				}
+				else
+				{
+					if (!$oAttDef->IsNullAllowed() && isset($aParams['showMandatoryFields']))
+					{
+						$sStar = '*';
+					}
+					$sColLabel = MetaModel::GetLabel($sClassName, $sAttCode).$sStar;
+				}
+				$oFinalAttDef = $oAttDef->GetFinalAttDef();
+				if (get_class($oFinalAttDef) == 'AttributeDateTime')
+				{
+					$aHeader[] = $sColLabel.' ('.Dict::S('UI:SplitDateTime-Date').')';
+					$aHeader[] = $sColLabel.' ('.Dict::S('UI:SplitDateTime-Time').')';
+				}
+				else
+				{
+					$aHeader[] = $sColLabel;
+				}
+			}
+		}
+
+
+		$sHtml = "<table border=\"1\">\n";
+		$sHtml .= "<tr>\n";
+		$sHtml .= "<td>".implode("</td><td>", $aHeader)."</td>\n";
+		$sHtml .= "</tr>\n";
+		$oSet->Seek(0);
+		while ($aObjects = $oSet->FetchAssoc())
+		{
+			$aRow = array();
+			foreach($aAuthorizedClasses as $sAlias => $sClassName)
+			{
+				$oObj = $aObjects[$sAlias];
+				if (is_null($oObj))
+				{
+					$aRow[] = '';
+				}
+				else
+				{
+					$aRow[] = '<td>'.$oObj->GetKey().'</td>';
+				}
+				foreach($aList[$sClassName] as $sAttCode => $oAttDef)
+				{
+					if (is_null($oObj))
+					{
+						$aRow[] = '';
+					}
+					else
+					{
+						$oFinalAttDef = $oAttDef->GetFinalAttDef();
+						if (get_class($oFinalAttDef) == 'AttributeDateTime')
+						{
+							$iDate = AttributeDateTime::GetAsUnixSeconds($oObj->Get($sAttCode));
+							$aRow[] = '<td>'.date('Y-m-d', $iDate).'</td>';
+							$aRow[] = '<td>'.date('h:i:s', $iDate).'</td>';
+						}
+						else
+						{
+							$aRow[] = '<td>'.(string) $oObj->Get($sAttCode).'</td>';
+						}
+					}
+				}
+			}
+			$sHtml .= implode("\n", $aRow);
+			$sHtml .= "</tr>\n";
+		}
+		$sHtml .= "</table>\n";
+		
+		return $sHtml;
+	}
+	
 	static function DisplaySetAsXML(WebPage $oPage, CMDBObjectSet $oSet, $aParams = array())
 	{
 		$oAppContext = new ApplicationContext();

+ 11 - 0
core/attributedef.class.inc.php

@@ -162,6 +162,10 @@ abstract class AttributeDefinition
 		return "";
 		// e.g: return array("Site", "infrid", "name");
 	} 
+	public function GetFinalAttDef()
+	{
+		return $this;
+	}
 	public function IsDirectField() {return false;} 
 	public function IsScalar() {return false;} 
 	public function IsLinkSet() {return false;} 
@@ -2761,6 +2765,13 @@ class AttributeExternalField extends AttributeDefinition
 	}
 
 	public function GetEditClass() {return "ExtField";}
+
+	public function GetFinalAttDef()
+	{
+		$oExtAttDef = $this->GetExtAttDef();
+		return $oExtAttDef->GetFinalAttDef(); 
+	}
+
 	protected function GetSQLCol()
 	{
 		// throw new CoreException("external attribute: does it make any sense to request its type ?");  

+ 2 - 0
dictionaries/dictionary.itop.ui.php

@@ -429,6 +429,8 @@ Dict::Add('EN US', 'English', 'English', array(
 	'UI:UndefinedObject' => 'undefined',
 	'UI:Document:OpenInNewWindow:Download' => 'Open in new window: %1$s, Download: %2$s',
 	'UI:SelectAllToggle+' => 'Select / Deselect All',
+	'UI:SplitDateTime-Date' => 'date',
+	'UI:SplitDateTime-Time' => 'time',
 	'UI:TruncatedResults' => '%1$d objects displayed out of %2$d',
 	'UI:DisplayAll' => 'Display All',
 	'UI:CollapseList' => 'Collapse',

+ 2 - 0
dictionaries/fr.dictionary.itop.ui.php

@@ -316,6 +316,8 @@ Dict::Add('FR FR', 'French', 'Français', array(
 	'UI:Document:OpenInNewWindow:Download' => 'Ouvrir dans un nouvelle fenêtre: %1$s, Télécharger: %2$s',
 	'UI:SelectAllToggle+' => 'Tout sélectionner / Tout déselectionner',
 	'UI:TruncatedResults' => '%1$d objets affichés sur %2$d',
+	'UI:SplitDateTime-Date' => 'date',
+	'UI:SplitDateTime-Time' => 'heure',
 	'UI:DisplayAll' => 'Tout afficher',
 	'UI:CollapseList' => 'Refermer',
 	'UI:CountOfResults' => '%1$d objet(s)',

+ 2 - 2
pages/UI.php

@@ -2109,7 +2109,7 @@ EOF
 	DisplayWelcomePopup($oP);
 	$oP->output();	
 }
-catch(CoreException $e)
+catch(xxxCoreException $e)
 {
 	require_once(APPROOT.'/setup/setuppage.class.inc.php');
 	$oP = new SetupWebPage(Dict::S('UI:PageTitle:FatalError'));
@@ -2152,7 +2152,7 @@ catch(CoreException $e)
 	// For debugging only
 	//throw $e;
 }
-catch(Exception $e)
+catch(xxxException $e)
 {
 	require_once(APPROOT.'/setup/setuppage.class.inc.php');
 	$oP = new SetupWebPage(Dict::S('UI:PageTitle:FatalError'));

+ 13 - 0
webservices/export.php

@@ -126,6 +126,19 @@ if (!empty($sExpression))
 				cmdbAbstractObject::DisplaySetAsCSV($oP, $oSet, array('fields' => $sFields));
 				break;
 				
+				case 'spreadsheet':
+				$oP = new WebPage("iTop - Export for spreadsheet");
+
+				// Integration within MS-Excel web queries + HTTPS + IIS:
+				// MS-IIS set these header values with no-cache... while Excel fails to do the job if using HTTPS
+				// Then the fix is to force the reset of header values Pragma and Cache-control 
+				header("Pragma:", true);
+				header("Cache-control:", true);
+
+				$sFields = implode(',', $aFields);
+				cmdbAbstractObject::DisplaySetAsHTMLSpreadsheet($oP, $oSet, array('fields' => $sFields));
+				break;
+
 				case 'xml':
 				$oP = new XMLPage("iTop - Export", true /* passthrough */);
 				cmdbAbstractObject::DisplaySetAsXML($oP, $oSet);