PHP Strange Timezone problem

On my system Timezone is Europe/Berlin in php.ini

//Block 1
$z = \'2009-10-25\';
$a = strtotime($z);
$b = date(\'r\',$a); //Format date from int time stamp to string
echo $b;
//value of $b will be Sun, 25 Oct 2009 00:00:00 +0200

//Block 2
$z = \'2009-10-26\';
$a = strtotime($z);
$b = date(\'r\',$a); //Format date from int time stamp to string
echo $b;
//value of $b will be Mon, 26 Oct 2009 00:00:00 +0100

1. When date is 25th Oct timezone is +2
2. When date is 26th Oct timezone is +1

You can see the difference in timezone caused by strtotime.
Assuming from 26th Oct, winter considered to be start & DST will be applied
in central Europe.

Now is is confirmed that, problem is caused by timezone setting change or DST.

If I keep timezone to UTC, then I can not see this problem. To overcome this issue I set timezone to UTC in my function. This behaviour seriously affects my complex program which calcultes hours.

Please let me know if you have any DST related official information. I mean when it will apply on which date.

Clock changes in Berlin

Advertisements

Gmail/Gdata Contacts & Group via Proxy

In last few days I got chance to see Gdata API. This is nice. I tried to retrieve Gmail Contacts via Proxy server in PHP code using Zend Gdata libriary. Actually Zend Gdata libriary do not have Contacts object like it has for other Google service like calendar, Youtube etc… But Google contacts can be accessed via Zend_Gdata classes easily on direct internet connection but It has some problem with Proxy connection. It can be solved by providing proxy connection parameters while creating Zend_Http_Client object like following:

$httpProxy = array(
       'adapter'      => 'Zend_Http_Client_Adapter_Proxy',
       'proxy_host'   => 'my.proxy.com',
       'proxy_port'   => 3128
);
$clientProxy = new Zend_Http_Client('https://raiyaraj.wordpress.com/', $httpProxy); 

//Client authentication
$client = Zend_Gdata_ClientLogin::getHttpClient($email, $passwd, 'cp', $clientProxy, 'My-ContactFetcher-0.1'); //cp for contacts

Above code help to do some client authentication via proxy server. But If we use $client object make request to retrieve feed data then it gives some errors saying ‘Can not connect to tcp://google.com:80’. Now it seems we have already provided http proxy detail to $clientProxy object, why it is giving error. But http proxy detail needs to provide again before making request to retrieve feed data. Code is like following

$client->setConfig($httpProxy);

Above $client object can be used to call following functions.

Google contacts can have group so to retrieve associated group of contact. First we need to retrieve all groups & its ids. Because only id of group is stored with contact. Following is code to retrieve all groups & its ids.

function getAllContactsGroups($client,$mail)
{
       $scope= "http://www.google.com/m8/feeds/groups/".urlencode($mail)."/";
       $gdata = new Zend_Gdata($client); 
       $query = new Zend_Gdata_Query($scope.'full');
       $query->setMaxResults(10);
       $feed = $gdata->retrieveAllEntriesForFeed($gdata->getFeed($query));
       $arrGroups = array();
       foreach ($feed as $entry){
		$arrGroups[$entry->id->text] =  $entry->title->text;
       }
       return $arrGroups;
} 

Following is code to retrieve all contacts. This code also finds its group id, that is retrieved with contact entry. At the end it prints contact name, its email & its group name.

function getAllContacts($client, $email)
{
	$arrContactGroups = getAllContactsGroups($client,$email);
	$gdata = new Zend_Gdata($client);
	$query = new Zend_Gdata_Query('http://www.google.com/m8/feeds/contacts/default/thin');
	$query->setMaxResults(10);
	$feed = $gdata->retrieveAllEntriesForFeed($gdata->getFeed($query));
	$i =1;
	$arrContacts =  array();
	foreach($feed as $entry){ 
	$name = $entry->title->text;
	$parts = $entry->getExtensionElements(); 
	$contactGroup = '';
		foreach($parts as $p){ 
			$element = $p->getDOM(); 
			switch($element->tagName){ 
			case 'email': 
				$email = $element->getAttribute('address'); 
				break; 
			case 'groupMembershipInfo': 
				$contactGroup = $element->getAttribute('href'); 
				break; 
			default: 
				continue;
			} 
		}
	echo $i++.") ".$name."=". $email ."=". $arrContactGroups[$contactGroup]."<br/>" ;	
	}
}

Links for 2008-09-14

Some good links about GData Zend Framework authentication problem

Zend Framework Bootstrap

Bootstrap is a setup process of different framework component to make easily accessible/available in application. It is very important to setup all require component of framework, so whenever it can be used effectively without any hassle. Bootstrap file is very important file for project using Zend Framework. Bootstrap file or bootstrap process is not a standard in Zend Framework, but to create bootstrap file but it is good practice. Many people use it many way.

It is important to know what are the component of Zend Framework is require. Following is good example of bootstrap.php


require_once 'Zend/Loader.php';

class Bootstrap
{

    public static $frontController = null;

    public static $root = '';

    public static $registry = null;

    //Primary function will be called first from index.php, it will call rest of functions to boot
	public static function run()
    {
        self::prepare();
        $response = self::$frontController->dispatch();
        self::sendResponse($response);
    }

    /*It is used to prepare from macro view.
	It gives macro view idea about preparation.
	Sequence of each call is important.
	*/
	public static function prepare()
    {
        self::setupPath();
    	self::setupErrorReporting();

		//To load all classes automatically, without include or require statement
        Zend_Loader::registerAutoload();

        self::setupRegistry();
        self::setupConfiguration();
        self::setupFrontController();
        self::setupView();
		self::setupLogger();
        self::setupDatabase();
		self::setupSession();
    }

    //Error reporting setting
	public static function setupErrorReporting()
    {
    	error_reporting(E_ALL|E_STRICT);
    	ini_set('display_errors', true);
    }

    //Path settings will be done using this
	public static function setupPath()
    {
        $root = dirname(dirname(__FILE__));
		set_include_path(
		    $root . '/library' . PATH_SEPARATOR .
			$root . '/application' . PATH_SEPARATOR .
			$root . '/application/models' . PATH_SEPARATOR .
			 get_include_path()
		);
        self::$root = dirname(dirname(__FILE__));
    }

	//Date time setting will be done here
	public static function setupDateTime()
	{
		date_default_timezone_set('Europe/London');
	}

    //Registry setting will be done here.
	public static function setupRegistry()
    {
        self::$registry = new Zend_Registry(array(), ArrayObject::ARRAY_AS_PROPS);
        Zend_Registry::setInstance(self::$registry);
    }

    //Configuration file reading & setting up configuration will be done using following.
	public static function setupConfiguration()
    {
        $config = new Zend_Config_Ini(
            self::$root . '/application/config/config.ini',
            'general'
        );
        self::$registry->configuration = $config;
    }

    //Important: Setting of front controller will done here.
	public static function setupFrontController()
    {
        self::$frontController = Zend_Controller_Front::getInstance();
        self::$frontController->throwExceptions(true);
        self::$frontController->returnResponse(true);
        self::$frontController->setControllerDirectory(
            array(
                'default' => self::$root . '/application/controllers',
				'admin' => self::$root . '/application/admin/controllers'
            )
        );
        self::$frontController->setParam('registry', self::$registry);
    }

    /*View setup will be done here.
	Setup view encoding, layout setup also done here
	*/
	public static function setupView()
    {
        $view = new Zend_View;
        $view->setEncoding('UTF-8');
        $viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
        Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
        Zend_Layout::startMvc(
            array(
                'layoutPath' => self::$root . '/application/views/layouts',
                'layout' => 'common',
                'pluginClass' => 'ZFBlog_Layout_Controller_Plugin_Layout'
            )
        );
    }

    /*DB setup done here.
	Read configuration, create db instance & set in registry to use in other part of application.*/
	public static function setupDatabase()
    {
        $config = self::$registry->configuration;
        $db = Zend_Db::factory($config->db->adapter, $config->db->toArray());
        $db->query("SET NAMES 'utf8'");
        self::$registry->database = $db;
        Zend_Db_Table::setDefaultAdapter($db);
    }

    //Response will be sent from following function, also set header for response.
	public static function sendResponse(Zend_Controller_Response_Http $response)
    {
        $response->setHeader('Content-Type', 'text/html; charset=UTF-8', true);
    	$response->sendResponse();
    }

	//Logger setup will can be done using following
	public static function setupLogger()
	{
		/**
		* Create a log formatter
		*/
		$format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
		$formatter = new Zend_Log_Formatter_Simple($format);

		/**
		* Create a file logger
		*/
		$stream = @fopen(APP_DIR . "tmp/logs/" . date("Y-m-d") . ".php", 'a', false);
		if (!$stream)
		{
			throw new Exception('Failed to open stream');
		}
		try
		{
			$fileWriter = new Zend_Log_Writer_Stream($stream);
			$fileWriter->setFormatter($formatter);
			$fileLogger = new Zend_Log($fileWriter);
			Zend_Registry::set("fileLogger", $fileLogger);
		}
		catch (Zend_Log_Exception $e)
		{
			echo "Error: " . $e->getMessage();
		}
		catch (Zend_Exception $e)
		{
			echo "Error: " . $e->getMessage();
		}
	}

	/*
	Zend session setting done here.
	*/
	public static function setupSession()
	{
		try
		{
			Zend_Session::setOptions(array(
				'save_path' => APP_DIR . "/tmp/sessions",
				'remember_me_seconds' => 7200,
		));
		Zend_Session::start();
		}
		catch (Zend_Session_Exception $e)
		{
			$dbLogger->log('Error: ' . $e->getMessage(), 1);
			$fileLogger->log($e->getMessage(), 1);
		}
		$defaultNs = new Zend_Session_Namespace('default');

		Zend_Registry::set("defaultNs", $defaultNs);

		if($config->log_level == 2)
		{
			$fileLogger->info("Sessions setup finished!");
		}
	}

}

To run this bootstrap file we just need to add following code to index.php

require '../application/Bootstrap.php';
Bootstrap::run();

There are many Zend Framework component that is used in normal/regular/usual project but I have not placed it in above code listing. Please suggest.

Please feel free to provide your feedback.