[TikiWiki-commits] [Git][tikiwiki/tiki][master] [NEW] Detect timezone incoherence and easy way to fix

Benoit Grégoire (@benoitg) via TikiWiki-cvs <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <68b88a74edb04_2cdd1d06174e@gitlab-sidekiq-low-urgency-cpu-bound-v2-57685456b9-gvvjp.mail>

Benoit Grégoire pushed to branch master at Tiki Wiki CMS Groupware / Tiki


Commits:
eabe0d07 by Alain Cisirika at 2025-09-03T18:27:18+00:00
[NEW] Detect timezone incoherence and easy way to fix
---
* [NEW] Detect timezone incoherence and easy way to fix

See merge request tikiwiki/tiki!8079

- - - - -


6 changed files:

- .gitlab-ci.yml
- lib/core/Services/User/Controller.php
- lib/prefs/user.php
- + lib/test/Core/Services/User/ControllerTest.php
- templates/tiki-show_page.tpl
- + templates/user/localtimezonesync.tpl


Changes:

=====================================
.gitlab-ci.yml
=====================================
@@ -9,6 +9,7 @@ stages:
   - composer-stability
 
 variables:
+  TZ: "UTC"
   MYSQL_ROOT_PASSWORD: secret
   MYSQL_DATABASE: tikitest
   MYSQL_USER: tikiuser


=====================================
lib/core/Services/User/Controller.php
=====================================
@@ -1128,6 +1128,55 @@ class Services_User_Controller
         }
     }
 
+    public function actionLocalTimezoneSync($input)
+    {
+        global $user, $tikilib;
+        $access = TikiLib::lib('access');
+        $clientTz = $input->client_timezone->text();
+        $action = $input->timezone_action->text();
+
+        if ($action === 'never') {
+            if ($tikilib->set_preference('user_localtimezonesync', 'n')) {
+                $tikilib->set_user_preference($user, 'localtimezonesync', 'n');
+            }
+            $access->redirect($_SERVER['HTTP_REFERER']);
+            return [];
+        }
+
+        if (! empty($_SESSION["temp_timezone"])) {
+            $preferedTz = $_SESSION["temp_timezone"];
+        } else {
+            $preferedTz = $tikilib->get_user_preference($user, 'display_timezone', '');
+        }
+
+        if ($action === 'switch') {
+            $tikilib->set_user_preference($user, 'display_timezone', $clientTz);
+            $preferedTz = $tikilib->get_user_preference($user, 'display_timezone', '');
+        } elseif ($action === 'temporary') {
+            $_SESSION["temp_timezone"] = $clientTz;
+            $preferedTz = $clientTz;
+        }
+
+        $different = $clientTz && $clientTz !== $preferedTz;
+        $result = [
+            'different'      => $different ? true : false,
+            'preferedTimezone' => $preferedTz,
+            'clientTimezone'   => $clientTz,
+        ];
+
+        if ($action === 'switch' || $action === 'temporary') {
+            return $this->redirectAndReturn($result);
+        }
+
+        return $result;
+    }
+
+    private function redirectAndReturn($data = []): array
+    {
+        header("Location:" . $_SERVER['HTTP_REFERER']);
+        return $data;
+    }
+
     private function removeUsers(array $users, $page = false, $trackerIds = [], $files = false)
     {
         global $user;


=====================================
lib/prefs/user.php
=====================================
@@ -369,6 +369,14 @@ function prefs_user_list($partial = false)
             'default' => 'n',
             'dependencies' => ['feature_userPreferences'],
         ],
