diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 7ab6646a8..e282b43e3 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -742,7 +742,7 @@ abstract class AttributeDefinition * * @return mixed a value out of suffix/value pairs, for SELECT result interpretation */ - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { return null; } @@ -2402,9 +2402,9 @@ class AttributeDBFieldVoid extends AttributeDefinition return $aColumns; } - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { - $value = $this->MakeRealValue($aCols[$sPrefix.''], null); + $value = $this->MakeRealValue($aCols[$sPrefix.''], $oHostObject); return $value; } @@ -3913,7 +3913,7 @@ class AttributeEncryptedString extends AttributeString * @return string * @throws \Exception */ - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $oSimpleCrypt = new SimpleCrypt(self::$sLibrary); $sValue = $oSimpleCrypt->Decrypt(self::$sKey, $aCols[$sPrefix]); @@ -4283,7 +4283,7 @@ class AttributeText extends AttributeString * * @return string */ - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $value = $aCols[$sPrefix.'']; if ($this->GetOptional('format', null) != null) @@ -4577,7 +4577,7 @@ class AttributeCaseLog extends AttributeLongText * @return \ormCaseLog * @throws \MissingColumnException */ - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { if (!array_key_exists($sPrefix, $aCols)) { @@ -7378,18 +7378,18 @@ class AttributeExternalField extends AttributeDefinition //public function GetSQLExpressions($sPrefix = '') {return array();} // Here, we get the data... - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $oExtAttDef = $this->GetExtAttDef(); - return $oExtAttDef->FromSQLToValue($aCols, $sPrefix); + return $oExtAttDef->FromSQLToValue($aCols, $sPrefix, $oHostObject, $sHostAttCode); } public function GetAsHTML($value, $oHostObject = null, $bLocalize = true) { $oExtAttDef = $this->GetExtAttDef(); - return $oExtAttDef->GetAsHTML($value, null, $bLocalize); + return $oExtAttDef->GetAsHTML($value, $oHostObject, $bLocalize); } public function GetAsXML($value, $oHostObject = null, $bLocalize = true) @@ -7645,6 +7645,10 @@ class AttributeBlob extends AttributeDefinition if (is_object($proposedValue)) { + if (!$proposedValue instanceof ormDocument) + { + throw new Exception(__METHOD__.": unexpected class ".get_class($proposedValue)); + } $proposedValue = clone $proposedValue; } else @@ -7661,6 +7665,7 @@ class AttributeBlob extends AttributeDefinition } } + $proposedValue->SetHostObject($oHostObj, $this->GetCode()); return $proposedValue; } @@ -7679,7 +7684,7 @@ class AttributeBlob extends AttributeDefinition return $aColumns; } - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { if (!array_key_exists($sPrefix, $aCols)) { @@ -7703,7 +7708,7 @@ class AttributeBlob extends AttributeDefinition $sFileName = isset($aCols[$sPrefix.'_filename']) ? $aCols[$sPrefix.'_filename'] : ''; $value = new ormDocument($data, $sMimeType, $sFileName); - + $value->SetHostObject($oHostObject, $sHostAttCode); return $value; } @@ -8219,7 +8224,7 @@ class AttributeStopWatch extends AttributeDefinition return date("Y-m-d H:i:s", $iSeconds); } - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $aExpectedCols = array($sPrefix, $sPrefix.'_started', $sPrefix.'_laststart', $sPrefix.'_stopped'); foreach($this->ListThresholds() as $iThreshold => $aFoo) @@ -9056,7 +9061,7 @@ class AttributeSubItem extends AttributeDefinition // // protected function ScalarToSQL($value) {return $value;} // format value as a valuable SQL literal (quoted outside) - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { } @@ -9274,7 +9279,7 @@ class AttributeOneWayPassword extends AttributeDefinition return $aColumns; } - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { if (!array_key_exists($sPrefix, $aCols)) { @@ -9471,7 +9476,7 @@ class AttributeTable extends AttributeDBField return $proposedValue; } - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { try { @@ -9486,11 +9491,11 @@ class AttributeTable extends AttributeDBField } if ($value === false) { - $value = $this->MakeRealValue($aCols[$sPrefix.''], null); + $value = $this->MakeRealValue($aCols[$sPrefix.''], $oHostObject); } } catch (Exception $e) { - $value = $this->MakeRealValue($aCols[$sPrefix.''], null); + $value = $this->MakeRealValue($aCols[$sPrefix.''], $oHostObject); } return $value; @@ -9885,11 +9890,11 @@ abstract class AttributeSet extends AttributeDBFieldVoid * @return mixed * @throws \Exception */ - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $sValue = $aCols["$sPrefix"]; - return $this->MakeRealValue($sValue, null, true); + return $this->MakeRealValue($sValue, $oHostObject, true); } /** @@ -11034,7 +11039,7 @@ class AttributeTagSet extends AttributeSet * @throws \CoreException * @throws \Exception */ - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $sValue = $aCols["$sPrefix"]; @@ -11616,7 +11621,7 @@ class AttributeFriendlyName extends AttributeDefinition return $sLabel; } - public function FromSQLToValue($aCols, $sPrefix = '') + public function FromSQLToValue($aCols, $sPrefix = '', $oHostObject = null, $sHostAttCode = null) { $sValue = $aCols[$sPrefix]; diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 263592ca5..5263184c6 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -461,7 +461,7 @@ abstract class DBObject implements iDisplay if (array_key_exists($sAttRef, $aRow)) { - $value = $oAttDef->FromSQLToValue($aRow, $sAttRef); + $value = $oAttDef->FromSQLToValue($aRow, $sAttRef, $this, $sAttCode); $bIsDefined = true; } } diff --git a/core/oql/expression.class.inc.php b/core/oql/expression.class.inc.php index 8b2e43e27..25ac6de80 100644 --- a/core/oql/expression.class.inc.php +++ b/core/oql/expression.class.inc.php @@ -1643,6 +1643,35 @@ class FieldExpression extends UnaryExpression // Has been resolved into an SQL expression class FieldExpressionResolved extends FieldExpression { + protected $m_aAdditionalExpressions; + + public function __construct($mExpression, $sParent = '') + { + $this->m_aAdditionalExpressions = array(); + if (is_array($mExpression)) + { + foreach ($mExpression as $sSuffix => $sExpression) + { + if ($sSuffix == '') + { + $sName = $sExpression; + } + $this->m_aAdditionalExpressions[$sSuffix] = new FieldExpressionResolved($sExpression, $sParent); + } + } + else + { + $sName = $mExpression; + } + + parent::__construct($sName, $sParent); + } + + public function AdditionalExpressions() + { + return $this->m_aAdditionalExpressions; + } + public function GetUnresolvedFields($sAlias, &$aUnresolved) { } diff --git a/core/ormdocument.class.inc.php b/core/ormdocument.class.inc.php index aa8b91eba..98fc02dd5 100644 --- a/core/ormdocument.class.inc.php +++ b/core/ormdocument.class.inc.php @@ -38,6 +38,8 @@ class ormDocument protected $m_data; protected $m_sMimeType; protected $m_sFileName; + protected $m_oHostObject; + protected $m_sHostObjectAttcode; /** * Constructor @@ -47,6 +49,15 @@ class ormDocument $this->m_data = $data; $this->m_sMimeType = $sMimeType; $this->m_sFileName = $sFileName; + + $this->m_oHostObject = null; + $this->m_sHostObjectAttcode = null; + } + + public function SetHostObject(DBObject $oHostObject, $sAttCode) + { + $this->m_oHostObject = $oHostObject; + $this->m_sHostObjectAttcode = $sAttCode; } public function __toString() @@ -138,6 +149,12 @@ class ormDocument */ public function GetDownloadLink($sClass, $Id, $sAttCode) { + if ($this->m_oHostObject) + { + $sClass = get_class($this->m_oHostObject); + $Id = $this->m_oHostObject->GetKey(); + $sAttCode = $this->m_sHostObjectAttcode; + } return "".htmlentities($this->GetFileName(), ENT_QUOTES, 'UTF-8')."\n"; } @@ -147,6 +164,12 @@ class ormDocument */ public function GetDisplayURL($sClass, $Id, $sAttCode) { + if ($this->m_oHostObject) + { + $sClass = get_class($this->m_oHostObject); + $Id = $this->m_oHostObject->GetKey(); + $sAttCode = $this->m_sHostObjectAttcode; + } // TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route) return utils::GetAbsoluteUrlAppRoot() . "pages/ajax.render.php?operation=display_document&class=$sClass&id=$Id&field=$sAttCode"; } @@ -157,6 +180,12 @@ class ormDocument */ public function GetDownloadURL($sClass, $Id, $sAttCode) { + if ($this->m_oHostObject) + { + $sClass = get_class($this->m_oHostObject); + $Id = $this->m_oHostObject->GetKey(); + $sAttCode = $this->m_sHostObjectAttcode; + } // Compute a signature to reset the cache anytime the data changes (this is acceptable if used only with icon files) $sSignature = md5($this->GetData()); // TODO: When refactoring this with the URLMaker system, mind to also change calls in the portal (look for the "p_object_document_display" route) diff --git a/core/querybuilderexpressions.class.inc.php b/core/querybuilderexpressions.class.inc.php index 5f3aca1cf..c713610a8 100644 --- a/core/querybuilderexpressions.class.inc.php +++ b/core/querybuilderexpressions.class.inc.php @@ -178,6 +178,14 @@ class QueryBuilderExpressions foreach ($this->m_aSelectExpr as $sColAlias => $oExpr) { $this->m_aSelectExpr[$sColAlias] = $oExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved); + if ($this->m_aSelectExpr[$sColAlias] instanceof FieldExpressionResolved) + { + // Split the field with the relevant alias + foreach ($this->m_aSelectExpr[$sColAlias]->AdditionalExpressions() as $sSuffix => $oAdditionalExpr) + { + $this->m_aSelectExpr[$sColAlias.$sSuffix] = $oAdditionalExpr->Translate($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved); + } + } } if ($this->m_aGroupByExpr) { diff --git a/core/sqlobjectquerybuilder.class.inc.php b/core/sqlobjectquerybuilder.class.inc.php index b1ecb1d43..4d85480ba 100644 --- a/core/sqlobjectquerybuilder.class.inc.php +++ b/core/sqlobjectquerybuilder.class.inc.php @@ -239,24 +239,16 @@ class SQLObjectQueryBuilder continue; } $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); - foreach ($oAttDef->GetSQLExpressions() as $sColId => $sSQLExpr) + $oFieldSQLExp = new FieldExpressionResolved($oAttDef->GetSQLExpressions(), $sClassAlias); + /** + * @var string $sPluginClass + * @var iQueryModifier $oQueryModifier + */ + foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier) { - if (!empty($sColId)) - { - // Multi column attributes - $oBuild->m_oQBExpressions->AddSelect($sSelectedClassAlias.$sAttCode.$sColId, new FieldExpression($sAttCode.$sColId, $sClassAlias)); - } - $oFieldSQLExp = new FieldExpressionResolved($sSQLExpr, $sClassAlias); - /** - * @var string $sPluginClass - * @var iQueryModifier $oQueryModifier - */ - foreach (MetaModel::EnumPlugins('iQueryModifier') as $sPluginClass => $oQueryModifier) - { - $oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sClass, $sAttCode, $sColId, $oFieldSQLExp, $oBaseSQLQuery); - } - $aTranslation[$sClassAlias][$sAttCode.$sColId] = $oFieldSQLExp; + $oFieldSQLExp = $oQueryModifier->GetFieldExpression($oBuild, $sClass, $sAttCode, '', $oFieldSQLExp, $oBaseSQLQuery); } + $aTranslation[$sClassAlias][$sAttCode] = $oFieldSQLExp; } // Translate the selected columns