Merge remote-tracking branch 'upstream/develop' into more-q

This commit is contained in:
Michael 2021-10-03 19:49:11 +00:00
commit 1d86d79778
39 changed files with 664 additions and 712 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------ -- ------------------------------------------
-- Friendica 2021.12-dev (Siberian Iris) -- Friendica 2021.12-dev (Siberian Iris)
-- DB_UPDATE_VERSION 1435 -- DB_UPDATE_VERSION 1436
-- ------------------------------------------ -- ------------------------------------------
@ -565,7 +565,6 @@ CREATE TABLE IF NOT EXISTS `event` (
`location` text COMMENT 'event location', `location` text COMMENT 'event location',
`type` varchar(20) NOT NULL DEFAULT '' COMMENT 'event or birthday', `type` varchar(20) NOT NULL DEFAULT '' COMMENT 'event or birthday',
`nofinish` boolean NOT NULL DEFAULT '0' COMMENT 'if event does have no end this is 1', `nofinish` boolean NOT NULL DEFAULT '0' COMMENT 'if event does have no end this is 1',
`adjust` boolean NOT NULL DEFAULT '1' COMMENT 'adjust to timezone of the recipient (0 or 1)',
`ignore` boolean NOT NULL DEFAULT '0' COMMENT '0 or 1', `ignore` boolean NOT NULL DEFAULT '0' COMMENT '0 or 1',
`allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'', `allow_cid` mediumtext COMMENT 'Access Control - list of allowed contact.id \'<19><78>\'',
`allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups', `allow_gid` mediumtext COMMENT 'Access Control - list of allowed groups',
@ -1699,7 +1698,6 @@ CREATE VIEW `post-user-view` AS SELECT
`event`.`location` AS `event-location`, `event`.`location` AS `event-location`,
`event`.`type` AS `event-type`, `event`.`type` AS `event-type`,
`event`.`nofinish` AS `event-nofinish`, `event`.`nofinish` AS `event-nofinish`,
`event`.`adjust` AS `event-adjust`,
`event`.`ignore` AS `event-ignore`, `event`.`ignore` AS `event-ignore`,
`diaspora-interaction`.`interaction` AS `signed_text`, `diaspora-interaction`.`interaction` AS `signed_text`,
`parent-item-uri`.`guid` AS `parent-guid`, `parent-item-uri`.`guid` AS `parent-guid`,
@ -1860,7 +1858,6 @@ CREATE VIEW `post-thread-user-view` AS SELECT
`event`.`location` AS `event-location`, `event`.`location` AS `event-location`,
`event`.`type` AS `event-type`, `event`.`type` AS `event-type`,
`event`.`nofinish` AS `event-nofinish`, `event`.`nofinish` AS `event-nofinish`,
`event`.`adjust` AS `event-adjust`,
`event`.`ignore` AS `event-ignore`, `event`.`ignore` AS `event-ignore`,
`diaspora-interaction`.`interaction` AS `signed_text`, `diaspora-interaction`.`interaction` AS `signed_text`,
`parent-item-uri`.`guid` AS `parent-guid`, `parent-item-uri`.`guid` AS `parent-guid`,

View file

@ -439,12 +439,6 @@ Ex: Wed May 23 06:01:13 +0000 2007
<td>Optional. Location.</td> <td>Optional. Location.</td>
</tr> </tr>
<tr>
<td><code>adjust</code></td>
<td>Boolean</td>
<td>???</td>
</tr>
<tr> <tr>
<td><code>ignore</code></td> <td><code>ignore</code></td>
<td>Boolean</td> <td>Boolean</td>

View file

@ -23,7 +23,6 @@ Fields
| location | event location | text | YES | | NULL | | | location | event location | text | YES | | NULL | |
| type | event or birthday | varchar(20) | NO | | | | | type | event or birthday | varchar(20) | NO | | | |
| nofinish | if event does have no end this is 1 | boolean | NO | | 0 | | | nofinish | if event does have no end this is 1 | boolean | NO | | 0 | |
| adjust | adjust to timezone of the recipient (0 or 1) | boolean | NO | | 1 | |
| ignore | 0 or 1 | boolean | NO | | 0 | | | ignore | 0 or 1 | boolean | NO | | 0 | |
| allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | | | allow_cid | Access Control - list of allowed contact.id '<19><78>' | mediumtext | YES | | NULL | |
| allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | | | allow_gid | Access Control - list of allowed groups | mediumtext | YES | | NULL | |

View file

@ -36,11 +36,6 @@ The finishing date/time has to be after the beginning date/time of the event.
But you don't have to specify it. But you don't have to specify it.
If the event is open-ended or the finishing date/time does not matter, just select the box below the two first fields. If the event is open-ended or the finishing date/time does not matter, just select the box below the two first fields.
* **Adjust for viewer timezone**: If you check this box, the beginning and finishing times will automatically converted to the local time according to the timezone setting
This might prevent early birthday wishes, or the panic that you have forgotten the birthday from your buddy at the other side of the world.
And similar events.
* **Title**: a title for the event * **Title**: a title for the event
* **Description**: a longer description for the event * **Description**: a longer description for the event
* **Location**: the location the event will took place * **Location**: the location the event will took place

View file

@ -185,16 +185,11 @@ function cal_content(App $a)
$start = DateTimeFormat::utc($start); $start = DateTimeFormat::utc($start);
$finish = DateTimeFormat::utc($finish); $finish = DateTimeFormat::utc($finish);
$adjust_start = DateTimeFormat::local($start);
$adjust_finish = DateTimeFormat::local($finish);
// put the event parametes in an array so we can better transmit them // put the event parametes in an array so we can better transmit them
$event_params = [ $event_params = [
'event_id' => intval($_GET['id'] ?? 0), 'event_id' => intval($_GET['id'] ?? 0),
'start' => $start, 'start' => $start,
'finish' => $finish, 'finish' => $finish,
'adjust_start' => $adjust_start,
'adjust_finish' => $adjust_finish,
'ignore' => $ignored, 'ignore' => $ignored,
]; ];
@ -210,7 +205,7 @@ function cal_content(App $a)
if (DBA::isResult($r)) { if (DBA::isResult($r)) {
$r = Event::sortByDate($r); $r = Event::sortByDate($r);
foreach ($r as $rr) { foreach ($r as $rr) {
$j = $rr['adjust'] ? DateTimeFormat::local($rr['start'], 'j') : DateTimeFormat::utc($rr['start'], 'j'); $j = DateTimeFormat::local($rr['start'], 'j');
if (empty($links[$j])) { if (empty($links[$j])) {
$links[$j] = DI::baseUrl() . '/' . DI::args()->getCommand() . '#link-' . $j; $links[$j] = DI::baseUrl() . '/' . DI::args()->getCommand() . '#link-' . $j;
} }
@ -229,11 +224,7 @@ function cal_content(App $a)
if (!empty($_GET['id'])) { if (!empty($_GET['id'])) {
$tpl = Renderer::getMarkupTemplate("event.tpl"); $tpl = Renderer::getMarkupTemplate("event.tpl");
} else { } else {
// if (DI::config()->get('experimentals','new_calendar')==1){
$tpl = Renderer::getMarkupTemplate("events_js.tpl"); $tpl = Renderer::getMarkupTemplate("events_js.tpl");
// } else {
// $tpl = Renderer::getMarkupTemplate("events.tpl");
// }
} }
// Get rid of dashes in key names, Smarty3 can't handle them // Get rid of dashes in key names, Smarty3 can't handle them

View file

@ -49,12 +49,6 @@ function events_init(App $a)
return; return;
} }
// If it's a json request abort here because we don't
// need the widget data
if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] === 'json') {
return;
}
if (empty(DI::page()['aside'])) { if (empty(DI::page()['aside'])) {
DI::page()['aside'] = ''; DI::page()['aside'] = '';
} }
@ -80,7 +74,6 @@ function events_post(App $a)
$start_text = Strings::escapeHtml($_REQUEST['start_text'] ?? ''); $start_text = Strings::escapeHtml($_REQUEST['start_text'] ?? '');
$finish_text = Strings::escapeHtml($_REQUEST['finish_text'] ?? ''); $finish_text = Strings::escapeHtml($_REQUEST['finish_text'] ?? '');
$adjust = intval($_POST['adjust'] ?? 0);
$nofinish = intval($_POST['nofinish'] ?? 0); $nofinish = intval($_POST['nofinish'] ?? 0);
$share = intval($_POST['share'] ?? 0); $share = intval($_POST['share'] ?? 0);
@ -99,16 +92,9 @@ function events_post(App $a)
$finish = $finish_text; $finish = $finish_text;
} }
if ($adjust) { $start = DateTimeFormat::convert($start, 'UTC', $a->getTimeZone());
$start = DateTimeFormat::convert($start, 'UTC', date_default_timezone_get()); if (!$nofinish) {
if (!$nofinish) { $finish = DateTimeFormat::convert($finish, 'UTC', $a->getTimeZone());
$finish = DateTimeFormat::convert($finish, 'UTC', date_default_timezone_get());
}
} else {
$start = DateTimeFormat::utc($start);
if (!$nofinish) {
$finish = DateTimeFormat::utc($finish);
}
} }
// Don't allow the event to finish before it begins. // Don't allow the event to finish before it begins.
@ -127,7 +113,6 @@ function events_post(App $a)
'location' => $location, 'location' => $location,
'start' => $start_text, 'start' => $start_text,
'finish' => $finish_text, 'finish' => $finish_text,
'adjust' => $adjust,
'nofinish' => $nofinish, 'nofinish' => $nofinish,
]; ];
@ -196,7 +181,6 @@ function events_post(App $a)
$datarray['desc'] = $desc; $datarray['desc'] = $desc;
$datarray['location'] = $location; $datarray['location'] = $location;
$datarray['type'] = $type; $datarray['type'] = $type;
$datarray['adjust'] = $adjust;
$datarray['nofinish'] = $nofinish; $datarray['nofinish'] = $nofinish;
$datarray['uid'] = $uid; $datarray['uid'] = $uid;
$datarray['cid'] = $cid; $datarray['cid'] = $cid;
@ -331,28 +315,11 @@ function events_content(App $a)
$start = sprintf('%d-%d-%d %d:%d:%d', $y, $m, 1, 0, 0, 0); $start = sprintf('%d-%d-%d %d:%d:%d', $y, $m, 1, 0, 0, 0);
$finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59); $finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59);
if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] === 'json') {
if (!empty($_GET['start'])) {
$start = $_GET['start'];
}
if (!empty($_GET['end'])) {
$finish = $_GET['end'];
}
}
$start = DateTimeFormat::utc($start);
$finish = DateTimeFormat::utc($finish);
$adjust_start = DateTimeFormat::local($start);
$adjust_finish = DateTimeFormat::local($finish);
// put the event parametes in an array so we can better transmit them // put the event parametes in an array so we can better transmit them
$event_params = [ $event_params = [
'event_id' => intval($_GET['id'] ?? 0), 'event_id' => intval($_GET['id'] ?? 0),
'start' => $start, 'start' => $start,
'finish' => $finish, 'finish' => $finish,
'adjust_start' => $adjust_start,
'adjust_finish' => $adjust_finish,
'ignore' => $ignored, 'ignore' => $ignored,
]; ];
@ -368,7 +335,7 @@ function events_content(App $a)
if (DBA::isResult($r)) { if (DBA::isResult($r)) {
$r = Event::sortByDate($r); $r = Event::sortByDate($r);
foreach ($r as $rr) { foreach ($r as $rr) {
$j = $rr['adjust'] ? DateTimeFormat::local($rr['start'], 'j') : DateTimeFormat::utc($rr['start'], 'j'); $j = DateTimeFormat::local($rr['start'], 'j');
if (empty($links[$j])) { if (empty($links[$j])) {
$links[$j] = DI::baseUrl() . '/' . DI::args()->getCommand() . '#link-' . $j; $links[$j] = DI::baseUrl() . '/' . DI::args()->getCommand() . '#link-' . $j;
} }
@ -383,12 +350,6 @@ function events_content(App $a)
$events = Event::prepareListForTemplate($r); $events = Event::prepareListForTemplate($r);
} }
if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] === 'json') {
header('Content-Type: application/json');
echo json_encode($events);
exit();
}
if (!empty($_GET['id'])) { if (!empty($_GET['id'])) {
$tpl = Renderer::getMarkupTemplate("event.tpl"); $tpl = Renderer::getMarkupTemplate("event.tpl");
} else { } else {
@ -457,7 +418,6 @@ function events_content(App $a)
// In case of an error the browser is redirected back here, with these parameters filled in with the previous values // In case of an error the browser is redirected back here, with these parameters filled in with the previous values
if (!empty($_REQUEST['nofinish'])) {$orig_event['nofinish'] = $_REQUEST['nofinish'];} if (!empty($_REQUEST['nofinish'])) {$orig_event['nofinish'] = $_REQUEST['nofinish'];}
if (!empty($_REQUEST['adjust'])) {$orig_event['adjust'] = $_REQUEST['adjust'];}
if (!empty($_REQUEST['summary'])) {$orig_event['summary'] = $_REQUEST['summary'];} if (!empty($_REQUEST['summary'])) {$orig_event['summary'] = $_REQUEST['summary'];}
if (!empty($_REQUEST['desc'])) {$orig_event['desc'] = $_REQUEST['desc'];} if (!empty($_REQUEST['desc'])) {$orig_event['desc'] = $_REQUEST['desc'];}
if (!empty($_REQUEST['location'])) {$orig_event['location'] = $_REQUEST['location'];} if (!empty($_REQUEST['location'])) {$orig_event['location'] = $_REQUEST['location'];}
@ -465,7 +425,6 @@ function events_content(App $a)
if (!empty($_REQUEST['finish'])) {$orig_event['finish'] = $_REQUEST['finish'];} if (!empty($_REQUEST['finish'])) {$orig_event['finish'] = $_REQUEST['finish'];}
$n_checked = (!empty($orig_event['nofinish']) ? ' checked="checked" ' : ''); $n_checked = (!empty($orig_event['nofinish']) ? ' checked="checked" ' : '');
$a_checked = (!empty($orig_event['adjust']) ? ' checked="checked" ' : '');
$t_orig = $orig_event['summary'] ?? ''; $t_orig = $orig_event['summary'] ?? '';
$d_orig = $orig_event['desc'] ?? ''; $d_orig = $orig_event['desc'] ?? '';
@ -481,24 +440,19 @@ function events_content(App $a)
$sdt = $orig_event['start'] ?? 'now'; $sdt = $orig_event['start'] ?? 'now';
$fdt = $orig_event['finish'] ?? 'now'; $fdt = $orig_event['finish'] ?? 'now';
$tz = date_default_timezone_get(); $syear = DateTimeFormat::local($sdt, 'Y');
if (isset($orig_event['adjust'])) { $smonth = DateTimeFormat::local($sdt, 'm');
$tz = ($orig_event['adjust'] ? date_default_timezone_get() : 'UTC'); $sday = DateTimeFormat::local($sdt, 'd');
}
$syear = DateTimeFormat::convert($sdt, $tz, 'UTC', 'Y'); $shour = !empty($orig_event) ? DateTimeFormat::local($sdt, 'H') : '00';
$smonth = DateTimeFormat::convert($sdt, $tz, 'UTC', 'm'); $sminute = !empty($orig_event) ? DateTimeFormat::local($sdt, 'i') : '00';
$sday = DateTimeFormat::convert($sdt, $tz, 'UTC', 'd');
$shour = !empty($orig_event) ? DateTimeFormat::convert($sdt, $tz, 'UTC', 'H') : '00'; $fyear = DateTimeFormat::local($fdt, 'Y');
$sminute = !empty($orig_event) ? DateTimeFormat::convert($sdt, $tz, 'UTC', 'i') : '00'; $fmonth = DateTimeFormat::local($fdt, 'm');
$fday = DateTimeFormat::local($fdt, 'd');
$fyear = DateTimeFormat::convert($fdt, $tz, 'UTC', 'Y'); $fhour = !empty($orig_event) ? DateTimeFormat::local($fdt, 'H') : '00';
$fmonth = DateTimeFormat::convert($fdt, $tz, 'UTC', 'm'); $fminute = !empty($orig_event) ? DateTimeFormat::local($fdt, 'i') : '00';
$fday = DateTimeFormat::convert($fdt, $tz, 'UTC', 'd');
$fhour = !empty($orig_event) ? DateTimeFormat::convert($fdt, $tz, 'UTC', 'H') : '00';
$fminute = !empty($orig_event) ? DateTimeFormat::convert($fdt, $tz, 'UTC', 'i') : '00';
if (!$cid && in_array($mode, ['new', 'copy'])) { if (!$cid && in_array($mode, ['new', 'copy'])) {
$acl = ACL::getFullSelectorHTML(DI::page(), $a->getLoggedInUserId(), false, ACL::getDefaultUserPermissions($orig_event)); $acl = ACL::getFullSelectorHTML(DI::page(), $a->getLoggedInUserId(), false, ACL::getDefaultUserPermissions($orig_event));
@ -549,8 +503,6 @@ function events_content(App $a)
true, true,
'start_text' 'start_text'
), ),
'$a_text' => DI::l10n()->t('Adjust for viewer timezone'),
'$a_checked' => $a_checked,
'$d_text' => DI::l10n()->t('Description:'), '$d_text' => DI::l10n()->t('Description:'),
'$d_orig' => $d_orig, '$d_orig' => $d_orig,
'$l_text' => DI::l10n()->t('Location:'), '$l_text' => DI::l10n()->t('Location:'),
@ -562,7 +514,6 @@ function events_content(App $a)
'$share' => ['share', DI::l10n()->t('Share this event'), $share_checked, '', $share_disabled], '$share' => ['share', DI::l10n()->t('Share this event'), $share_checked, '', $share_disabled],
'$sh_checked' => $share_checked, '$sh_checked' => $share_checked,
'$nofinish' => ['nofinish', DI::l10n()->t('Finish date/time is not known or not relevant'), $n_checked], '$nofinish' => ['nofinish', DI::l10n()->t('Finish date/time is not known or not relevant'), $n_checked],
'$adjust' => ['adjust', DI::l10n()->t('Adjust for viewer timezone'), $a_checked],
'$preview' => DI::l10n()->t('Preview'), '$preview' => DI::l10n()->t('Preview'),
'$acl' => $acl, '$acl' => $acl,
'$submit' => DI::l10n()->t('Submit'), '$submit' => DI::l10n()->t('Submit'),

View file

@ -686,7 +686,7 @@ function item_post(App $a) {
Hook::callAll('post_local',$datarray); Hook::callAll('post_local',$datarray);
if (!empty($_REQUEST['scheduled_at'])) { if (!empty($_REQUEST['scheduled_at'])) {
$scheduled_at = DateTimeFormat::convert($_REQUEST['scheduled_at'], 'UTC', $a->getTimezone()); $scheduled_at = DateTimeFormat::convert($_REQUEST['scheduled_at'], 'UTC', $a->getTimeZone());
if ($scheduled_at > DateTimeFormat::utcNow()) { if ($scheduled_at > DateTimeFormat::utcNow()) {
unset($datarray['created']); unset($datarray['created']);
unset($datarray['edited']); unset($datarray['edited']);

View file

@ -219,7 +219,7 @@ function ping_init(App $a)
$all_events = count($ev); $all_events = count($ev);
if ($all_events) { if ($all_events) {
$str_now = DateTimeFormat::timezoneNow($a->getTimeZone(), 'Y-m-d'); $str_now = DateTimeFormat::localNow('Y-m-d');
foreach ($ev as $x) { foreach ($ev as $x) {
$bd = false; $bd = false;
if ($x['type'] === 'birthday') { if ($x['type'] === 'birthday') {
@ -228,7 +228,7 @@ function ping_init(App $a)
} else { } else {
$events ++; $events ++;
} }
if (DateTimeFormat::convert($x['start'], ((intval($x['adjust'])) ? $a->getTimeZone() : 'UTC'), 'UTC', 'Y-m-d') === $str_now) { if (DateTimeFormat::local($x['start'], 'Y-m-d') === $str_now) {
$all_events_today ++; $all_events_today ++;
if ($bd) { if ($bd) {
$birthdays_today ++; $birthdays_today ++;

View file

@ -333,7 +333,7 @@ function settings_post(App $a)
} }
if (($timezone != $user['timezone']) && strlen($timezone)) { if (($timezone != $user['timezone']) && strlen($timezone)) {
date_default_timezone_set($timezone); $a->setTimeZone($timezone);
} }
$aclFormatter = DI::aclFormatter(); $aclFormatter = DI::aclFormatter();
@ -601,7 +601,7 @@ function settings_content(App $a)
$expire_network_only = DI::pConfig()->get(local_user(), 'expire', 'network_only', false); $expire_network_only = DI::pConfig()->get(local_user(), 'expire', 'network_only', false);
if (!strlen($user['timezone'])) { if (!strlen($user['timezone'])) {
$timezone = date_default_timezone_get(); $timezone = $a->getTimeZone();
} }
// Set the account type to "Community" when the page is a community page but the account type doesn't fit // Set the account type to "Community" when the page is a community page but the account type doesn't fit

View file

@ -40,6 +40,7 @@ use Friendica\Model\Profile;
use Friendica\Module\Special\HTTPException as ModuleHTTPException; use Friendica\Module\Special\HTTPException as ModuleHTTPException;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
use Friendica\Util\ConfigFileLoader; use Friendica\Util\ConfigFileLoader;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\HTTPSignature; use Friendica\Util\HTTPSignature;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Friendica\Util\Strings; use Friendica\Util\Strings;
@ -217,12 +218,13 @@ class App
/** /**
* Set the timezone * Set the timezone
* *
* @param int $timezone * @param string $timezone A valid time zone identifier, see https://www.php.net/manual/en/timezones.php
* @return void * @return void
*/ */
public function setTimeZone(string $timezone) public function setTimeZone(string $timezone)
{ {
$this->timezone = $timezone; $this->timezone = (new \DateTimeZone($timezone))->getName();
DateTimeFormat::setLocalTimeZone($this->timezone);
} }
/** /**
@ -338,6 +340,9 @@ class App
{ {
set_time_limit(0); set_time_limit(0);
// Ensure that all "strtotime" operations do run timezone independent
date_default_timezone_set('UTC');
// This has to be quite large to deal with embedded private photos // This has to be quite large to deal with embedded private photos
ini_set('pcre.backtrack_limit', 500000); ini_set('pcre.backtrack_limit', 500000);
@ -372,15 +377,13 @@ class App
private function loadDefaultTimezone() private function loadDefaultTimezone()
{ {
if ($this->config->get('system', 'default_timezone')) { if ($this->config->get('system', 'default_timezone')) {
$this->timezone = $this->config->get('system', 'default_timezone'); $timezone = $this->config->get('system', 'default_timezone', 'UTC');
} else { } else {
global $default_timezone; global $default_timezone;
$this->timezone = !empty($default_timezone) ? $default_timezone : 'UTC'; $timezone = $default_timezone ?? '' ?: 'UTC';
} }
if ($this->timezone) { $this->setTimeZone($timezone);
date_default_timezone_set($this->timezone);
}
} }
/** /**

View file

@ -1857,7 +1857,6 @@ class BBCode
$text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism", $sub, $text); $text = preg_replace("/\[event\-start\](.*?)\[\/event\-start\]/ism", $sub, $text);
$text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism", '', $text); $text = preg_replace("/\[event\-finish\](.*?)\[\/event\-finish\]/ism", '', $text);
$text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism", '', $text); $text = preg_replace("/\[event\-location\](.*?)\[\/event\-location\]/ism", '', $text);
$text = preg_replace("/\[event\-adjust\](.*?)\[\/event\-adjust\]/ism", '', $text);
$text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism", '', $text); $text = preg_replace("/\[event\-id\](.*?)\[\/event\-id\]/ism", '', $text);
} }

View file

@ -61,9 +61,6 @@ class Worker
*/ */
public static function processQueue($run_cron = true) public static function processQueue($run_cron = true)
{ {
// Ensure that all "strtotime" operations do run timezone independent
date_default_timezone_set('UTC');
self::$up_start = microtime(true); self::$up_start = microtime(true);
// At first check the maximum load. We shouldn't continue with a high load // At first check the maximum load. We shouldn't continue with a high load

View file

@ -51,16 +51,10 @@ class Event
$bd_format = DI::l10n()->t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8 AM. $bd_format = DI::l10n()->t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8 AM.
$event_start = DI::l10n()->getDay( $event_start = DI::l10n()->getDay(DateTimeFormat::local($event['start'], $bd_format));
!empty($event['adjust']) ?
DateTimeFormat::local($event['start'], $bd_format) : DateTimeFormat::utc($event['start'], $bd_format)
);
if (!empty($event['finish'])) { if (!empty($event['finish'])) {
$event_end = DI::l10n()->getDay( $event_end = DI::l10n()->getDay(DateTimeFormat::local($event['finish'], $bd_format));
!empty($event['adjust']) ?
DateTimeFormat::local($event['finish'], $bd_format) : DateTimeFormat::utc($event['finish'], $bd_format)
);
} else { } else {
$event_end = ''; $event_end = '';
} }
@ -94,13 +88,13 @@ class Event
$o .= '<div class="summary event-summary">' . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['summary']), $simple) . '</div>' . "\r\n"; $o .= '<div class="summary event-summary">' . BBCode::convertForUriId($uriid, Strings::escapeHtml($event['summary']), $simple) . '</div>' . "\r\n";
$o .= '<div class="event-start"><span class="event-label">' . DI::l10n()->t('Starts:') . '</span>&nbsp;<span class="dtstart" title="' $o .= '<div class="event-start"><span class="event-label">' . DI::l10n()->t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
. DateTimeFormat::utc($event['start'], (!empty($event['adjust']) ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s')) . DateTimeFormat::local($event['start'], DateTimeFormat::ATOM)
. '" >' . $event_start . '" >' . $event_start
. '</span></div>' . "\r\n"; . '</span></div>' . "\r\n";
if (!$event['nofinish']) { if (!$event['nofinish']) {
$o .= '<div class="event-end" ><span class="event-label">' . DI::l10n()->t('Finishes:') . '</span>&nbsp;<span class="dtend" title="' $o .= '<div class="event-end" ><span class="event-label">' . DI::l10n()->t('Finishes:') . '</span>&nbsp;<span class="dtend" title="'
. DateTimeFormat::utc($event['finish'], (!empty($event['adjust']) ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s')) . DateTimeFormat::local($event['finish'], DateTimeFormat::ATOM)
. '" >' . $event_end . '" >' . $event_end
. '</span></div>' . "\r\n"; . '</span></div>' . "\r\n";
} }
@ -157,10 +151,6 @@ class Event
$o .= '[event-location]' . $event['location'] . '[/event-location]'; $o .= '[event-location]' . $event['location'] . '[/event-location]';
} }
if ($event['adjust']) {
$o .= '[event-adjust]' . $event['adjust'] . '[/event-adjust]';
}
return $o; return $o;
} }
@ -200,11 +190,6 @@ class Event
$ev['location'] = $match[1]; $ev['location'] = $match[1];
} }
$match = [];
if (preg_match("/\[event\-adjust\](.*?)\[\/event\-adjust\]/is", $text, $match)) {
$ev['adjust'] = $match[1];
}
$ev['nofinish'] = !empty($ev['start']) && empty($ev['finish']) ? 1 : 0; $ev['nofinish'] = !empty($ev['start']) && empty($ev['finish']) ? 1 : 0;
return $ev; return $ev;
@ -218,8 +203,8 @@ class Event
private static function compareDatesCallback($event_a, $event_b) private static function compareDatesCallback($event_a, $event_b)
{ {
$date_a = (($event_a['adjust']) ? DateTimeFormat::local($event_a['start']) : $event_a['start']); $date_a = DateTimeFormat::local($event_a['start']);
$date_b = (($event_b['adjust']) ? DateTimeFormat::local($event_b['start']) : $event_b['start']); $date_b = DateTimeFormat::local($event_b['start']);
if ($date_a === $date_b) { if ($date_a === $date_b) {
return strcasecmp($event_a['desc'], $event_b['desc']); return strcasecmp($event_a['desc'], $event_b['desc']);
@ -274,7 +259,6 @@ class Event
$event['allow_gid'] = $arr['allow_gid'] ?? ''; $event['allow_gid'] = $arr['allow_gid'] ?? '';
$event['deny_cid'] = $arr['deny_cid'] ?? ''; $event['deny_cid'] = $arr['deny_cid'] ?? '';
$event['deny_gid'] = $arr['deny_gid'] ?? ''; $event['deny_gid'] = $arr['deny_gid'] ?? '';
$event['adjust'] = intval($arr['adjust'] ?? 0);
$event['nofinish'] = intval($arr['nofinish'] ?? (!empty($event['start']) && empty($event['finish']))); $event['nofinish'] = intval($arr['nofinish'] ?? (!empty($event['start']) && empty($event['finish'])));
$event['created'] = DateTimeFormat::utc(($arr['created'] ?? '') ?: 'now'); $event['created'] = DateTimeFormat::utc(($arr['created'] ?? '') ?: 'now');
@ -305,7 +289,6 @@ class Event
'desc' => $event['desc'], 'desc' => $event['desc'],
'location' => $event['location'], 'location' => $event['location'],
'type' => $event['type'], 'type' => $event['type'],
'adjust' => $event['adjust'],
'nofinish' => $event['nofinish'], 'nofinish' => $event['nofinish'],
]; ];
@ -547,8 +530,6 @@ class Event
* int 'ignore' => * int 'ignore' =>
* string 'start' => Start time of the timeframe. * string 'start' => Start time of the timeframe.
* string 'finish' => Finish time of the timeframe. * string 'finish' => Finish time of the timeframe.
* string 'adjust_start' =>
* string 'adjust_finish' =>
* *
* @param string $sql_extra Additional sql conditions (e.g. permission request). * @param string $sql_extra Additional sql conditions (e.g. permission request).
* *
@ -568,11 +549,11 @@ class Event
$events = DBA::toArray(DBA::p("SELECT `event`.*, `post-user`.`id` AS `itemid` FROM `event` $events = DBA::toArray(DBA::p("SELECT `event`.*, `post-user`.`id` AS `itemid` FROM `event`
LEFT JOIN `post-user` ON `post-user`.`event-id` = `event`.`id` AND `post-user`.`uid` = `event`.`uid` LEFT JOIN `post-user` ON `post-user`.`event-id` = `event`.`id` AND `post-user`.`uid` = `event`.`uid`
WHERE `event`.`uid` = ? AND `event`.`ignore` = ? WHERE `event`.`uid` = ? AND `event`.`ignore` = ?
AND ((NOT `adjust` AND (`finish` >= ? OR (`nofinish` AND `start` >= ?)) AND `start` <= ?) AND (`finish` >= ? OR (`nofinish` AND `start` >= ?)) AND `start` <= ?
OR (`adjust` AND (`finish` >= ? OR (`nofinish` AND `start` >= ?)) AND `start` <= ?))" . $sql_extra, " . $sql_extra,
$owner_uid, $event_params["ignore"], $owner_uid, $event_params['ignore'],
$event_params["start"], $event_params["start"], $event_params["finish"], $event_params['start'], $event_params['start'], $event_params['finish']
$event_params["adjust_start"], $event_params["adjust_start"], $event_params["adjust_finish"])); ));
if (DBA::isResult($events)) { if (DBA::isResult($events)) {
$return = self::removeDuplicates($events); $return = self::removeDuplicates($events);
@ -604,15 +585,15 @@ class Event
$event = array_merge($event, $item); $event = array_merge($event, $item);
$start = $event['adjust'] ? DateTimeFormat::local($event['start'], 'c') : DateTimeFormat::utc($event['start'], 'c'); $start = DateTimeFormat::local($event['start'], 'c');
$j = $event['adjust'] ? DateTimeFormat::local($event['start'], 'j') : DateTimeFormat::utc($event['start'], 'j'); $j = DateTimeFormat::local($event['start'], 'j');
$day = $event['adjust'] ? DateTimeFormat::local($event['start'], $fmt) : DateTimeFormat::utc($event['start'], $fmt); $day = DateTimeFormat::local($event['start'], $fmt);
$day = DI::l10n()->getDay($day); $day = DI::l10n()->getDay($day);
if ($event['nofinish']) { if ($event['nofinish']) {
$end = null; $end = null;
} else { } else {
$end = $event['adjust'] ? DateTimeFormat::local($event['finish'], 'c') : DateTimeFormat::utc($event['finish'], 'c'); $end = DateTimeFormat::local($event['finish'], 'c');
} }
$is_first = ($day !== $last_date); $is_first = ($day !== $last_date);
@ -720,23 +701,14 @@ class Event
// but test your solution against http://icalvalid.cloudapp.net/ // but test your solution against http://icalvalid.cloudapp.net/
// also long lines SHOULD be split at 75 characters length // also long lines SHOULD be split at 75 characters length
foreach ($events as $event) { foreach ($events as $event) {
if ($event['adjust'] == 1) {
$UTC = 'Z';
} else {
$UTC = '';
}
$o .= 'BEGIN:VEVENT' . PHP_EOL; $o .= 'BEGIN:VEVENT' . PHP_EOL;
if ($event['start']) { if ($event['start']) {
$tmp = strtotime($event['start']); $o .= 'DTSTART:' . DateTimeFormat::utc($event['start'], 'Ymd\THis\Z') . PHP_EOL;
$dtformat = "%Y%m%dT%H%M%S" . $UTC;
$o .= 'DTSTART:' . strftime($dtformat, $tmp) . PHP_EOL;
} }
if (!$event['nofinish']) { if (!$event['nofinish']) {
$tmp = strtotime($event['finish']); $o .= 'DTEND:' . DateTimeFormat::utc($event['finish'], 'Ymd\THis\Z') . PHP_EOL;
$dtformat = "%Y%m%dT%H%M%S" . $UTC;
$o .= 'DTEND:' . strftime($dtformat, $tmp) . PHP_EOL;
} }
if ($event['summary']) { if ($event['summary']) {
@ -793,7 +765,7 @@ class Event
return $return; return $return;
} }
$fields = ['start', 'finish', 'adjust', 'summary', 'desc', 'location', 'nofinish']; $fields = ['start', 'finish', 'summary', 'desc', 'location', 'nofinish'];
$conditions = ['uid' => $uid, 'cid' => 0]; $conditions = ['uid' => $uid, 'cid' => 0];
@ -883,48 +855,22 @@ class Event
$tformat = DI::l10n()->t('g:i A'); // 8:01 AM. $tformat = DI::l10n()->t('g:i A'); // 8:01 AM.
// Convert the time to different formats. // Convert the time to different formats.
$dtstart_dt = DI::l10n()->getDay( $dtstart_dt = DI::l10n()->getDay(DateTimeFormat::local($item['event-start'], $dformat));
$item['event-adjust'] ? $dtstart_title = DateTimeFormat::utc($item['event-start'], DateTimeFormat::ATOM);
DateTimeFormat::local($item['event-start'], $dformat)
: DateTimeFormat::utc($item['event-start'], $dformat)
);
$dtstart_title = DateTimeFormat::utc($item['event-start'], $item['event-adjust'] ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s');
// Format: Jan till Dec. // Format: Jan till Dec.
$month_short = DI::l10n()->getDayShort( $month_short = DI::l10n()->getDayShort(DateTimeFormat::local($item['event-start'], 'M'));
$item['event-adjust'] ?
DateTimeFormat::local($item['event-start'], 'M')
: DateTimeFormat::utc($item['event-start'], 'M')
);
// Format: 1 till 31. // Format: 1 till 31.
$date_short = $item['event-adjust'] ? $date_short = DateTimeFormat::local($item['event-start'], 'j');
DateTimeFormat::local($item['event-start'], 'j') $start_time = DateTimeFormat::local($item['event-start'], $tformat);
: DateTimeFormat::utc($item['event-start'], 'j'); $start_short = DI::l10n()->getDayShort(DateTimeFormat::local($item['event-start'], $dformat_short));
$start_time = $item['event-adjust'] ?
DateTimeFormat::local($item['event-start'], $tformat)
: DateTimeFormat::utc($item['event-start'], $tformat);
$start_short = DI::l10n()->getDayShort(
$item['event-adjust'] ?
DateTimeFormat::local($item['event-start'], $dformat_short)
: DateTimeFormat::utc($item['event-start'], $dformat_short)
);
// If the option 'nofinisch' isn't set, we need to format the finish date/time. // If the option 'nofinisch' isn't set, we need to format the finish date/time.
if (!$item['event-nofinish']) { if (!$item['event-nofinish']) {
$finish = true; $finish = true;
$dtend_dt = DI::l10n()->getDay( $dtend_dt = DI::l10n()->getDay(DateTimeFormat::local($item['event-finish'], $dformat));
$item['event-adjust'] ? $dtend_title = DateTimeFormat::utc($item['event-finish'], DateTimeFormat::ATOM);
DateTimeFormat::local($item['event-finish'], $dformat) $end_short = DI::l10n()->getDayShort(DateTimeFormat::utc($item['event-finish'], $dformat_short));
: DateTimeFormat::utc($item['event-finish'], $dformat) $end_time = DateTimeFormat::local($item['event-finish'], $tformat);
);
$dtend_title = DateTimeFormat::utc($item['event-finish'], $item['event-adjust'] ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s');
$end_short = DI::l10n()->getDayShort(
$item['event-adjust'] ?
DateTimeFormat::local($item['event-finish'], $dformat_short)
: DateTimeFormat::utc($item['event-finish'], $dformat_short)
);
$end_time = $item['event-adjust'] ?
DateTimeFormat::local($item['event-finish'], $tformat)
: DateTimeFormat::utc($item['event-finish'], $tformat);
// Check if start and finish time is at the same day. // Check if start and finish time is at the same day.
if (substr($dtstart_title, 0, 10) === substr($dtend_title, 0, 10)) { if (substr($dtstart_title, 0, 10) === substr($dtend_title, 0, 10)) {
$same_date = true; $same_date = true;
@ -1063,7 +1009,6 @@ class Event
'summary' => DI::l10n()->t('%s\'s birthday', $contact['name']), 'summary' => DI::l10n()->t('%s\'s birthday', $contact['name']),
'desc' => DI::l10n()->t('Happy Birthday %s', ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'), 'desc' => DI::l10n()->t('Happy Birthday %s', ' [url=' . $contact['url'] . ']' . $contact['name'] . '[/url]'),
'type' => 'birthday', 'type' => 'birthday',
'adjust' => 0
]; ];
self::store($values); self::store($values);

View file

@ -88,7 +88,7 @@ class Item
'writable', 'self', 'cid', 'alias', 'writable', 'self', 'cid', 'alias',
'event-created', 'event-edited', 'event-start', 'event-finish', 'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type', 'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-adjust', 'event-ignore', 'event-id', 'event-nofinish', 'event-ignore', 'event-id',
'delivery_queue_count', 'delivery_queue_done', 'delivery_queue_failed' 'delivery_queue_count', 'delivery_queue_done', 'delivery_queue_failed'
]; ];
@ -103,7 +103,7 @@ class Item
'thr-parent-id', 'parent-uri-id', 'postopts', 'pubmail', 'thr-parent-id', 'parent-uri-id', 'postopts', 'pubmail',
'event-created', 'event-edited', 'event-start', 'event-finish', 'event-created', 'event-edited', 'event-start', 'event-finish',
'event-summary', 'event-desc', 'event-location', 'event-type', 'event-summary', 'event-desc', 'event-location', 'event-type',
'event-nofinish', 'event-adjust', 'event-ignore', 'event-id']; 'event-nofinish', 'event-ignore', 'event-id'];
// All fields in the item table // All fields in the item table
const ITEM_FIELDLIST = ['id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent', const ITEM_FIELDLIST = ['id', 'uid', 'parent', 'uri', 'parent-uri', 'thr-parent',

View file

@ -555,7 +555,7 @@ class Profile
$rr['link'] = Contact::magicLinkById($rr['cid']); $rr['link'] = Contact::magicLinkById($rr['cid']);
$rr['title'] = $rr['name']; $rr['title'] = $rr['name'];
$rr['date'] = DI::l10n()->getDay(DateTimeFormat::convert($rr['start'], $a->getTimeZone(), 'UTC', $rr['adjust'] ? $bd_format : $bd_short)) . (($today) ? ' ' . DI::l10n()->t('[today]') : ''); $rr['date'] = DI::l10n()->getDay(DateTimeFormat::local($rr['start'], $bd_short)) . (($today) ? ' ' . DI::l10n()->t('[today]') : '');
$rr['startime'] = null; $rr['startime'] = null;
$rr['today'] = $today; $rr['today'] = $today;
} }
@ -614,8 +614,8 @@ class Profile
$total++; $total++;
} }
$strt = DateTimeFormat::convert($rr['start'], $rr['adjust'] ? $a->getTimeZone() : 'UTC', 'UTC', 'Y-m-d'); $strt = DateTimeFormat::local($rr['start'], 'Y-m-d');
if ($strt === DateTimeFormat::timezoneNow($a->getTimeZone(), 'Y-m-d')) { if ($strt === DateTimeFormat::localNow('Y-m-d')) {
$istoday = true; $istoday = true;
} }
@ -630,17 +630,17 @@ class Profile
$description = DI::l10n()->t('[No description]'); $description = DI::l10n()->t('[No description]');
} }
$strt = DateTimeFormat::convert($rr['start'], $rr['adjust'] ? $a->getTimeZone() : 'UTC'); $strt = DateTimeFormat::local($rr['start']);
if (substr($strt, 0, 10) < DateTimeFormat::timezoneNow($a->getTimeZone(), 'Y-m-d')) { if (substr($strt, 0, 10) < DateTimeFormat::localNow('Y-m-d')) {
continue; continue;
} }
$today = ((substr($strt, 0, 10) === DateTimeFormat::timezoneNow($a->getTimeZone(), 'Y-m-d')) ? true : false); $today = substr($strt, 0, 10) === DateTimeFormat::localNow('Y-m-d');
$rr['title'] = $title; $rr['title'] = $title;
$rr['description'] = $description; $rr['description'] = $description;
$rr['date'] = DI::l10n()->getDay(DateTimeFormat::convert($rr['start'], $rr['adjust'] ? $a->getTimeZone() : 'UTC', 'UTC', $bd_format)) . (($today) ? ' ' . DI::l10n()->t('[today]') : ''); $rr['date'] = DI::l10n()->getDay(DateTimeFormat::local($rr['start'], $bd_format)) . (($today) ? ' ' . DI::l10n()->t('[today]') : '');
$rr['startime'] = $strt; $rr['startime'] = $strt;
$rr['today'] = $today; $rr['today'] = $today;

View file

@ -61,7 +61,7 @@ class Index extends BaseApi
'type' => $event['type'], 'type' => $event['type'],
'nofinish' => $event['nofinish'], 'nofinish' => $event['nofinish'],
'place' => $event['location'], 'place' => $event['location'],
'adjust' => $event['adjust'], 'adjust' => 1,
'ignore' => $event['ignore'], 'ignore' => $event['ignore'],
'allow_cid' => $event['allow_cid'], 'allow_cid' => $event['allow_cid'],
'allow_gid' => $event['allow_gid'], 'allow_gid' => $event['allow_gid'],

View file

@ -372,10 +372,10 @@ class Network extends BaseModule
} }
if (self::$dateFrom) { if (self::$dateFrom) {
$conditionStrings = DBA::mergeConditions($conditionStrings, ["`received` <= ? ", DateTimeFormat::convert(self::$dateFrom, 'UTC', date_default_timezone_get())]); $conditionStrings = DBA::mergeConditions($conditionStrings, ["`received` <= ? ", DateTimeFormat::convert(self::$dateFrom, 'UTC', DI::app()->getTimeZone())]);
} }
if (self::$dateTo) { if (self::$dateTo) {
$conditionStrings = DBA::mergeConditions($conditionStrings, ["`received` >= ? ", DateTimeFormat::convert(self::$dateTo, 'UTC', date_default_timezone_get())]); $conditionStrings = DBA::mergeConditions($conditionStrings, ["`received` >= ? ", DateTimeFormat::convert(self::$dateTo, 'UTC', DI::app()->getTimeZone())]);
} }
if (self::$groupId) { if (self::$groupId) {

104
src/Module/Events/Json.php Normal file
View file

@ -0,0 +1,104 @@
<?php
namespace Friendica\Module\Events;
use Friendica\Database\DBA;
use Friendica\DI;
use Friendica\Model\Event;
use Friendica\Model\Item;
use Friendica\Model\Post;
use Friendica\Network\HTTPException;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Temporal;
class Json extends \Friendica\BaseModule
{
public static function rawContent(array $parameters = [])
{
if (!local_user()) {
throw new HTTPException\UnauthorizedException();
}
$y = intval(DateTimeFormat::localNow('Y'));
$m = intval(DateTimeFormat::localNow('m'));
// Put some limit on dates. The PHP date functions don't seem to do so well before 1900.
if ($y < 1901) {
$y = 1900;
}
$dim = Temporal::getDaysInMonth($y, $m);
$start = sprintf('%d-%d-%d %d:%d:%d', $y, $m, 1, 0, 0, 0);
$finish = sprintf('%d-%d-%d %d:%d:%d', $y, $m, $dim, 23, 59, 59);
if (!empty($_GET['start'])) {
$start = $_GET['start'];
}
if (!empty($_GET['end'])) {
$finish = $_GET['end'];
}
// put the event parametes in an array so we can better transmit them
$event_params = [
'event_id' => intval($_GET['id'] ?? 0),
'start' => $start,
'finish' => $finish,
'ignore' => 0,
];
// get events by id or by date
if ($event_params['event_id']) {
$r = Event::getListById(local_user(), $event_params['event_id']);
} else {
$r = Event::getListByDate(local_user(), $event_params);
}
$links = [];
if (DBA::isResult($r)) {
$r = Event::sortByDate($r);
foreach ($r as $rr) {
$j = DateTimeFormat::utc($rr['start'], 'j');
if (empty($links[$j])) {
$links[$j] = DI::baseUrl() . '/' . DI::args()->getCommand() . '#link-' . $j;
}
}
}
$events = [];
// transform the event in a usable array
if (DBA::isResult($r)) {
$events = Event::sortByDate($r);
$events = self::map($events);
}
header('Content-Type: application/json');
echo json_encode($events);
exit();
}
private static function map(array $events): array
{
return array_map(function ($event) {
$item = Post::selectFirst(['plink', 'author-name', 'author-avatar', 'author-link', 'private', 'uri-id'], ['id' => $event['itemid']]);
if (!DBA::isResult($item)) {
// Using default values when no item had been found
$item = ['plink' => '', 'author-name' => '', 'author-avatar' => '', 'author-link' => '', 'private' => Item::PUBLIC, 'uri-id' => ($event['uri-id'] ?? 0)];
}
return [
'id' => $event['id'],
'title' => $event['summary'],
'start' => DateTimeFormat::local($event['start']),
'end' => DateTimeFormat::local($event['finish']),
'nofinish' => $event['nofinish'],
'desc' => $event['desc'],
'location' => $event['location'],
'item' => $item,
];
}, $events);
}
}

View file

@ -151,10 +151,10 @@ class Status extends BaseProfile
} }
if (!empty($datequery)) { if (!empty($datequery)) {
$condition = DBA::mergeConditions($condition, ["`received` <= ?", DateTimeFormat::convert($datequery, 'UTC', date_default_timezone_get())]); $condition = DBA::mergeConditions($condition, ["`received` <= ?", DateTimeFormat::convert($datequery, 'UTC', $a->getTimeZone())]);
} }
if (!empty($datequery2)) { if (!empty($datequery2)) {
$condition = DBA::mergeConditions($condition, ["`received` >= ?", DateTimeFormat::convert($datequery2, 'UTC', date_default_timezone_get())]); $condition = DBA::mergeConditions($condition, ["`received` >= ?", DateTimeFormat::convert($datequery2, 'UTC', $a->getTimeZone())]);
} }
// Does the profile page belong to a forum? // Does the profile page belong to a forum?

View file

@ -104,11 +104,11 @@ class Notify extends BaseDepository
$fields = [ $fields = [
'type' => $Notify->type, 'type' => $Notify->type,
'name' => $Notify->name, 'name' => $Notify->name,
'url' => $Notify->url, 'url' => (string)$Notify->url,
'photo' => $Notify->photo, 'photo' => (string)$Notify->photo,
'msg' => $Notify->msg, 'msg' => $Notify->msg,
'uid' => $Notify->uid, 'uid' => $Notify->uid,
'link' => $Notify->link, 'link' => (string)$Notify->link,
'iid' => $Notify->itemId, 'iid' => $Notify->itemId,
'parent' => $Notify->parent, 'parent' => $Notify->parent,
'seen' => $Notify->seen, 'seen' => $Notify->seen,

View file

@ -408,7 +408,6 @@ class Processor
$event['finish'] = $activity['end-time']; $event['finish'] = $activity['end-time'];
$event['nofinish'] = empty($event['finish']); $event['nofinish'] = empty($event['finish']);
$event['location'] = $activity['location']; $event['location'] = $activity['location'];
$event['adjust'] = $activity['adjust'] ?? true;
$event['cid'] = $item['contact-id']; $event['cid'] = $item['contact-id'];
$event['uid'] = $item['uid']; $event['uid'] = $item['uid'];
$event['uri'] = $item['uri']; $event['uri'] = $item['uri'];

View file

@ -1389,7 +1389,6 @@ class Receiver
$object_data = self::getSource($object, $object_data); $object_data = self::getSource($object, $object_data);
$object_data['start-time'] = JsonLD::fetchElement($object, 'as:startTime', '@value'); $object_data['start-time'] = JsonLD::fetchElement($object, 'as:startTime', '@value');
$object_data['end-time'] = JsonLD::fetchElement($object, 'as:endTime', '@value'); $object_data['end-time'] = JsonLD::fetchElement($object, 'as:endTime', '@value');
$object_data['adjust'] = JsonLD::fetchElement($object, 'dfrn:adjust', '@value');
$object_data['location'] = $location; $object_data['location'] = $location;
$object_data['latitude'] = JsonLD::fetchElement($object, 'as:location', 'as:latitude', '@type', 'as:Place'); $object_data['latitude'] = JsonLD::fetchElement($object, 'as:location', 'as:latitude', '@type', 'as:Place');
$object_data['latitude'] = JsonLD::fetchElement($object_data, 'latitude', '@value'); $object_data['latitude'] = JsonLD::fetchElement($object_data, 'latitude', '@value');

View file

@ -1476,10 +1476,10 @@ class Transmitter
$event = []; $event = [];
$event['name'] = $item['event-summary']; $event['name'] = $item['event-summary'];
$event['content'] = BBCode::convertForUriId($item['uri-id'], $item['event-desc'], BBCode::ACTIVITYPUB); $event['content'] = BBCode::convertForUriId($item['uri-id'], $item['event-desc'], BBCode::ACTIVITYPUB);
$event['startTime'] = DateTimeFormat::utc($item['event-start'] . '+00:00', DateTimeFormat::ATOM); $event['startTime'] = DateTimeFormat::utc($item['event-start'], 'c');
if (!$item['event-nofinish']) { if (!$item['event-nofinish']) {
$event['endTime'] = DateTimeFormat::utc($item['event-finish'] . '+00:00', DateTimeFormat::ATOM); $event['endTime'] = DateTimeFormat::utc($item['event-finish'], 'c');
} }
if (!empty($item['event-location'])) { if (!empty($item['event-location'])) {
@ -1487,7 +1487,8 @@ class Transmitter
$event['location'] = self::createLocation($item); $event['location'] = self::createLocation($item);
} }
$event['dfrn:adjust'] = (bool)$item['event-adjust']; // 2021.12: Backward compatibility value, all the events now "adjust" to the viewer timezone
$event['dfrn:adjust'] = true;
return $event; return $event;
} }

View file

@ -488,10 +488,7 @@ class DFRN
XML::addElement($doc, $author, "poco:note", $profile["about"]); XML::addElement($doc, $author, "poco:note", $profile["about"]);
XML::addElement($doc, $author, "poco:preferredUsername", $profile["nickname"]); XML::addElement($doc, $author, "poco:preferredUsername", $profile["nickname"]);
$savetz = date_default_timezone_get(); XML::addElement($doc, $author, "poco:utcOffset", DateTimeFormat::timezoneNow($profile["timezone"], "P"));
date_default_timezone_set($profile["timezone"]);
XML::addElement($doc, $author, "poco:utcOffset", date("P"));
date_default_timezone_set($savetz);
if (trim($profile["homepage"]) != "") { if (trim($profile["homepage"]) != "") {
$urls = $doc->createElement("poco:urls"); $urls = $doc->createElement("poco:urls");

View file

@ -3314,15 +3314,12 @@ class Diaspora
$eventdata["all_day"] = "false"; $eventdata["all_day"] = "false";
$eventdata['timezone'] = 'UTC'; $eventdata['timezone'] = 'UTC';
if (!$event['adjust'] && $owner['timezone']) {
$eventdata['timezone'] = $owner['timezone'];
}
if ($event['start']) { if ($event['start']) {
$eventdata['start'] = DateTimeFormat::convert($event['start'], "UTC", $eventdata['timezone'], $mask); $eventdata['start'] = DateTimeFormat::utc($event['start'], $mask);
} }
if ($event['finish'] && !$event['nofinish']) { if ($event['finish'] && !$event['nofinish']) {
$eventdata['end'] = DateTimeFormat::convert($event['finish'], "UTC", $eventdata['timezone'], $mask); $eventdata['end'] = DateTimeFormat::utc($event['finish'], $mask);
} }
if ($event['summary']) { if ($event['summary']) {
$eventdata['summary'] = html_entity_decode(BBCode::toMarkdown($event['summary'])); $eventdata['summary'] = html_entity_decode(BBCode::toMarkdown($event['summary']));

View file

@ -305,7 +305,6 @@ class Authentication
$this->session->set('new_member', time() < ($member_since + (60 * 60 * 24 * 14))); $this->session->set('new_member', time() < ($member_since + (60 * 60 * 24 * 14)));
if (strlen($user_record['timezone'])) { if (strlen($user_record['timezone'])) {
date_default_timezone_set($user_record['timezone']);
$a->setTimeZone($user_record['timezone']); $a->setTimeZone($user_record['timezone']);
} }

View file

@ -36,6 +36,13 @@ class DateTimeFormat
const HTTP = 'D, d M Y H:i:s \G\M\T'; const HTTP = 'D, d M Y H:i:s \G\M\T';
const JSON = 'Y-m-d\TH:i:s.v\Z'; const JSON = 'Y-m-d\TH:i:s.v\Z';
static $localTimezone = 'UTC';
public static function setLocalTimeZone(string $timezone)
{
self::$localTimezone = $timezone;
}
/** /**
* convert() shorthand for UTC. * convert() shorthand for UTC.
* *
@ -59,7 +66,7 @@ class DateTimeFormat
*/ */
public static function local($time, $format = self::MYSQL) public static function local($time, $format = self::MYSQL)
{ {
return self::convert($time, date_default_timezone_get(), 'UTC', $format); return self::convert($time, self::$localTimezone, 'UTC', $format);
} }
/** /**
@ -160,7 +167,7 @@ class DateTimeFormat
$to_obj = new DateTimeZone('UTC'); $to_obj = new DateTimeZone('UTC');
} }
$d->setTimeZone($to_obj); $d->setTimezone($to_obj);
return $d->format($format); return $d->format($format);
} }

View file

@ -271,7 +271,11 @@ class Temporal
$id, $id,
$label, $label,
$input_text, $input_text,
'', DI::l10n()->t(
'Time zone: <strong>%s</strong> <a href="%s">Change in Settings</a>',
str_replace('_', ' ', DI::app()->getTimeZone()) . ' (GMT ' . DateTimeFormat::localNow('P') . ')',
DI::baseUrl() . '/settings'
),
$required ? '*' : '', $required ? '*' : '',
'placeholder="' . $readable_format . '"' 'placeholder="' . $readable_format . '"'
], ],
@ -284,7 +288,7 @@ class Temporal
'lang' => $lang, 'lang' => $lang,
'minfrom' => $minfrom, 'minfrom' => $minfrom,
'maxfrom' => $maxfrom, 'maxfrom' => $maxfrom,
] ],
]); ]);
return $o; return $o;
@ -360,23 +364,19 @@ class Temporal
* Returns the age in years, given a date of birth and the timezone of the person * Returns the age in years, given a date of birth and the timezone of the person
* whose date of birth is provided. * whose date of birth is provided.
* *
* @param string $dob Date of Birth * @param string $dob Date of Birth
* @param string $owner_tz (optional) Timezone of the person of interest * @param string $timezone Timezone of the person of interest
* *
* @return int Age in years * @return int Age in years
* @throws \Exception * @throws \Exception
*/ */
public static function getAgeByTimezone($dob, $owner_tz = ''): int public static function getAgeByTimezone(string $dob, string $timezone): int
{ {
if (!intval($dob)) { if (!intval($dob)) {
return 0; return 0;
} }
if (!$owner_tz) { $birthdate = new DateTime($dob . ' 00:00:00', new DateTimeZone($timezone));
$owner_tz = date_default_timezone_get();
}
$birthdate = new DateTime($dob . ' 00:00:00', new DateTimeZone($owner_tz));
$currentDate = new DateTime('now', new DateTimeZone('UTC')); $currentDate = new DateTime('now', new DateTimeZone('UTC'));
$interval = $birthdate->diff($currentDate); $interval = $birthdate->diff($currentDate);

View file

@ -55,7 +55,7 @@
use Friendica\Database\DBA; use Friendica\Database\DBA;
if (!defined('DB_UPDATE_VERSION')) { if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1435); define('DB_UPDATE_VERSION', 1436);
} }
return [ return [
@ -629,7 +629,6 @@ return [
"location" => ["type" => "text", "comment" => "event location"], "location" => ["type" => "text", "comment" => "event location"],
"type" => ["type" => "varchar(20)", "not null" => "1", "default" => "", "comment" => "event or birthday"], "type" => ["type" => "varchar(20)", "not null" => "1", "default" => "", "comment" => "event or birthday"],
"nofinish" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "if event does have no end this is 1"], "nofinish" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "if event does have no end this is 1"],
"adjust" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "adjust to timezone of the recipient (0 or 1)"],
"ignore" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "0 or 1"], "ignore" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "0 or 1"],
"allow_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed contact.id '<19><78>'"], "allow_cid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed contact.id '<19><78>'"],
"allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"], "allow_gid" => ["type" => "mediumtext", "comment" => "Access Control - list of allowed groups"],

View file

@ -186,7 +186,6 @@
"event-location" => ["event", "location"], "event-location" => ["event", "location"],
"event-type" => ["event", "type"], "event-type" => ["event", "type"],
"event-nofinish" => ["event", "nofinish"], "event-nofinish" => ["event", "nofinish"],
"event-adjust" => ["event", "adjust"],
"event-ignore" => ["event", "ignore"], "event-ignore" => ["event", "ignore"],
"signed_text" => ["diaspora-interaction", "interaction"], "signed_text" => ["diaspora-interaction", "interaction"],
"parent-guid" => ["parent-item-uri", "guid"], "parent-guid" => ["parent-item-uri", "guid"],
@ -345,7 +344,6 @@
"event-location" => ["event", "location"], "event-location" => ["event", "location"],
"event-type" => ["event", "type"], "event-type" => ["event", "type"],
"event-nofinish" => ["event", "nofinish"], "event-nofinish" => ["event", "nofinish"],
"event-adjust" => ["event", "adjust"],
"event-ignore" => ["event", "ignore"], "event-ignore" => ["event", "ignore"],
"signed_text" => ["diaspora-interaction", "interaction"], "signed_text" => ["diaspora-interaction", "interaction"],
"parent-guid" => ["parent-item-uri", "guid"], "parent-guid" => ["parent-item-uri", "guid"],

View file

@ -259,6 +259,8 @@ return [
'/dirfind' => [Module\Search\Directory::class, [R::GET]], '/dirfind' => [Module\Search\Directory::class, [R::GET]],
'/directory' => [Module\Directory::class, [R::GET]], '/directory' => [Module\Directory::class, [R::GET]],
'/events/json' => [Module\Events\Json::class, [R::GET]],
'/feed' => [ '/feed' => [
'/{nickname}' => [Module\Feed::class, [R::GET]], '/{nickname}' => [Module\Feed::class, [R::GET]],
'/{nickname}/posts' => [Module\Feed::class, [R::GET]], '/{nickname}/posts' => [Module\Feed::class, [R::GET]],

File diff suppressed because it is too large Load diff

View file

@ -18,8 +18,6 @@
{{include file="field_checkbox.tpl" field=$nofinish}} {{include file="field_checkbox.tpl" field=$nofinish}}
{{include file="field_checkbox.tpl" field=$adjust}}
{{include file="field_input.tpl" field=$summary}} {{include file="field_input.tpl" field=$summary}}

View file

@ -2351,12 +2351,6 @@ aside input[type='text'] {
font-weight: bold; font-weight: bold;
} }
#birthday-adjust {
float: left;
font-size: 75%;
margin-left: 10px;
}
#birthday-title-end { #birthday-title-end {
clear: both; clear: both;
} }
@ -2664,14 +2658,14 @@ aside input[type='text'] {
margin-bottom: 5px; margin-bottom: 5px;
} }
#event-nofinish-checkbox, #event-nofinish-text, #event-adjust-checkbox, #event-adjust-text { #event-nofinish-checkbox, #event-nofinish-text {
float: left; float: left;
} }
#event-datetime-break { #event-datetime-break {
margin-bottom: 10px; margin-bottom: 10px;
} }
#event-nofinish-break, #event-adjust-break { #event-nofinish-break {
clear: both; clear: both;
} }

View file

@ -42,7 +42,6 @@ $(document).ready(function () {
defaultView: "month", defaultView: "month",
aspectRatio: 1, aspectRatio: 1,
eventRender: function (event, element, view) { eventRender: function (event, element, view) {
//console.log(view.name);
switch (view.name) { switch (view.name) {
case "month": case "month":
element element
@ -52,8 +51,8 @@ $(document).ready(function () {
event.item["author-avatar"], event.item["author-avatar"],
event.item["author-name"], event.item["author-name"],
event.title, event.title,
event.item.desc, event.desc,
event.item.location, event.location,
), ),
); );
break; break;
@ -65,8 +64,8 @@ $(document).ready(function () {
"<img src='{0}' style='height:12px; width:12px'>{1}<p>{2}</p><p>{3}</p>".format( "<img src='{0}' style='height:12px; width:12px'>{1}<p>{2}</p><p>{3}</p>".format(
event.item["author-avatar"], event.item["author-avatar"],
event.item["author-name"], event.item["author-name"],
event.item.desc, event.desc,
htmlToText(event.item.location), htmlToText(event.location),
), ),
); );
break; break;
@ -78,8 +77,8 @@ $(document).ready(function () {
"<img src='{0}' style='height:24px;width:24px'>{1}<p>{2}</p><p>{3}</p>".format( "<img src='{0}' style='height:24px;width:24px'>{1}<p>{2}</p><p>{3}</p>".format(
event.item["author-avatar"], event.item["author-avatar"],
event.item["author-name"], event.item["author-name"],
event.item.desc, event.desc,
htmlToText(event.item.location), htmlToText(event.location),
), ),
); );
break; break;
@ -252,27 +251,24 @@ function eventHoverHtmlContent(event) {
moment.locale(locale); moment.locale(locale);
// format dates to different styles // format dates to different styles
var startDate = moment(event.item.start).format("dd HH:mm"); var startDate = event.start.format('dd HH:mm');
var endDate = moment(event.item.finsih).format("dd HH:mm"); var monthShort = event.start.format('MMM');
var monthShort = moment(event.item.start).format("MMM"); var dayNumberStart = event.start.format('DD');
var dayNumberStart = moment(event.item.start).format("DD");
var dayNumberEnd = moment(event.item.finish).format("DD");
var startTime = moment(event.item.start).format("HH:mm");
var endTime = moment(event.item.finish).format("HH:mm");
var monthNumber;
var formattedDate = startDate; var formattedDate = startDate;
// We only need the to format the end date if the event does have // We only need the to format the end date if the event does have
// a finish date. // a finish date.
if (event.item.nofinish == 0) { if (event.nofinish === 0 && event.end !== null) {
var dayNumberEnd = event.end.format('DD');
var endTime = event.end.format('HH:mm');
formattedDate = startDate + " - " + endTime; formattedDate = startDate + " - " + endTime;
// use a different Format (15. Feb - 18. Feb) if the events end date // use a different Format (15. Feb - 18. Feb) if the events end date
// is not the start date // is not the start date
if (dayNumberStart != dayNumberEnd) { if (dayNumberStart !== dayNumberEnd) {
formattedDate = formattedDate = event.start.format('Do MMM') + ' - ' + event.end.format('Do MMM');
moment(event.item.start).format("Do MMM") + " - " + moment(event.item.finish).format("Do MMM");
} }
} }
@ -280,8 +276,8 @@ function eventHoverHtmlContent(event) {
data = eventHoverBodyTemplate(); data = eventHoverBodyTemplate();
// Get only template data if there exists location data // Get only template data if there exists location data
if (event.item.location) { if (event.location) {
var eventLocationText = htmlToText(event.item.location); var eventLocationText = htmlToText(event.location);
// Get the the html template for formatting the location // Get the the html template for formatting the location
var eventLocationTemplate = eventHoverLocationTemplate(); var eventLocationTemplate = eventHoverLocationTemplate();
// Format the event location data according to the the event location // Format the event location data according to the the event location

View file

@ -49,9 +49,6 @@
{{* checkbox if the the event doesn't have a finish time *}} {{* checkbox if the the event doesn't have a finish time *}}
{{include file="field_checkbox.tpl" field=$nofinish}} {{include file="field_checkbox.tpl" field=$nofinish}}
{{* checkbox for adjusting the event time to the timezone of the user *}}
{{include file="field_checkbox.tpl" field=$adjust}}
</div> </div>
{{* checkbox to enable event sharing and the permissions tab *}} {{* checkbox to enable event sharing and the permissions tab *}}

View file

@ -15,8 +15,6 @@
{{$f_dsel nofilter}} {{$f_dsel nofilter}}
{{include file="field_checkbox.tpl" field=$nofinish}} {{include file="field_checkbox.tpl" field=$nofinish}}
{{include file="field_checkbox.tpl" field=$adjust}}
<hr> <hr>
{{include file="field_input.tpl" field=$summary}} {{include file="field_input.tpl" field=$summary}}
{{include file="field_textarea.tpl" field=array('desc', $d_text, $d_orig, "")}} {{include file="field_textarea.tpl" field=array('desc', $d_text, $d_orig, "")}}

View file

@ -3682,8 +3682,6 @@ margin-left: 0px;
#event-nofinish-checkbox, #event-nofinish-checkbox,
#event-nofinish-text, #event-nofinish-text,
#event-adjust-checkbox,
#event-adjust-text,
#event-share-checkbox { #event-share-checkbox {
float: left; float: left;
} }
@ -3693,7 +3691,6 @@ margin-left: 0px;
} }
#event-nofinish-break, #event-nofinish-break,
#event-adjust-break,
#event-share-break { #event-share-break {
clear: both; clear: both;
} }

View file

@ -19,8 +19,6 @@
{{include file="field_checkbox.tpl" field=$nofinish}} {{include file="field_checkbox.tpl" field=$nofinish}}
{{include file="field_checkbox.tpl" field=$adjust}}
{{include file="field_input.tpl" field=$summary}} {{include file="field_input.tpl" field=$summary}}