From 499ec9bfcfe75dbe1e10204da3dcfcbd6b3e1c46 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Philipp=20Sch=C3=BCle?=
Date: Tue, 4 Apr 2023 18:16:07 +0200
Subject: [PATCH] fix(Tinebase/CustomField): fix date custom fields
... values without time (00:00:00) were never displayed in the gui
---
tests/tine20/Addressbook/Import/CsvTest.php | 14 ++++--
tests/tine20/Tinebase/CustomFieldTest.php | 20 ++++++++-
tine20/Tinebase/CustomField.php | 47 ++++++++++++++++-----
tine20/Tinebase/Export/Abstract.php | 2 +-
4 files changed, 67 insertions(+), 16 deletions(-)
diff --git a/tests/tine20/Addressbook/Import/CsvTest.php b/tests/tine20/Addressbook/Import/CsvTest.php
index 99908effaa0..71782996b63 100644
--- a/tests/tine20/Addressbook/Import/CsvTest.php
+++ b/tests/tine20/Addressbook/Import/CsvTest.php
@@ -211,11 +211,15 @@ public function testImportExportWithCustomFieldTypeDate()
. '"key":null},"label":"CF ausgestellt am:","type":"date","required":false}');
$this->_customFieldImportExportHelper([
'definition' => $definition,
- ], '2023-04-04');
+ ], '2023-04-04',
+ // client expects TIME
+ '2023-04-04 00:00:00');
}
/**
- * @param array|string $cfConfig
+ * @param $cfConfig
+ * @param string $cfTestValue
+ * @param string|null $expectedValue
* @return void
* @throws Addressbook_Exception_AccessDenied
* @throws Addressbook_Exception_NotFound
@@ -224,7 +228,9 @@ public function testImportExportWithCustomFieldTypeDate()
* @throws Tinebase_Exception_NotFound
* @throws Tinebase_Exception_Record_DefinitionFailure
*/
- protected function _customFieldImportExportHelper($cfConfig = 'YomiName', $cfTestValue = 'testing')
+ protected function _customFieldImportExportHelper($cfConfig = 'YomiName',
+ string $cfTestValue = 'testing',
+ ?string $expectedValue = null)
{
$customField = $this->_createCustomField($cfConfig);
$this->assertTrue($customField instanceof Tinebase_Model_CustomField_Config);
@@ -251,7 +257,7 @@ protected function _customFieldImportExportHelper($cfConfig = 'YomiName', $cfTes
$exceptionArray = $result['exceptions']->toArray();
$this->assertTrue(isset($exceptionArray[0]['exception']['clientRecord']['customfields']),
'could not find customfields in client record: ' . print_r($exceptionArray[0]['exception']['clientRecord'], TRUE));
- $this->assertEquals($cfTestValue, $exceptionArray[0]['exception']['clientRecord']['customfields'][$customField->name],
+ $this->assertEquals($expectedValue ?? $cfTestValue, $exceptionArray[0]['exception']['clientRecord']['customfields'][$customField->name],
'could not find cf value in client record: ' . print_r($exceptionArray[0]['exception']['clientRecord'], TRUE));
}
diff --git a/tests/tine20/Tinebase/CustomFieldTest.php b/tests/tine20/Tinebase/CustomFieldTest.php
index b52a51047fd..8b85305d781 100644
--- a/tests/tine20/Tinebase/CustomFieldTest.php
+++ b/tests/tine20/Tinebase/CustomFieldTest.php
@@ -404,8 +404,12 @@ protected function _createContactWithCustomField($customFieldValue)
* @param string $type
* @param mixed $customFieldValue
* @param array $filtersToTest
+ * @return void
+ * @throws Tinebase_Exception_InvalidArgument
+ * @throws Tinebase_Exception_NotFound
+ * @throws Tinebase_Exception_Record_DefinitionFailure
*/
- protected function _testContactCustomFieldOfType($type, $customFieldValue, $filtersToTest)
+ protected function _testContactCustomFieldOfType(string $type, $customFieldValue, array $filtersToTest)
{
$this->_testCustomField = $this->_createCustomField('test', 'Addressbook_Model_Contact', $type);
$contact = $this->_createContactWithCustomField($customFieldValue);
@@ -425,6 +429,11 @@ protected function _testContactCustomFieldOfType($type, $customFieldValue, $filt
. ' cf value: ' . $customFieldValue
);
static::assertTrue(in_array($contact->getId(), $result->getArrayOfIds()));
+ if (isset($filterToTest['expectedValue'])) {
+ $recordCustomfields = $result->getFirstRecord()->customfields;
+ self::assertEquals($filterToTest['expectedValue'],
+ $recordCustomfields[$this->_testCustomField->name], print_r($recordCustomfields, true));
+ }
} else {
static::assertFalse(in_array($contact->getId(), $result->getArrayOfIds()));
}
@@ -717,4 +726,13 @@ public function testCustomKeyFieldFilterEmpty()
];
$this->_testContactCustomFieldOfType('keyField', $value, $filtersToTest);
}
+
+ public function testCustomDateField()
+ {
+ $value = '2022-01-21';
+ $filtersToTest = [
+ ['operator' => 'equals', 'value' => '2022-01-21', 'expectContactToBeFound' => 1, 'expectedValue' => '2022-01-21 00:00:00'],
+ ];
+ $this->_testContactCustomFieldOfType('date', $value, $filtersToTest);
+ }
}
diff --git a/tine20/Tinebase/CustomField.php b/tine20/Tinebase/CustomField.php
index f4ee1111773..3f280aec367 100644
--- a/tine20/Tinebase/CustomField.php
+++ b/tine20/Tinebase/CustomField.php
@@ -479,22 +479,20 @@ public function saveRecordCustomFields(Tinebase_Record_Interface $_record)
foreach ($appCustomFields as $customField) {
if (is_array($_record->customfields) && (isset($_record->customfields[$customField->name]) || array_key_exists($customField->name, $_record->customfields))) {
- $value = $_record->customfields[$customField->name];
$filtered = $existingCustomFields->filter('customfield_id', $customField->id);
-
- // we need to resolve the modelName and the record value if array is given (e.g. on updating customfield)
- if (isset($customField->definition['type']) && (strtolower($customField->definition['type']) == 'record' || strtolower($customField->definition['type']) == 'recordlist')) {
- $value = $this->_getValueForRecordOrListCf($_record, $customField, $value);
- }
+ $value = $this->_getCustomFieldValue($_record, $customField);
switch (count($filtered)) {
case 1:
$cf = $filtered->getFirstRecord();
if ($customField->valueIsEmpty($value)) {
- if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Deleting cf value for ' . $customField->name);
+ if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(
+ __METHOD__ . '::' . __LINE__ . ' Deleting cf value for ' . $customField->name);
$this->_backendValue->delete($cf);
} else {
- if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Updating value for ' . $customField->name . ' to ' . $value);
+ if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(
+ __METHOD__ . '::' . __LINE__ . ' Updating value for ' . $customField->name . ' to '
+ . $value);
$cf->value = $value;
$this->_backendValue->update($cf);
}
@@ -507,7 +505,8 @@ public function saveRecordCustomFields(Tinebase_Record_Interface $_record)
'value' => $value
));
if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(
- __METHOD__ . '::' . __LINE__ . ' Creating value for ' . $customField->name . ' -> ' . print_r($value, true));
+ __METHOD__ . '::' . __LINE__ . ' Creating value for ' . $customField->name . ' -> '
+ . print_r($value, true));
try {
$this->_backendValue->create($cf);
} catch (Zend_Db_Statement_Exception $zdse) {
@@ -527,6 +526,34 @@ public function saveRecordCustomFields(Tinebase_Record_Interface $_record)
}
}
+ /**
+ * @param Tinebase_Record_Interface $_record
+ * @param Tinebase_Model_CustomField_Config $customField
+ * @return null|string
+ * @throws Tinebase_Exception_Record_Validation
+ */
+ protected function _getCustomFieldValue(Tinebase_Record_Interface $_record,
+ Tinebase_Model_CustomField_Config $customField): ?string
+ {
+ $value = $_record->customfields[$customField->name];
+
+ if (isset($customField->definition['type'])) {
+ switch (strtolower($customField->definition['type'])) {
+ case 'record':
+ case 'recordlist':
+ // we need to resolve the modelName and the record value if array is given (e.g. on updating customfield)
+ $value = $this->_getValueForRecordOrListCf($_record, $customField, $value);
+ break;
+ case 'date':
+ if (strpos($value, '00:00:00') === false) {
+ $value .= ' 00:00:00';
+ }
+ break;
+ }
+ }
+ return $value;
+ }
+
public static function getModelNameFromDefinition($definition)
{
$modelParts = explode('.', $definition[$definition['type'] . 'Config']['value']['records']);
@@ -546,7 +573,7 @@ protected function _getValueForRecordOrListCf($_record, $_customField, $_value)
$modelName = self::getModelNameFromDefinition($_customField->definition);
$model = new $modelName(array(), true);
$idProperty = $model->getIdProperty();
- if (is_array($_value)) {
+ if (! is_scalar($_value)) {
if (strtolower($_customField->definition['type']) == 'record') {
/** @var Tinebase_Record_Interface $model */
$value = $_value[$idProperty];
diff --git a/tine20/Tinebase/Export/Abstract.php b/tine20/Tinebase/Export/Abstract.php
index 1e692bd5b9d..d598ecf86a4 100644
--- a/tine20/Tinebase/Export/Abstract.php
+++ b/tine20/Tinebase/Export/Abstract.php
@@ -1662,7 +1662,7 @@ protected function _convertToString($_value, ?string $_type = null)
}
$_value = Tinebase_Translation::dateToStringInTzAndLocaleFormat($_value, null, null,
$format);
- } elseif($_value instanceof Tinebase_Model_CustomField_Config) {
+ } elseif ($_value instanceof Tinebase_Model_CustomField_Config) {
$_value = $_value->value->__toString();
} elseif ($_value instanceof Tinebase_Config_KeyFieldRecord) {
$_value = $_value->__toString();