diff --git a/core/bulkexport.class.inc.php b/core/bulkexport.class.inc.php index a3cd3727d..46710d04a 100644 --- a/core/bulkexport.class.inc.php +++ b/core/bulkexport.class.inc.php @@ -133,6 +133,7 @@ abstract class BulkExport protected $aStatusInfo; protected $oBulkExportResult; protected $sTmpFile; + protected $bLocalizeOutput; public function __construct() { @@ -142,6 +143,7 @@ abstract class BulkExport $this->aStatusInfo = array(); $this->oBulkExportResult = null; $this->sTmpFile = ''; + $this->bLocalizeOutput = false; } /** @@ -331,7 +333,7 @@ abstract class BulkExport } public function ReadParameters() { - + $this->bLocalizeOutput = !((bool)utils::ReadParam('no_localize', 0, true, 'integer')); } public function GetResultAsHtml() diff --git a/core/csvbulkexport.class.inc.php b/core/csvbulkexport.class.inc.php index 995996d13..1a55444c1 100644 --- a/core/csvbulkexport.class.inc.php +++ b/core/csvbulkexport.class.inc.php @@ -53,7 +53,7 @@ class CSVBulkExport extends TabularBulkExport { $this->aStatusInfo['text_qualifier'] = utils::ReadParam('other-text-qualifier', '"', true, 'raw_data'); } - $this->aStatusInfo['localize'] = !((bool)utils::ReadParam('no_localize', 0, true, 'integer')); + $this->aStatusInfo['charset'] = strtoupper(utils::ReadParam('charset', 'UTF-8', true, 'raw_data')); } @@ -188,70 +188,10 @@ class CSVBulkExport extends TabularBulkExport $this->aStatusInfo['position'] = 0; $this->aStatusInfo['total'] = $oSet->Count(); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); - $aAuthorizedClasses = array(); - foreach($aSelectedClasses as $sAlias => $sClassName) - { - if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) - { - $aAuthorizedClasses[$sAlias] = $sClassName; - } - } - $aAliases = array_keys($aAuthorizedClasses); $aData = array(); - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = reset($aAliases); - $sAttCode = $sExtendedAttCode; - } - if (!in_array($sAlias, $aAliases)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); - } - $sClass = $aAuthorizedClasses[$sAlias]; - - switch($sAttCode) - { - case 'id': - $sLabel = 'id'; - break; - - default: - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if (($oAttDef instanceof AttributeExternalField) || (($oAttDef instanceof AttributeFriendlyName) && ($oAttDef->GetKeyAttCode() != 'id'))) - { - $oKeyAttDef = MetaModel::GetAttributeDef($sClass, $oAttDef->GetKeyAttCode()); - $oExtAttDef = MetaModel::GetAttributeDef($oKeyAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); - if ($this->aStatusInfo['localize']) - { - $sStar = $oAttDef->IsNullAllowed() ? '' : '*'; - $sLabel = $oKeyAttDef->GetLabel().$sStar.'->'.$oExtAttDef->GetLabel(); - } - else - { - $sLabel = $oKeyAttDef->GetCode().'->'.$oExtAttDef->GetCode(); - } - } - else - { - $sLabel = $this->aStatusInfo['localize'] ? $oAttDef->GetLabel() : $sAttCode; - } - } - if (count($aAuthorizedClasses) > 1) - { - $aData[] = $sAlias.'.'.$sLabel; - } - else - { - $aData[] = $sLabel; - } + $aData[] = $aFieldSpec['sColLabel']; } $sFrom = array("\r\n", $this->aStatusInfo['text_qualifier']); $sTo = array("\n", $this->aStatusInfo['text_qualifier'].$this->aStatusInfo['text_qualifier']); @@ -278,75 +218,34 @@ class CSVBulkExport extends TabularBulkExport $iPercentage = 0; $oSet = new DBObjectSet($this->oSearch); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); - $aAuthorizedClasses = array(); - foreach($aSelectedClasses as $sAlias => $sClassName) - { - if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) - { - $aAuthorizedClasses[$sAlias] = $sClassName; - } - } - $aAliases = array_keys($aAuthorizedClasses); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); - - $aAliasByField = array(); - $aColumnsToLoad = array(); - - // Prepare the list of aliases / columns to load - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) - { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = reset($aAliases); - $sAttCode = $sExtendedAttCode; - } - - if (!in_array($sAlias, $aAliases)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); - } - - if (!array_key_exists($sAlias, $aColumnsToLoad)) - { - $aColumnsToLoad[$sAlias] = array(); - } - if ($sAttCode != 'id') - { - // id is not a real attribute code and, moreover, is always loaded - $aColumnsToLoad[$sAlias][] = $sAttCode; - } - $aAliasByField[$sExtendedAttCode] = array('alias' => $sAlias, 'attcode' => $sAttCode); - } + $this->OptimizeColumnLoad($oSet); $iCount = 0; $sData = ''; - $oSet->OptimizeColumnLoad($aColumnsToLoad); $iPreviousTimeLimit = ini_get('max_execution_time'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); while($aRow = $oSet->FetchAssoc()) { set_time_limit($iLoopTimeLimit); $aData = array(); - foreach($aAliasByField as $aAttCode) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { + $sAlias = $aFieldSpec['sAlias']; + $sAttCode = $aFieldSpec['sAttCode']; + $sField = ''; - $oObj = $aRow[$aAttCode['alias']]; + $oObj = $aRow[$sAlias]; if ($oObj != null) { - switch($aAttCode['attcode']) + switch($sAttCode) { case 'id': $sField = $oObj->GetKey(); break; default: - $sField = $oObj->GetAsCSV($aAttCode['attcode'], $this->aStatusInfo['separator'], $this->aStatusInfo['text_qualifier'], $this->aStatusInfo['localize']); + $sField = $oObj->GetAsCSV($sAttCode, $this->aStatusInfo['separator'], $this->aStatusInfo['text_qualifier'], $this->bLocalizeOutput); } } if ($this->aStatusInfo['charset'] != 'UTF-8') diff --git a/core/excelbulkexport.class.inc.php b/core/excelbulkexport.class.inc.php index 9b17eeff3..0b7ec92eb 100644 --- a/core/excelbulkexport.class.inc.php +++ b/core/excelbulkexport.class.inc.php @@ -67,13 +67,6 @@ class ExcelBulkExport extends TabularBulkExport } } - public function ReadParameters() - { - parent::ReadParameters(); - $this->aStatusInfo['localize'] = !((bool)utils::ReadParam('no_localize', 0, true, 'integer')); - } - - protected function SuggestField($aAliases, $sClass, $sAlias, $sAttCode) { switch($sAttCode) @@ -101,74 +94,27 @@ class ExcelBulkExport extends TabularBulkExport $this->aStatusInfo['position'] = 0; $this->aStatusInfo['total'] = $oSet->Count(); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); - foreach($aSelectedClasses as $sAlias => $sClassName) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { - if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) - { - $aAuthorizedClasses[$sAlias] = $sClassName; - } - } - $aAliases = array_keys($aAuthorizedClasses); - $aTableHeaders = array(); - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) - { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = reset($aAliases); - $sAttCode = $sExtendedAttCode; - } - if (!in_array($sAlias, $aAliases)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); - } - $sClass = $aSelectedClasses[$sAlias]; - - $sFullAlias = ''; - if (count($aSelectedClasses) > 1) - { - $sFullAlias = $sAlias.'.'; - } + $sExtendedAttCode = $aFieldSpec['sFieldSpec']; + $sAttCode = $aFieldSpec['sAttCode']; + $sColLabel = $aFieldSpec['sColLabel']; switch($sAttCode) { case 'id': - $aTableHeaders[] = array('label' => $sFullAlias.'id', 'type' => '0'); - + $sType = '0'; break; default: - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + $oAttDef = MetaModel::GetAttributeDef($aFieldSpec['sClass'], $aFieldSpec['sAttCode']); $sType = 'string'; if($oAttDef instanceof AttributeDateTime) { $sType = 'datetime'; } - if (($oAttDef instanceof AttributeExternalField) || (($oAttDef instanceof AttributeFriendlyName) && ($oAttDef->GetKeyAttCode() != 'id'))) - { - $oKeyAttDef = MetaModel::GetAttributeDef($sClass, $oAttDef->GetKeyAttCode()); - $oExtAttDef = MetaModel::GetAttributeDef($oKeyAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); - if ($this->aStatusInfo['localize']) - { - $sLabel = $oKeyAttDef->GetLabel().'->'.$oExtAttDef->GetLabel(); - } - else - { - $sLabel = $oKeyAttDef->GetCode().'->'.$oExtAttDef->GetCode(); - } - } - else - { - $sLabel = $this->aStatusInfo['localize'] ? $oAttDef->GetLabel() : $sAttCode; - } - - $aTableHeaders[] = array('label' => $sFullAlias.$sLabel, 'type' => $sType); } + $aTableHeaders[] = array('label' => $sColLabel, 'type' => $sType); } $sRow = json_encode($aTableHeaders); @@ -188,67 +134,35 @@ class ExcelBulkExport extends TabularBulkExport $iPercentage = 0; $hFile = fopen($this->aStatusInfo['tmp_file'], 'ab'); + $oSet = new DBObjectSet($this->oSearch); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); - $aAliases = array_keys($aSelectedClasses); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); - - $aAliasByField = array(); - $aColumnsToLoad = array(); - - // Prepare the list of aliases / columns to load - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) - { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = reset($aAliases); - $sAttCode = $sExtendedAttCode; - } - - if (!in_array($sAlias, $aAliases)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); - } - - if (!array_key_exists($sAlias, $aColumnsToLoad)) - { - $aColumnsToLoad[$sAlias] = array(); - } - if ($sAttCode != 'id') - { - // id is not a real attribute code and, moreover, is always loaded - $aColumnsToLoad[$sAlias][] = $sAttCode; - } - $aAliasByField[$sExtendedAttCode] = array('alias' => $sAlias, 'attcode' => $sAttCode); - } + $this->OptimizeColumnLoad($oSet); $iCount = 0; - $oSet->OptimizeColumnLoad($aColumnsToLoad); $iPreviousTimeLimit = ini_get('max_execution_time'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); while($aRow = $oSet->FetchAssoc()) { set_time_limit($iLoopTimeLimit); $aData = array(); - foreach($aAliasByField as $aAttCode) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { - $oObj = $aRow[$aAttCode['alias']]; + $sAlias = $aFieldSpec['sAlias']; + $sAttCode = $aFieldSpec['sAttCode']; + + $oObj = $aRow[$sAlias]; $sField = ''; if ($oObj) { - switch($aAttCode['attcode']) + switch($sAttCode) { case 'id': $sField = $oObj->GetKey(); break; default: - $value = $oObj->Get($aAttCode['attcode']); + $value = $oObj->Get($sAttCode); if ($value instanceOf ormCaseLog) { // Extract the case log as text and remove the "===" which make Excel think that the cell contains a formula the next time you edit it! @@ -256,12 +170,12 @@ class ExcelBulkExport extends TabularBulkExport } else if ($value instanceOf DBObjectSet) { - $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $aAttCode['attcode']); + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); $sField = $oAttDef->GetAsCSV($value, '', '', $oObj); } else { - $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $aAttCode['attcode']); + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); $sField = $oAttDef->GetEditValue($value, $oObj); } } diff --git a/core/htmlbulkexport.class.inc.php b/core/htmlbulkexport.class.inc.php index 0d15fb42f..d742beb14 100644 --- a/core/htmlbulkexport.class.inc.php +++ b/core/htmlbulkexport.class.inc.php @@ -64,83 +64,19 @@ class HTMLBulkExport extends TabularBulkExport public function GetHeader() { - $sData = ''; + $sData = ''; $oSet = new DBObjectSet($this->oSearch); $this->aStatusInfo['status'] = 'running'; $this->aStatusInfo['position'] = 0; $this->aStatusInfo['total'] = $oSet->Count(); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); - foreach($aSelectedClasses as $sAlias => $sClassName) - { - if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ, $oSet) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) - { - $aAuthorizedClasses[$sAlias] = $sClassName; - } - } - $aAliases = array_keys($aAuthorizedClasses); - $aData = array(); - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) - { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - - $sAlias = reset($aAliases); - $sAttCode = $sExtendedAttCode; - } - if (!in_array($sAlias, $aAliases)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); - } - $sClass = $aSelectedClasses[$sAlias]; - - switch($sAttCode) - { - case 'id': - if (count($aSelectedClasses) > 1) - { - $aData[] = $sAlias.'.id'; //@@@ - } - else - { - $aData[] = 'id'; //@@@ - } - break; - - default: - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if (($oAttDef instanceof AttributeExternalField) || (($oAttDef instanceof AttributeFriendlyName) && ($oAttDef->GetKeyAttCode() != 'id'))) - { - $oKeyAttDef = MetaModel::GetAttributeDef($sClass, $oAttDef->GetKeyAttCode()); - $oExtAttDef = MetaModel::GetAttributeDef($oKeyAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); - $sLabel = $oKeyAttDef->GetLabel().'->'.$oExtAttDef->GetLabel(); - } - else - { - $sLabel = $oAttDef->GetLabel(); - } - if (count($aSelectedClasses) > 1) - { - $aData[] = $sAlias.'.'.$sLabel; - } - else - { - $aData[] = $sLabel; - } - } - } $sData .= "\n"; $sData .= "\n"; $sData .= "\n"; - foreach($aData as $sLabel) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { - $sData .= "\n"; + $sData .= "\n"; } $sData .= "\n"; $sData .= "\n"; @@ -154,53 +90,18 @@ class HTMLBulkExport extends TabularBulkExport $iPercentage = 0; $oSet = new DBObjectSet($this->oSearch); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); - $aAliases = array_keys($aSelectedClasses); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); + $this->OptimizeColumnLoad($oSet); - $aAliasByField = array(); - $aColumnsToLoad = array(); - - // Prepare the list of aliases / columns to load - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) - { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = reset($aAliases); - $sAttCode = $sExtendedAttCode; - } - - if (!in_array($sAlias, $aAliases)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); - } - - if (!array_key_exists($sAlias, $aColumnsToLoad)) - { - $aColumnsToLoad[$sAlias] = array(); - } - if ($sAttCode != 'id') - { - // id is not a real attribute code and, moreover, is always loaded - $aColumnsToLoad[$sAlias][] = $sAttCode; - } - $aAliasByField[$sExtendedAttCode] = array('alias' => $sAlias, 'attcode' => $sAttCode); - } + $sFirstAlias = $this->oSearch->GetClassAlias(); $iCount = 0; $sData = ''; - $oSet->OptimizeColumnLoad($aColumnsToLoad); $iPreviousTimeLimit = ini_get('max_execution_time'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); while($aRow = $oSet->FetchAssoc()) { set_time_limit($iLoopTimeLimit); - $sFirstAlias = reset($aAliases); $oMainObj = $aRow[$sFirstAlias]; $sHilightClass = ''; if ($oMainObj) @@ -215,20 +116,23 @@ class HTMLBulkExport extends TabularBulkExport { $sData .= ""; } - foreach($aAliasByField as $aAttCode) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { - $oObj = $aRow[$aAttCode['alias']]; + $sAlias = $aFieldSpec['sAlias']; + $sAttCode = $aFieldSpec['sAttCode']; + + $oObj = $aRow[$sAlias]; $sField = ''; if ($oObj) { - switch($aAttCode['attcode']) + switch($sAttCode) { case 'id': - $sField = $aRow[$aAttCode['alias']]->GetHyperlink(); + $sField = $aRow[$sAlias]->GetHyperlink(); break; default: - $sField = $aRow[$aAttCode['alias']]->GetAsHtml($aAttCode['attcode']); + $sField = $aRow[$sAlias]->GetAsHtml($sAttCode); } } $sValue = ($sField === '') ? ' ' : $sField; diff --git a/core/spreadsheetbulkexport.class.inc.php b/core/spreadsheetbulkexport.class.inc.php index 423ea01cf..5b8e1dd33 100644 --- a/core/spreadsheetbulkexport.class.inc.php +++ b/core/spreadsheetbulkexport.class.inc.php @@ -61,13 +61,6 @@ class SpreadsheetBulkExport extends TabularBulkExport } } - public function ReadParameters() - { - parent::ReadParameters(); - - $this->aStatusInfo['localize'] = (utils::ReadParam('no_localize', 0) != 1); - } - protected function GetSampleData($oObj, $sAttCode) { if ($oObj) @@ -88,83 +81,23 @@ class SpreadsheetBulkExport extends TabularBulkExport $this->aStatusInfo['position'] = 0; $this->aStatusInfo['total'] = $oSet->Count(); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); $aData = array(); - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) + $sColLabel = $aFieldSpec['sColLabel']; + if ($aFieldSpec['sAttCode'] != 'id') { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = $this->oSearch->GetClassAlias(); - $sAttCode = $sExtendedAttCode; - } - if (!array_key_exists($sAlias, $aSelectedClasses)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", array_keys($aSelectedClasses))."'"); - } - $sClass = $aSelectedClasses[$sAlias]; - - switch($sAttCode) - { - case 'id': - if (count($aSelectedClasses) > 1) - { - $aData[] = $sAlias.'.id'; //@@@ - } - else - { - $aData[] = 'id'; //@@@ - } - break; - - default: - $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - if (($oAttDef instanceof AttributeExternalField) || (($oAttDef instanceof AttributeFriendlyName) && ($oAttDef->GetKeyAttCode() != 'id'))) - { - $oKeyAttDef = MetaModel::GetAttributeDef($sClass, $oAttDef->GetKeyAttCode()); - $oExtAttDef = MetaModel::GetAttributeDef($oKeyAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); - if ($this->aStatusInfo['localize']) - { - $sColLabel = $oKeyAttDef->GetLabel().'->'.$oExtAttDef->GetLabel(); - } - else - { - $sColLabel = $oKeyAttDef->GetCode().'->'.$oExtAttDef->GetCode(); - } - } - else - { - $sColLabel = $this->aStatusInfo['localize'] ? $oAttDef->GetLabel() : $sAttCode; - } - $oFinalAttDef = $oAttDef->GetFinalAttDef(); - if (get_class($oFinalAttDef) == 'AttributeDateTime') - { - if (count($aSelectedClasses) > 1) - { - $aData[] = $sAlias.'.'.$sColLabel.' ('.Dict::S('UI:SplitDateTime-Date').')'; - $aData[] = $sAlias.'.'.$sColLabel.' ('.Dict::S('UI:SplitDateTime-Time').')'; - } - else - { - $aData[] = $sColLabel.' ('.Dict::S('UI:SplitDateTime-Date').')'; - $aData[] = $sColLabel.' ('.Dict::S('UI:SplitDateTime-Time').')'; - } - } - else - { - if (count($aSelectedClasses) > 1) - { - $aData[] = $sAlias.'.'.$sColLabel; - } - else - { - $aData[] = $sColLabel; - } - } + $oAttDef = MetaModel::GetAttributeDef($aFieldSpec['sClass'], $aFieldSpec['sAttCode']); + $oFinalAttDef = $oAttDef->GetFinalAttDef(); + if (get_class($oFinalAttDef) == 'AttributeDateTime') + { + $aData[] = $sColLabel.' ('.Dict::S('UI:SplitDateTime-Date').')'; + $aData[] = $sColLabel.' ('.Dict::S('UI:SplitDateTime-Time').')'; + } + else + { + $aData[] = $sColLabel; + } } } $sData = "
".$sLabel."".$aFieldSpec['sColLabel']."
\n"; @@ -183,46 +116,11 @@ class SpreadsheetBulkExport extends TabularBulkExport $iPercentage = 0; $oSet = new DBObjectSet($this->oSearch); - $aSelectedClasses = $this->oSearch->GetSelectedClasses(); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); - - $aAliasByField = array(); - $aColumnsToLoad = array(); - - // Prepare the list of aliases / columns to load - foreach($this->aStatusInfo['fields'] as $sExtendedAttCode) - { - if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) - { - $sAlias = $aMatches[1]; - $sAttCode = $aMatches[2]; - } - else - { - $sAlias = $this->oSearch->GetClassAlias(); - $sAttCode = $sExtendedAttCode; - } - - if (!array_key_exists($sAlias, $aSelectedClasses)) - { - throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", array_keys($aSelectedClasses))."'"); - } - - if (!array_key_exists($sAlias, $aColumnsToLoad)) - { - $aColumnsToLoad[$sAlias] = array(); - } - if ($sAttCode != 'id') - { - // id is not a real attribute code and, moreover, is always loaded - $aColumnsToLoad[$sAlias][] = $sAttCode; - } - $aAliasByField[$sExtendedAttCode] = array('alias' => $sAlias, 'attcode' => $sAttCode); - } + $this->OptimizeColumnLoad($oSet); $iCount = 0; $sData = ''; - $oSet->OptimizeColumnLoad($aColumnsToLoad); $iPreviousTimeLimit = ini_get('max_execution_time'); $iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop'); while($aRow = $oSet->FetchAssoc()) @@ -230,17 +128,20 @@ class SpreadsheetBulkExport extends TabularBulkExport set_time_limit($iLoopTimeLimit); $sData .= ""; - foreach($aAliasByField as $aAttCode) + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) { + $sAlias = $aFieldSpec['sAlias']; + $sAttCode = $aFieldSpec['sAttCode']; + $sField = ''; - $oObj = $aRow[$aAttCode['alias']]; + $oObj = $aRow[$sAlias]; if ($oObj == null) { $sData .= ""; continue; } - switch($aAttCode['attcode']) + switch($sAttCode) { case 'id': $sField = $oObj->GetName(); @@ -248,25 +149,25 @@ class SpreadsheetBulkExport extends TabularBulkExport break; default: - $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $aAttCode['attcode']); + $oAttDef = MetaModel::GetAttributeDef(get_class($oObj), $sAttCode); $oFinalAttDef = $oAttDef->GetFinalAttDef(); if (get_class($oFinalAttDef) == 'AttributeDateTime') { - $iDate = AttributeDateTime::GetAsUnixSeconds($oObj->Get($aAttCode['attcode'])); + $iDate = AttributeDateTime::GetAsUnixSeconds($oObj->Get($sAttCode)); $sData .= ''; // Add the first column directly $sField = date('H:i:s', $iDate); // Will add the second column below $sData .= ""; } else if($oAttDef instanceof AttributeCaseLog) { - $rawValue = $oObj->Get($aAttCode['attcode']); + $rawValue = $oObj->Get($sAttCode); $sField = str_replace("\n", "
", htmlentities($rawValue->__toString(), ENT_QUOTES, 'UTF-8')); // Trick for Excel: treat the content as text even if it begins with an equal sign $sData .= ""; } else { - $rawValue = $oObj->Get($aAttCode['attcode']); + $rawValue = $oObj->Get($sAttCode); // Due to custom formatting rules, empty friendlynames may be rendered as non-empty strings // let's fix this and make sure we render an empty string if the key == 0 if ($oAttDef instanceof AttributeFriendlyName) @@ -280,7 +181,7 @@ class SpreadsheetBulkExport extends TabularBulkExport } } } - if ($this->aStatusInfo['localize']) + if ($this->bLocalizeOutput) { $sField = htmlentities($oFinalAttDef->GetEditValue($rawValue), ENT_QUOTES, 'UTF-8'); } diff --git a/core/tabularbulkexport.class.inc.php b/core/tabularbulkexport.class.inc.php index 5f94f8d03..eba74edac 100644 --- a/core/tabularbulkexport.class.inc.php +++ b/core/tabularbulkexport.class.inc.php @@ -310,12 +310,113 @@ EOF } } + // Interpret (and check) the list of fields + // + $aSelectedClasses = $this->oSearch->GetSelectedClasses(); + $aAliases = array_keys($aSelectedClasses); + $aAuthorizedClasses = array(); + foreach($aSelectedClasses as $sAlias => $sClassName) + { + if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ) == UR_ALLOWED_YES) + { + $aAuthorizedClasses[$sAlias] = $sClassName; + } + } $aFields = explode(',', $sFields); $this->aStatusInfo['fields'] = array(); - foreach($aFields as $sField) + foreach($aFields as $sFieldSpec) { - // Trim the values since it's too temping to write: fields=name, first_name, org_name instead of fields=name,first_name,org_name - $this->aStatusInfo['fields'][] = trim($sField); + // Trim the values since it's natural to write: fields=name, first_name, org_name instead of fields=name,first_name,org_name + $sExtendedAttCode = trim($sFieldSpec); + + if (preg_match('/^([^\.]+)\.(.+)$/', $sExtendedAttCode, $aMatches)) + { + $sAlias = $aMatches[1]; + $sAttCode = $aMatches[2]; + } + else + { + $sAlias = reset($aAliases); + $sAttCode = $sExtendedAttCode; + } + if (!array_key_exists($sAlias, $aSelectedClasses)) + { + throw new Exception("Invalid alias '$sAlias' for the column '$sExtendedAttCode'. Availables aliases: '".implode("', '", $aAliases)."'"); + } + $sClass = $aSelectedClasses[$sAlias]; + if (!array_key_exists($sAlias, $aAuthorizedClasses)) + { + throw new Exception("You do not have enough permissions to bulk read data of class '$sClass' (alias: $sAlias)"); + } + + switch($sAttCode) + { + case 'id': + $sLabel = 'id'; + $oAttDef = null; + break; + + default: + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + if (($oAttDef instanceof AttributeExternalField) || (($oAttDef instanceof AttributeFriendlyName) && ($oAttDef->GetKeyAttCode() != 'id'))) + { + $oKeyAttDef = MetaModel::GetAttributeDef($sClass, $oAttDef->GetKeyAttCode()); + $oExtAttDef = MetaModel::GetAttributeDef($oKeyAttDef->GetTargetClass(), $oAttDef->GetExtAttCode()); + if ($this->bLocalizeOutput) + { + $sLabel = $oKeyAttDef->GetLabel().'->'.$oExtAttDef->GetLabel(); + } + else + { + $sLabel = $oKeyAttDef->GetCode().'->'.$oExtAttDef->GetCode(); + } + } + else + { + $sLabel = $this->bLocalizeOutput ? $oAttDef->GetLabel() : $sAttCode; + } + } + if (count($aAuthorizedClasses) > 1) + { + $sColLabel = $sAlias.'.'.$sLabel; + } + else + { + $sColLabel = $sLabel; + } + $this->aStatusInfo['fields'][] = array( + 'sFieldSpec' => $sExtendedAttCode, + 'sAlias' => $sAlias, + 'sClass' => $sClass, + 'sAttCode' => $sAttCode, + 'sLabel' => $sLabel, + 'sColLabel' => $sColLabel + ); } } + + /** + * Prepare the given object set with the list of fields as read into $this->aStatusInfo['fields'] + */ + protected function OptimizeColumnLoad(DBObjectSet $oSet) + { + $aColumnsToLoad = array(); + + foreach($this->aStatusInfo['fields'] as $iCol => $aFieldSpec) + { + $sAlias = $aFieldSpec['sAlias']; + $sAttCode = $aFieldSpec['sAttCode']; + + if (!array_key_exists($sAlias, $aColumnsToLoad)) + { + $aColumnsToLoad[$sAlias] = array(); + } + if ($sAttCode != 'id') + { + // id is not a real attribute code and, moreover, is always loaded + $aColumnsToLoad[$sAlias][] = $sAttCode; + } + } + $oSet->OptimizeColumnLoad($aColumnsToLoad); + } } diff --git a/core/xmlbulkexport.class.inc.php b/core/xmlbulkexport.class.inc.php index 184a02dd9..cdf821da6 100644 --- a/core/xmlbulkexport.class.inc.php +++ b/core/xmlbulkexport.class.inc.php @@ -65,7 +65,6 @@ class XMLBulkExport extends BulkExport { parent::ReadParameters(); - $this->aStatusInfo['localize'] = (utils::ReadParam('no_localize', 0) != 1); $this->aStatusInfo['linksets'] = (utils::ReadParam('linksets', 0) == 1); } @@ -84,6 +83,15 @@ class XMLBulkExport extends BulkExport public function GetHeader() { + // Check permissions + foreach($this->oSearch->GetSelectedClasses() as $sAlias => $sClass) + { + if (UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_READ) != UR_ALLOWED_YES) + { + throw new Exception("You do not have enough permissions to bulk read data of class '$sClass' (alias: $sAlias)"); + } + } + $oSet = new DBObjectSet($this->oSearch); $this->aStatusInfo['position'] = 0; $this->aStatusInfo['total'] = $oSet->Count(); @@ -102,8 +110,6 @@ class XMLBulkExport extends BulkExport $oSet = new DBObjectSet($this->oSearch); $oSet->SetLimit($this->iChunkSize, $this->aStatusInfo['position']); - $bLocalize = $this->aStatusInfo['localize']; - $aClasses = $this->oSearch->GetSelectedClasses(); $aAuthorizedClasses = array(); $aClass2Attributes = array(); @@ -170,7 +176,7 @@ class XMLBulkExport extends BulkExport } else { - $sValue = $oObj->GetAsXML($sAttCode, $bLocalize); + $sValue = $oObj->GetAsXML($sAttCode, $this->bLocalizeOutput); $sData .= "<$sAttCode>$sValue\n"; } }
$sField'.date('Y-m-d', $iDate).'$sField$sField