Показаны сообщения с ярлыком Zend Framework. Показать все сообщения
Показаны сообщения с ярлыком Zend Framework. Показать все сообщения

воскресенье, 25 декабря 2011 г.

PHP sessions across sub domains

Params:
PHP-5.3, Apache-2.2

Problem:
I need a single session for mysite.com and admin.mysite.com domains. I would login on main domain mysite.com, and will be already authorized on sub domains like admin.mysite.com.


Solution:
In script before session start need too setup this session parameters:
session.cookie_path = "/"
session.cookie_domain = ".mysite.com" - dot at the beginning is important, it specify use same sessions on sub domains

Example:
Example for Zend Framework application.


Define site domain name value:
*** public/index.php ***
...
defined('SITE_DOMAIN_NAME')
|| define('SITE_DOMAIN_NAME', (getenv('SITE_DOMAIN_NAME') ? getenv('SITE_DOMAIN_NAME') : 'mysite.com'));
...
It seems, if server value SITE_DOMAIN_NAME is not defined, craete it. We will use it in config file.

You can define SITE_DOMAIN_NAME in .htaccess file, Anyway he need to be configured on every server separately.

*** public/.htaccess ***
...
SetEnv SITE_DOMAIN_NAME mysite.com
...

Further I set session values in config file
*** application/configs/application.ini ***
[production]
...
local.session.cookie_path = "/"
local.session.cookie_domain = "." SITE_DOMAIN_NAME
...
This line  "." SITE_DOMAIN_NAME  is equal to ".mysite.com"

And in Bootstrap.php wee initialize session.
*** application/Bootstrap.php ***
...
protected function _initSession()
{
$localCfg = new Zend_Config($this->getOption('local'), true);
Zend_Session::setOptions($localCfg->session->toArray());
Zend_Session::start();
}
...

пятница, 23 декабря 2011 г.

Zend Framework, bind subdomains to modules

Params:
Zend Framework 1.11, PHP-5.3, Apache 2.2, local pc with Gentoo on board.

Problem:
I want to bind subdomains to certain module of Zend Framework application.
Example: 
http://mysite.com - follow to default module of my app.
http://admin.mysite.com - follow to admin module.
Controllers, actions and params may be various(global variables also):
http://admin.mysite.com/index/index/foo/bar/......
etc.

Solution:
1) Create site with default Zend Framework module structure.
/var/www/mysite.com/
   application/
      configs/
      modules/
         admin/
            controllers/
            views/
         default/
            ......
      Bootstrap.php
   ......

2) Bind DocumentRoot folder of mysite.com, www.mysite.com, admin.mysite.com to the same folder. In my case it's:
/var/www/mysite.com/public

3) In Bootstrap.php file init application router:
 protected function _initRouter()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
$hostnameDefaultRoute = new Zend_Controller_Router_Route_Hostname(':module.mysite.com'  , array('module' => 'default'));
$router->addRoute('default', $hostnameDefaultRoute->chain(new Zend_Controller_Router_Route(':lang/:controller/:action/*', array('lang' => 'en', 'controller'=>'index', 'action'=>'index'))));
  $hostnameDefaultRoute = new Zend_Controller_Router_Route_Hostname('mysite.com'  , array('module' => 'default'));
$router->addRoute('www', $hostnameDefaultRoute->chain(new Zend_Controller_Router_Route(':lang/:controller/:action/*', array('lang' => 'ru', 'controller'=>'index', 'action'=>'index'))))
->addRoute('login'  , $hostnameDefaultRoute->chain(new Zend_Controller_Router_Route_Static('login',   array('controller' => 'user', 'action'=>'login'))));
// routes for admin area
$hostnameAdminRoute = new Zend_Controller_Router_Route_Hostname('admin.mysite.com', array('module' => 'admin'));
$router->addRoute('admin' , $hostnameAdminRoute->chain(new Zend_Controller_Router_Route(':lang/:controller/:action/*',   array('lang' => 'en', 'controller'=>'index', 'action'=>'index'))))
->addRoute('settings' , $hostnameAdminRoute->chain(new Zend_Controller_Router_Route_Static('settings', array('controller' => 'config', 'action' => 'list'))));
}
==================================================================
In a result will work this url's:
mysite.com/ -> Module: default, IndexController, indexAction, lang: en
mysite.com/en/index/index -> Module: default, IndexController, indexAction, lang: en
mysite.com/en/index/index/foo/bar -> Module: default, IndexController, indexAction, lang: en , params: foo = bar
mysite.com/login -> Module: default, UserController, loginAction
admin.mysite.com -> Module: admin, indexController, indexAction, lang: en
admin.mysite.com/en/ -> Module: admin, indexController, indexAction, lang: en
admin.mysite.com/settings -> Module: admin, configController, listAction

