Mohammed Kashmiry Mohammed Kashmiry - 7 months ago 11
PHP Question

changing wordpress timezone manually by visitors

I have this code that change the wordpress time zone manually from the footer

<form method="post" id="timezone_change">
<select name="timezone_change" onchange='this.form.submit()'>
<option value="3">3</option>
<option value="4">4</option>
</select>
</form>

<?php
if ($_POST['timezone_change'] == '3') { update_option( 'gmt_offset', '+3' ); }
if ($_POST['timezone_change'] == '4') { update_option( 'gmt_offset', '+4' ); }
?>


The problem is that this would change the timezone for all the site visitors
I want the code to work just that every visitor have a different (separate) timezone settings? how can I make that possible

Answer

There's no nice way to do this in a persistent manner that you have stored and identified to each user. As such... it'd require a bit of database and code jiggery-pokery in order to actually allow for the dates to be changed in accordance to what is stored on a various cookie/session/something.

If you're really serious about having individual user timeframes on each post, besides the obvious 'godspeed' that I'll offer, you'd need to create the variable first. gmt_offset is for every post that is created, sort of like a global option as you've said. You'll have to create a value just for the users to have and look at.

Using Cookies

Having cookies is one way to store the data about whether a user has a timezone selected... and it's certainly a good way to do it. The example for that would be to do this:

set_cookie( "tzDif", $_POST['timezone_change'], time()+(30*24*60*60) );

This sets a cookie with the name of tzDif to have whatever value they have chosen. The same rule applies with a session with the minor differences of syntax and assignment. This would allow you to completely absolve yourself of looking at whether or not they are logged in as it would be selected and cached on their own systems.

If you'd like to implement that... skip to the bottom for the rest of the answer, this bit is going to be another option, using MySQL.

Using MySQL

The minor problem with cookies though, is that I've found them to be a tad unreliable.

Storing them as an SQL variable in the tables is a lot better in terms of reliability and in stuff that I like (take that however you will). This requires a lot more jiggery-pokery and actually requires for you to alter the database too.

You'd have to run a statement to add in an integer column named 'user_gmt_offset' for the wp_users table, giving it a default of '0'. So...

ALTER TABLE wp_users ADD user_gmt_offset INT NOT NULL DEFAULT 0;

As Pekka 웃 said in the comment above, you have to have some way to identify the user. You could use cookies or sessions of your own creation, or you could use the session that wordpress creates whenever you log in.

For the sake of simplicity, I'll talk about the latter option.

Whenever you do have a page which has been connected to the Wordpress headers, it lets you get the functions that it has, simple enough. One of those functions is called update_user_option() handily enough.

The composition of the function is similar to the one above with a few adjustments:

update_user_option( USER_ID, OPTION_NAME, OPTION_VALUE, BLOG_SPECIFIC )

They speak for themselves for the most part. USER_ID is the id of the user you are going to be altering. The OPTION_NAME is a string for the name of the option... again, obviously. OPTION_VALUE is whatever value you are going to be setting it to now, and finally, BLOG_SPECIFIC (which is false by default) is for if you want a certain option to be specific to a blog.

So in your case... this is the code composition you would be using (with a minor alteration in terms of how the tz selection is used):

<?php

  //Sort out WordPress malarkey and reference all the includes for using it
  define('WP_USE_THEMES', false);
  require("URL/TO/WP/INSTALLATION/wp-blog-header.php");

  //Then let's get the current user information IF AND ONLY IF they
  // are logged in... don't want to break things now...
  if ( is_user_logged_in() ) {

    //Although, if they've not set the timezone yet, we don't want
    // it to prematurely fire and break things to null or something
    if ( !isset( $_POST['timezone_change'] ) return;

    //Get the current user's information now and assign it
    // to the wordpress default variable for this stuff
    global $current_user;
    get_currentuserinfo();

    //Now let's do the update
    update_user_option( $current_user->ID, 
        'user_gmt_offset', $_POST['timezone_change'] );

  }

?>

Assuming that I have done things right in theory... that should change an individual user's value to whatever timezone they have desired. That was the SQL explanation.

Implementing in Wordpress

Moving on again to how it's actually implemented... you're going to have to go and find the function that gets the time, in other words... the_time() as I recall, and alter it to check a few things.

You'll have to check whether or not the user is logged in/if the cookie is set, if they're/it's not, use the default values of gmt_offset given in the database, and if they are/it is... use the value that has been defined previously, whether it's in the cookie, or in the database.

I'll not go into too specific detail of how to do that, I figure there's enough detail in this post to potentially confuse before I start rambling on about altering that function to something else (read as written too much).

I'll do some checking and re-update this with any enhancements that I find.

Comments