mirror of
https://gitlab.com/davical-project/davical.git
synced 2026-08-03 14:09:23 +00:00
Update instance range columns when a collection's timezone changes
TODO: Handle the case where it is updated through the web UI
This commit is contained in:
parent
7b55b7b1f2
commit
fe443bf2e6
@ -231,6 +231,9 @@ function UpdateCollectionTimezones( $username, $new_timezone=null ) {
|
||||
if ( empty($new_timezone) ) return;
|
||||
$qry = new AwlQuery('UPDATE collection SET timezone=? WHERE dav_name LIKE ? AND is_calendar', '/'.$username.'/%', $new_timezone);
|
||||
$qry->Exec();
|
||||
|
||||
require_once("instance_range.php");
|
||||
update_instance_ranges($dav_resource->dav_name());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -275,6 +275,8 @@ foreach( $setprops AS $k => $setting ) {
|
||||
|
||||
$qry->QDo('UPDATE collection SET timezone = :tzid WHERE dav_name = :dav_name',
|
||||
array( ':tzid' => $tzid, ':dav_name' => $dav_resource->dav_name()) );
|
||||
require_once("instance_range.php");
|
||||
update_instance_ranges($dav_resource->dav_name());
|
||||
}
|
||||
else {
|
||||
add_failure('set', $tag, 'HTTP/1.1 409 Conflict', translate("calendar-timezone property is only valid for a calendar."));
|
||||
@ -389,6 +391,8 @@ foreach( $rmprops AS $k => $setting ) {
|
||||
case 'urn:ietf:params:xml:ns:caldav:calendar-timezone':
|
||||
if ( $dav_resource->IsCollection() && $dav_resource->IsCalendar() && ! $dav_resource->IsBinding() ) {
|
||||
$qry->QDo('UPDATE collection SET timezone = NULL WHERE dav_name = :dav_name', array( ':dav_name' => $dav_resource->dav_name()) );
|
||||
require_once("instance_range.php");
|
||||
update_instance_ranges($dav_resource->dav_name());
|
||||
}
|
||||
else {
|
||||
add_failure('rm', $tag, 'HTTP/1.1 403 Forbidden',
|
||||
|
||||
55
inc/instance_range.php
Normal file
55
inc/instance_range.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
require_once("RRule.php");
|
||||
require_once("vCalendar.php");
|
||||
|
||||
function update_instance_ranges(string $collection_dav_name) {
|
||||
// This can take a while, since vCalendar parsing is very slow, and we're
|
||||
// going to parse every event in the collection!
|
||||
//
|
||||
// Since we might be doing this during a caldav request which we'd rather not
|
||||
// have fail, we increase the execution time limit to prevent timeouts
|
||||
set_time_limit(120);
|
||||
|
||||
$qry = new AwlQuery();
|
||||
|
||||
$in_transaction = ($qry->TransactionState() == 1);
|
||||
if ( ! $in_transaction ) $qry->Begin();
|
||||
|
||||
$qry->QDo(
|
||||
"SELECT d.dav_id, c.collection_id, d.caldav_data, c.timezone, i.first_instance_start, i.last_instance_end
|
||||
FROM caldav_data d
|
||||
INNER JOIN collection c ON d.collection_id = c.collection_id
|
||||
INNER JOIN calendar_item i ON d.collection_id = i.collection_id AND d.dav_id = i.dav_id
|
||||
WHERE c.dav_name = :dav_name",
|
||||
[":dav_name" => $collection_dav_name]
|
||||
);
|
||||
|
||||
while( $row = $qry->Fetch() ) {
|
||||
$range = getVCalendarRange(new vCalendar($row->caldav_data), $row->timezone);
|
||||
|
||||
$new_start = isset($range->from) ? $range->from->UTC() : null;
|
||||
$new_end = isset($range->until) ? $range->until->UTC() : null;
|
||||
|
||||
if ($new_start != $row->first_instance_start || $new_end != $row->last_instance_end) {
|
||||
$inner_qry = new AwlQuery(
|
||||
"UPDATE calendar_item
|
||||
SET first_instance_start = :first_instance_start,
|
||||
last_instance_end = :last_instance_end
|
||||
WHERE collection_id = :collection_id AND dav_id = :dav_id",
|
||||
[
|
||||
":dav_id" => $row->dav_id,
|
||||
":collection_id" => $row->collection_id,
|
||||
|
||||
":first_instance_start" => $new_start,
|
||||
":last_instance_end" => $new_end
|
||||
]
|
||||
);
|
||||
$inner_qry->Exec('UpdateInstanceRange',__LINE__,__FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $in_transaction ) $qry->Commit();
|
||||
}
|
||||
|
||||
?>
|
||||
@ -91,7 +91,14 @@ if ( $can_write_collection && $editor->IsSubmit() ) {
|
||||
}
|
||||
else {
|
||||
$c->messages[] = i18n("Updating Collection.");
|
||||
|
||||
// We need to know whether to update_instance_ranges, which is an expensive
|
||||
// operation we should only do if the collection timezone has been updated
|
||||
$tzqry = new AwlQuery( "SELECT timezone FROM collection WHERE collection_id=:id", [ ":id" => $id ] );
|
||||
$tzqry->Exec('collection-edit',__LINE__,__FILE__);
|
||||
$old_tz = $tzqry->Fetch()->timezone;
|
||||
}
|
||||
|
||||
if ( !$editor->Write() ) {
|
||||
$c->messages[] = i18n("Failed to write collection.");
|
||||
if ( $id > 0 ) $editor->GetRecord();
|
||||
@ -121,6 +128,13 @@ if ( $can_write_collection && $editor->IsSubmit() ) {
|
||||
$c->messages[] = i18n('The file is not UTF-8 encoded, please check the error for more details.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($editor->IsCreate() || $old_tz != $_POST['timezone']) {
|
||||
dbg_error_log('collection-edit', 'Need to update instance ranges, this will take a while...');
|
||||
require_once("instance_range.php");
|
||||
update_instance_ranges($editor->Value('dav_name'));
|
||||
}
|
||||
|
||||
// Uncache anything to do with the collection
|
||||
$cache = getCacheInstance();
|
||||
$cache->delete( 'collection-'.$editor->Value('dav_name'), null );
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user