4) Also you can use route names in view helper URL. In view script:
echo $this->url(array(), 'www') will output 'mysite.com/en/index/index'
echo $this->url(array('foo' => 'bar'), 'www') will output 'mysite.com/en/index/index/foo/bar'
echo $this->url(array(), 'login') will output 'mysite.com/login'
echo $this->url(array('page' => 1), 'admin') will output 'admin.mysite.com/en/index/index/page/1'
echo $this->url(array(), 'settings') will output 'admin.mysite.com/settings'
Also you can specify controllers and actions
echo $this->url(array('controller' => 'post', 'action' => 'list'), 'www') will output 'mysite.com/en/post/list'
echo $this->url(array('action' => 'print', 'id' => 2), 'admin') will output 'admin.mysite.com/en/index/print/id/2'

четверг, 31 марта 2011 г.

Zend_Validate_Db_RecordExists with doctrine

Validator Code:
<?php
class Validator_NoRecordExists extends Zend_Validate_Abstract
{
      private $_table;
      private $_field;

      const OK = '';

      protected $_messageTemplates = array(
          self::OK => "'%value%' allready in database"
      );

      public function __construct($table, $field) {
            if(is_null(Doctrine::getTable($table)))
                  return null;

            if(!Doctrine::getTable($table)->hasColumn($field))
                  return null;

            $this->_table = Doctrine::getTable($table);
            $this->_field = $field;
      }

      public function isValid($value)
      {
            $this->_setValue($value);

            $funcName = 'findBy' . $this->_field;

            if(count($this->_table->$funcName($value))>0) {
                  $this->_error();
                  return false;
            }

            return true;
      }
}

Use like:
$this->addElement('text', 'username', array(
      'validators' => array(
            array(
                  'validator' => new Validator_NoRecordExists('User','username')
            )
      )
));

 

пятница, 11 марта 2011 г.

Custom Zend_Paginator_Adapter_Doctrine


Source Code:

<?php
require_once ('Zend/Paginator/Adapter/Interface.php');
/**
* @author uommo
* @link http://code.google.com/p/smart-framework/source/browse/trunk/library/SmartL/Zend/Paginator/Adapter/Doctrine.php?r=67
*/
class Zend_Paginator_Adapter_Doctrine implements Zend_Paginator_Adapter_Interface
{
/**
* Doctrine's selection for paginator.
*
* @var Doctrine_Query
*/
private $_query;
/**
* Doctrine's selection for count of items.
*
* @var Doctrine_Query
*/
private $_countQuery = null;
/**
* Hydration mode for doctrine select query.
*
* @var integer
*/
private $_hydrationMode = null;

/**
* Constructs SmartL_Zend_Paginator_Doctrine
*
* @param Doctrine_Query|string $query
* @param integer $hydratationMode Use constaints Doctrine::HYDRATE_*.
* @param array[string]=>mixed $options Options may be:
* 'countQuery'-custom query for count counting. Dql or Doctrine_Query instance.
*/
public function __construct($query, $hydrationMode = null, $options = array())
{
if ( is_string($query) ) {
$newQuery = new Doctrine_Query();
$newQuery->parseDqlQuery($query);
$query = $newQuery;
}
else if ( ! ($query instanceof Doctrine_Query) ) {
require_once 'Zend/Paginator/Exception.php';
throw new Zend_Paginator_Exception("Given query is not instance of Doctrine_Query");
}
$this->_query = $query;
$this->_hydrationMode = $hydrationMode;

//options
if ( !empty($options['countQuery']) ) {
if ( is_string($options['countQuery']) ) {
$countQuery = new Doctrine_Query();
$countQuery->parseDqlQuery($options['countQuery']);
$options['countQuery'] = $countQuery;
}
else if ( ! ($options['countQuery'] instanceof Doctrine_Query) ) {
require_once 'Zend/Paginator/Exception.php';
throw new Zend_Paginator_Exception("Given count-query is not instance of Doctrine_Query");
}
$this->_countQuery = $options['countQuery'];
$this->_countQuery->select('count(*) as count');
}
}

/**
* Returns query for count of items.
*
* @return Doctrine_Query
*/
protected function getCountQuery()
{
if ( $this->_countQuery == null ) {
$this->_countQuery = $this->_query->copy();
$this->_countQuery->select('count(*) as count');

$partsToBeRemoved = array('offset','limit','orderby');
foreach( $partsToBeRemoved as $part ) {
$this->_countQuery->removeDqlQueryPart($part);
$this->_countQuery->removeSqlQueryPart($part);
}
}
return $this->_countQuery;
}

/**
* Implementation of method from Zend_Paginator_Adapter_Interface.
*
* @return integer
*/
public function count()
{
$result = $this->getCountQuery()->execute(array(), Doctrine::HYDRATE_ARRAY);
return $result[0]['count'];
}

/**
* Implementation of method from Zend_Paginator_Adapter_Interface.
*
* @param integer $offset
* @param integer $itemsPerPage
* @return array[numeric|whatever]=>array|Doctrine_Record
*/
public function getItems($offset, $itemsPerPage)
{
$this->_query->limit($itemsPerPage);
$this->_query->offset($offset);
$result = $this->_query->execute(array(), $this->_hydrationMode);
return $result;
}
}




PS. Big Thanks to author of this page: http://code.google.com/p/smart-framework/source/browse/trunk/library/SmartL/Zend/Paginator/Adapter/Doctrine.php?r=67