+        'user_localtimezonesync' => [
+            'name' => tra('Local Timezone Synchronization'),
+            'description' => tr('Allow user to manage timezone incoherence.'),
+            'help' => 'User-Preferences',
+            'type' => 'flag',
+            'default' => 'y',
+            'tags' => ['basic'],
+        ],
         'user_default_avatar_style' => [
             'name' => tr('Default avatar style'),
             'description' => tr('Default avatar style for users when registering.'),


=====================================
lib/test/Core/Services/User/ControllerTest.php
=====================================
@@ -0,0 +1,75 @@
+<?php
+
+// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
+//
+// All Rights Reserved. See copyright.txt for details and a complete list of authors.
+// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
+
+namespace Tiki\Test\Core\Services\User;
+
+use JitFilter;
+use PHPUnit\Framework\TestCase;
+use Services_User_Controller as ServicesUserController;
+
+class ServicesUserControllerTest extends TestCase
+{
+    protected $controller;
+    protected static $originalTimezone;
+    protected $originalUserSyncPref;
+
+    protected function setUp(): void
+    {
+        global $prefs,$user;
+
+        $_SERVER['HTTP_REFERER'] = 'http://example.com/some/page';
+
+        self::$originalTimezone = $prefs['display_timezone'];
+        $this->originalUserSyncPref = $prefs['user_localtimezonesync'];
+    }
+
+    protected function tearDown(): void
+    {
+        global $prefs;
+
+        $prefs['display_timezone'] = self::$originalTimezone;
+        $prefs['user_localtimezonesync'] = $this->originalUserSyncPref;
+
+        unset($_SESSION['temp_timezone']);
+        unset($_SERVER['HTTP_REFERER']);
+    }
+
+    public function testTimezoneSwitchAction(): void
+    {
+
+        $input = new JitFilter([
+            'client_timezone' => 'Africa/Lubumbashi',
+            'timezone_action' => 'switch',
+        ]);
+
+        $result = (new ServicesUserController())->actionLocalTimezoneSync($input);
+
+        $this->assertEquals([
+            'different' => false,
+            'preferedTimezone' => 'Africa/Lubumbashi',
+            'clientTimezone' => 'Africa/Lubumbashi'
+        ], $result);
+    }
+
+    public function testTimezoneTemporaryAction(): void
+    {
+        $input = new JitFilter([
+            'client_timezone' => 'Africa/Lubumbashi',
+            'timezone_action' => 'temporary',
+        ]);
+
+        $_SESSION['temp_timezone'] = $input->client_timezone;
+
+        $result = (new ServicesUserController())->actionLocalTimezoneSync($input);
+
+        $this->assertEquals([
+            'different' => false,
+            'preferedTimezone' => 'Africa/Lubumbashi',
+            'clientTimezone' => 'Africa/Lubumbashi'
+        ], $result);
+    }
+}


=====================================
templates/tiki-show_page.tpl
=====================================
@@ -39,7 +39,10 @@ Note: The show content block must be defined at root level to use the include. A
     {if !isset($hide_page_header) or !$hide_page_header}
         {include file='tiki-flaggedrev_approval_header.tpl'}
     {/if}
-
+    {if $prefs.user_localtimezonesync == 'y' and !empty($user)}
+        {include file="user/localtimezonesync.tpl"}
+    {/if}
+    
     {if $print_page ne 'y'}
         {if $prefs.page_bar_position eq 'top'}
             {include file='tiki-page_bar.tpl'}


=====================================
templates/user/localtimezonesync.tpl
=====================================
@@ -0,0 +1,54 @@
+<div id="timezone-sync-box" style="display: none;">
+    {remarksbox  close="" title="{tr}Timezone Synchronisation{/tr}"}
+        <div class="d-flex justify-content-between">
+            <form method="post" id="timezone-form" action="{service controller=user action=localtimezonesync}">
+                {ticket}
+                <p>
+                    {tr _0='<strong><span class="detected-tz-name"></span></strong>' _1='<strong><span class="current-tz-name"></span></strong>'}New Timezone Detected We detect a new timezone %0, but your configured timezone is set to %1.{/tr}
+                </p>
+                <p class="mb-3">{tr}What would you like to do?{/tr}</p>
+                <input type="hidden" name="client_timezone" id="client-timezone" value=""/>
+                <input type="hidden" name="prefered_timezone" id="prefered-timezone" value=""/>
+                <div class="d-grid gap-2">
+                    <button
+                        title="{tr}Details: {/tr}{tr}This will permanently change your profile timezone.{/tr}"
+                        class="btn btn-primary btn-sm tips tz-switch-button"
+                        name="timezone_action" value="switch" type="submit">
+                        {icon name="sync-alt"} {tr _0='<span class="detected-tz-name"></span>'}Switch my default to %0{/tr}
+                    </button>
+                    <button
+                        title="{tr}Details: {/tr}{tr}This will only use the detected timezone for this session.{/tr}"
+                        class="btn btn-secondary btn-sm tips tz-temporary-button"
+                        name="timezone_action" value="temporary" type="submit">
+                        {icon name="clock"} {tr _0='<span class="detected-tz-name"></span>'}Only change timezone to %0 until (your next login?){/tr}
+                    </button>
+
+                    <button
+                    title="{tr}Details: {/tr}{tr}Your timezone setting will not be changed and this notification will be disabled.{/tr}"
+                        class="btn btn-outline-danger btn-sm tips"
+                        name="timezone_action" value="never" type="submit">
+                        {icon name="times-circle"} {tr}Keep my current setting and stop asking{/tr}
+                    </button>
+                </div>
+            </form>
+        </div>
+    {/remarksbox}
+</div>
+{jq}
+    $(document).ready(function () {
+        const clientTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
+        $.post('tiki-ajax_services.php', {
+            controller: 'user',
+            action: 'LocalTimezoneSync',
+            client_timezone: clientTimeZone
+        }, function (response) {
+            if (response && response.different === true) {
+                $('#timezone-sync-box').show();
+                $('#prefered-timezone').val(response.preferedTimezone);
+                $('#client-timezone').val(response.clientTimezone);
+                $('.detected-tz-name').text(response.clientTimezone);
+                $('.current-tz-name').text(response.preferedTimezone);
+            }
+        }, 'json');
+    });
+{/jq}
\ No newline at end of file



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/eabe0d070f1ae4c03327b74096998787c33f9bd4

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/eabe0d070f1ae4c03327b74096998787c33f9bd4
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.