[TikiWiki-commits] [Git][tikiwiki/tiki][27.x] [ENH] tracker calendar item: auto-sync event date, multi-field support
"Victor Emanouilov \(@kroky\) via TikiWiki-cvs" <[email protected]>
| Newsgroups | gmane.comp.cms.tiki.cvs |
|---|---|
| Message-ID | <68aff53f6a01a_2cd785c38996@gitlab-sidekiq-low-urgency-cpu-bound-v2-74548c97d-lsv8c.mail> |
Victor Emanouilov pushed to branch 27.x at Tiki Wiki CMS Groupware / Tiki
Commits:
7abef06c by Victor Emanouilov at 2025-08-28T09:20:37+03:00
[ENH] tracker calendar item: auto-sync event date, multi-field support
---
* [ENH] tracker calendar item: auto-sync event date, ability to support more than one calendar item field per item (e.g. different expiry dates), respect datetime vs date allday events
See merge request tikiwiki/tiki!8432
- - - - -
5 changed files:
- db/tiki.sql
- + installer/schema/20250828_add_fieldId_to_attributes_tiki.sql
- lib/attributes/attributelib.php
- lib/core/Services/Attribute/Controller.php
- lib/core/Tracker/Field/CalendarItem.php
Changes:
=====================================
db/tiki.sql
=====================================
@@ -3678,6 +3678,7 @@ CREATE TABLE `tiki_object_attributes` (
`itemId` varchar(160) NOT NULL,
`attribute` varchar(70) NOT NULL,
`value` varchar(255),
+ `fieldId` INT DEFAULT NULL,
`comment` varchar(255),
UNIQUE `item_attribute_uq` ( `type`, `itemId`(91), `attribute`(50) ),
KEY `attribute_lookup_ix` (`attribute`, `value`(121))
=====================================
installer/schema/20250828_add_fieldId_to_attributes_tiki.sql
=====================================
@@ -0,0 +1,9 @@
+ALTER TABLE `tiki_object_attributes` ADD COLUMN `fieldId` INT DEFAULT NULL AFTER `value`;
+UPDATE `tiki_object_attributes` toa
+ SET toa.`fieldId` = (
+ SELECT ttf.`fieldId`
+ FROM `tiki_tracker_fields` ttf, `tiki_tracker_items` tti
+ WHERE tti.itemId = toa.`itemId` AND ttf.trackerId = tti.trackerId AND ttf.type = 'CAL'
+ LIMIT 1
+ )
+ WHERE toa.`attribute` = 'tiki.calendar.item' and toa.`type` = 'trackeritem';
\ No newline at end of file
=====================================
lib/attributes/attributelib.php
=====================================
@@ -77,13 +77,18 @@ class AttributeLib extends TikiDb_Bridge
* @param $type string One of \ObjectLib::get_supported_types()
* @param $objectId mixed Object id (or name for wiki pages)
* @param $attribute string At least two dots and only lowercase letters
+ * @param $fieldId int Field id (optional)
* @return string|boolean Contents of the attribute on the object or false if not present
*/
- public function get_attribute($type, $objectId, $attribute)
+ public function get_attribute($type, $objectId, $attribute, $fieldId = null)
{
+ $search = ['type' => $type, 'itemId' => $objectId, 'attribute' => $attribute];
+ if ($fieldId) {
+ $search['fieldId'] = $fieldId;
+ }
return $this->attributes->fetchOne(
'value',
- ['type' => $type, 'itemId' => $objectId, 'attribute' => $attribute]
+ $search
);
}
@@ -97,19 +102,20 @@ class AttributeLib extends TikiDb_Bridge
* attribute naming, and document new tiki.*.* names that you add
* (also grep "set_attribute" just in case there are undocumented names already used)
*/
- public function set_attribute($type, $objectId, $attribute, $value, $comment = null)
+ public function set_attribute($type, $objectId, $attribute, $value, $comment = null, $fieldId = null)
{
if (false === $name = $this->get_valid($attribute)) {
return false;
}
+ $search = ['type' => $type, 'itemId' => $objectId, 'attribute' => $name];
+ if ($fieldId) {
+ $search['fieldId'] = $fieldId;
+ }
+
if ($value === '') {
$this->attributes->delete(
- [
- 'type' => $type,
- 'itemId' => $objectId,
- 'attribute' => $name,
- ]
+ $search
);
} else {
$this->attributes->insertOrUpdate(
@@ -117,11 +123,7 @@ class AttributeLib extends TikiDb_Bridge
'value' => $value,
'comment' => $comment,
],
- [
- 'type' => $type,
- 'itemId' => $objectId,
- 'attribute' => $name,
- ]
+ $search
);
}
@@ -150,13 +152,16 @@ class AttributeLib extends TikiDb_Bridge
* @param $value
* @return mixed
*/
- public function find_objects_with($attribute, $value)
+ public function find_objects_with($attribute, $value, $fieldId = null)
{
$attribute = $this->get_valid($attribute);
-
+ $search = ['attribute' => $attribute, 'value' => $value];
+ if ($fieldId) {
+ $search['fieldId'] = $fieldId;
+ }
return $this->attributes->fetchAll(
- ['type', 'itemId', 'comment'],
- ['attribute' => $attribute, 'value' => $value,]
+ ['type', 'itemId', 'comment', 'fieldId'],
+ $search
);
}
@@ -165,11 +170,16 @@ class AttributeLib extends TikiDb_Bridge
* @param $value
* @return mixed
*/
- public function delete_objects_with($attribute, $value)
+ public function delete_objects_with($attribute, $value, $fieldId = null)
{
$attribute = $this->get_valid($attribute);
+
+ $search = ['attribute' => $attribute, 'value' => $value];
+ if ($fieldId) {
+ $search['fieldId'] = $fieldId;
+ }
return $this->attributes->delete(
- ['attribute' => $attribute, 'value' => $value]
+ $search
);
}
}
=====================================
lib/core/Services/Attribute/Controller.php
=====================================
@@ -17,6 +17,7 @@ class Services_Attribute_Controller
* ->attribute string lowercase letters and two dots
* ->type string object type
* ->object mixed id or name of object
+ * ->fieldId int optionalfieldId
*
* @return array value=>string containing the value
* @throws Exception
@@ -27,6 +28,8 @@ class Services_Attribute_Controller
$attribute = $input->attribute->text();
$type = $input->type->text();
$object = $input->object->text();
+ $fieldId = $input->fieldId->int();
+ $fieldId = $fieldId == 0 ? null : $fieldId;
$value = '';
// ensure the target, source, and relation info are passed to the service
@@ -35,7 +38,7 @@ class Services_Attribute_Controller
}
if ($object) { // for objects yet to be created we don't get an object id, so don't set any attributes
- $value = TikiLib::lib('attribute')->get_attribute($type, $object, $attribute);
+ $value = TikiLib::lib('attribute')->get_attribute($type, $object, $attribute, $fieldId);
}
//return the attribute value if there were no errors
@@ -51,6 +54,8 @@ class Services_Attribute_Controller
$value = $input->value->text();
$comment = $input->comment->text();
$attribute = $input->attribute->text();
+ $fieldId = $input->fieldId->int();
+ $fieldId = $fieldId == 0 ? null : $fieldId;
// Check if required infos are passed to the service
if (! $type || ! $itemId || ! $attribute) {
@@ -69,7 +74,8 @@ class Services_Attribute_Controller
$itemId,
$attribute,
$value,
- $comment
+ $comment,
+ $fieldId
);
}
@@ -77,6 +83,8 @@ class Services_Attribute_Controller
{
$attribute = $input->attribute->text();
$value = $input->value->text();
+ $fieldId = $input->fieldId->int();
+ $fieldId = $fieldId == 0 ? null : $fieldId;
// Check if info are passed to the service
if (! $attribute || ! $value) {
@@ -91,7 +99,8 @@ class Services_Attribute_Controller
$attributeLib = TikiLib::lib('attribute');
$ojects = $attributeLib->find_objects_with(
$attribute,
- $value
+ $value,
+ $fieldId
);
return [
@@ -104,6 +113,8 @@ class Services_Attribute_Controller
$type = $input->type->text();
$itemId = $input->itemId->text();
$attribute = $input->attribute->text();
+ $fieldId = $input->fieldId->int();
+ $fieldId = $fieldId == 0 ? null : $fieldId;
// Check if info are passed to the service
if (! $type || ! $itemId || ! $attribute) {
@@ -120,7 +131,8 @@ class Services_Attribute_Controller
$result = $attributeLib->get_attribute(
$type,
$itemId,
- $attribute
+ $attribute,
+ $fieldId
);
return $result;
=====================================
lib/core/Tracker/Field/CalendarItem.php
=====================================
@@ -40,6 +40,16 @@ class Tracker_Field_CalendarItem extends Tracker_Field_JsCalendar
1 => tr('Yes'),
],
],
+ 'overrideCalendarItemTime' => [
+ 'name' => tr('Override Calendar Item Time'),
+ 'description' => tr('When saving the tracker item, should it override the calendar item date and time with this field\'s value or should it prefer the calendar item date and time?'),
+ 'filter' => 'int',
+ 'options' => [
+ 0 => tr('Prefer Calendar Item Time'),
+ 1 => tr('Override Calendar Item Time'),
+ ],
+ 'default' => 0,
+ ],
],
],
];
@@ -118,11 +128,25 @@ class Tracker_Field_CalendarItem extends Tracker_Field_JsCalendar
if ($itemId) {
$trackerId = $this->getConfiguration('trackerId');
+ if ($this->getOption('datetime') == 'd') {
+ // convert to UTC @12:00am, so we don't depend on user's timezone when displaying later
+ $start = new TikiDate();
+ $start->setDate($value);
+ $start->setTZbyID(TikiLib::lib('tiki')->get_display_timezone());
+ $start->convertTimeToUTC(0, 0, 0);
+ $start = $start->getTime();
+ $end = $start;
+ } else {
+ $start = $value;
+ $end = $value + 3600;
+ }
+
if (! $event) { // new calendar item please
$data = [
'calendarId' => $calendarId,
- 'start' => $value,
- 'end' => $value + 3600,
+ 'start' => $start,
+ 'end' => $end,
+ 'allday' => $this->getOption('datetime') == 'd' ? 1 : 0,
// 'locationId',
// 'categoryId',
// 'nlId',
@@ -146,8 +170,15 @@ class Tracker_Field_CalendarItem extends Tracker_Field_JsCalendar
$calitemId = $this->calendarLib->getMaxItemId();
$this->setCalendarItemId($calitemId);
- } elseif ($event['start'] != $value) {
- $value = (int) $event['start'];
+ } elseif ($event['start'] != $start) {
+ if ($this->getOption('overrideCalendarItemTime')) {
+ $event['start'] = $start;
+ $event['end'] = $end;
+ $client = new \Tiki\SabreDav\CaldavClient();
+ $client->saveCalendarObject($event);
+ } else {
+ $value = (int) $event['start'];
+ }
}
}
}
@@ -274,7 +305,7 @@ class Tracker_Field_CalendarItem extends Tracker_Field_JsCalendar
*/
private function getCalendarItemId()
{
- $calitemId = $this->attributeLib->get_attribute('trackeritem', $this->getItemId(), 'tiki.calendar.item');
+ $calitemId = $this->attributeLib->get_attribute('trackeritem', $this->getItemId(), 'tiki.calendar.item', $this->getFieldId());
return $calitemId;
}
@@ -283,7 +314,7 @@ class Tracker_Field_CalendarItem extends Tracker_Field_JsCalendar
*/
private function removeCalendarItemId()
{
- $this->attributeLib->set_attribute('trackeritem', $this->getItemId(), 'tiki.calendar.item', '');
+ $this->attributeLib->set_attribute('trackeritem', $this->getItemId(), 'tiki.calendar.item', '', null, $this->getFieldId());
}
/**
@@ -295,7 +326,9 @@ class Tracker_Field_CalendarItem extends Tracker_Field_JsCalendar
'trackeritem',
$this->getItemId(),
'tiki.calendar.item',
- $calitemId
+ $calitemId,
+ null,
+ $this->getFieldId()
);
}
}
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/7abef06c1c5c06fe777560c20eda8c79bd1a9e8c
--
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/7abef06c1c5c06fe777560c20eda8c79bd1a9e8c
You're receiving this email because of your account on gitlab.com.
_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs