Archive for the ‘code snippt’ category

Symfony mongodb logger

January 9th, 2010

Thanks for the elegant design of symfony framework, we can easily create a new logger by extending sfLogger.

/**
 * opMongoLogger logs messages in a mongo database.
 *
 * @author     Jayson Xu(http://www.doupie.com) 
*/
class opMongoLogger extends sfLogger
{
  protected
    $timeFormat = '%b %d %H:%M:%S';
  /**
   * Initializes this logger.
   *
   * Available options:
   *
   * - database:      a database name to store the cache in
   * - host:         the host of database
   * - port:         the host of port
   * - collection:   the host of collection
   *
   * @param  sfEventDispatcher $dispatcher  A sfEventDispatcher instance
   * @param  array             $options     An array of options.
   *
   * @return Boolean      true, if initialization completes successfully, otherwise false.
   */
  public function initialize(sfEventDispatcher $dispatcher, $options = array())
  {

    if (!class_exists('Mongo'))
    {
      throw new sfInitializationException(sprintf('the mongodb extension is not installed or enable, cannot use opMongoLogger.'));
    }
    parent::initialize($dispatcher, $options);

    if (!$this->hasOption('database'))
    {
      throw new sfInitializationException(sprintf('You must provide a database name to store the cache in'));
    }
    $this->type = $this->getOption('type','m');
    $this->database = $this->getOption('database');
    $this->host = $this->getOption('host','127.0.0.1');
    $this->port = $this->getOption('port','27017');
    $this->collection = $this->getOption('collection','logs');
    try
    {
      $this->handler = new mongo($this->host.":".$this->port);
      $this->coll_db = $this->handler->selectDB($this->database)->selectCollection($this->collection);
    }
    catch (Exception $e)
    {
      throw new sfInitializationException(sprintf('Could not connect to mongo database : ', $e->getMessage()));
    }

    if (isset($options['time_format']))
    {
      $this->timeFormat = $options['time_format'];
    }
    return true;
  }

  /**
   * Logs a message.
   *
   * @param string $message   Message
   * @param string $priority  Message priority
   */
  protected function doLog($message, $priority)
  {
    $log = array(
      'type'      => $this->type,
      'message'   => $message,
      'time'      => strftime($this->timeFormat),
      'priority'  => $this->getPriority($priority),
      );
    if(sfContext::getInstance())
    {
      $log['module'] = sfContext::getInstance()->getRequest()->getParameter('module');
      $log['action'] = sfContext::getInstance()->getRequest()->getParameter('action');
    }
    $this->coll_db->insert($log);
  }

  /**
   * Returns the priority string to use in log messages.
   *
   * @param  string $priority The priority constant
   *
   * @return string The priority to use in log messages
   */
  protected function getPriority($priority)
  {
    return sfLogger::getPriorityName($priority);
  }

  /**
   * Executes the shutdown method.
   */
  public function shutdown()
  {
    $this->handler->close();
  }

  public function hasOption($option)
  {
    return array_key_exists($option, $this->options);
  }

    /**
   * Gets an option value.
   *
   * @param string $name    The option name
   * @param mixed  $default The default value
   *
   * @return mixed The option value
   */
  public function getOption($name, $default = null)
  {
    return isset($this->options[$name]) ? $this->options[$name] : $default;
  }
}

in opMongoLogger, if the logger is called from action, it will log the module and action too.

output download file in php

December 22nd, 2009

as easy as like this

header ("Content-type: $type");//text/plain
header ("Content-length: $size");// this line is optional
header ("Content-Disposition: attachment; filename=robots.txt"); //the filename you want to save as
readfile('realfile.txt');//the real file path

Minimal CSS pagination helper

December 21st, 2009
function pagination($pager)
{
    $uri = sfRouting :: getInstance()->getCurrentInternalUri();
    $html = '';

    if ($pager->haveToPaginate())
    {
        $uri .= strstr($uri, '?') ? '&page=' : '?page=';
        if ($pager->getPage() != 1)
        {
            $html .= '
  • ' . link_to('first', $uri . '1') . '
  • '; $html .= '
  • ' . link_to('previous', $uri . $pager->getPreviousPage()) . '
  • '; } foreach ($pager->getLinks() as $page) { if ($page == $pager->getPage()) $html .= '
  • ' . link_to($page, $uri . $page) . '
  • '; else $html .= '
  • ' . link_to($page, $uri . $page) . '
  • '; } if ($pager->getPage() != $pager->getLastPage()) { $html .= '
  • ' . link_to('next', $uri . $pager->getNextPage()) . '
  • '; $html .= '
  • ' . link_to('last', $uri . $pager->getLastPage()) . '
  • '; } $html = '
      ' . $html . '
    '; } return $html; }

    minial css

    ul.pagination li {
        display: inline;
        list-style-type: none;
        padding-right: 1em;
    }

    In your template

    echo use_helper('Pagination')
     echo pagination($pager)

    Fetch a Random Record with Doctrine

    December 21st, 2009
    $userCount = Doctrine::getTable('User')->count();
    $user = Doctrine::getTable('User')
      ->createQuery()
      ->limit(1)
      ->offset(rand(0, $userCount - 1))
      ->fetchOne();
    

    Master & Slave connections in Doctrine 1.2 and Symfony 1.3

    December 21st, 2009

    http://snippets.symfony-project.org/snippet/373

    1. 配置database.yml,设置master,slave数据库连接

    2. 覆写Doctrine默认的Query 和Record

    public function configureDoctrine(Doctrine_Manager $manager)
    {
        // Configure custom query and custom record classes
        $manager->setAttribute(Doctrine::ATTR_QUERY_CLASS, 'MyQuery');
        $options = array('baseClassName' => 'MyRecord');
        sfConfig::set('doctrine_model_builder_options', $options);
    }
    

    3. 创建自定义的Query

    class MyQuery extends Doctrine_Query
    {
      public function preQuery()
      {
          // If this is a select query then set connection to the slave
          if (Doctrine_Query::SELECT == $this->getType()) {
              $this->_conn = Doctrine_Manager::getInstance()->getConnection('slave');
          // All other queries are writes so they need to go to the master
          } else {
              $this->_conn = Doctrine_Manager::getInstance()->getConnection('master');
          }
      }
    }
    

    4.创建自定义的Record

    abstract class MyRecord extends sfDoctrineRecord
    {
        public function save(Doctrine_Connection $conn = null)
        {
          $conn = Doctrine_Manager::getInstance()->getConnection('master');
          parent::save($conn);
        }
    }
    

    5. 如果你使用的Doctrine Behaviour(比如Versionable)需要创建表,也需要指明

    Entity:
      ActAs:
        Versionable:
          builderOptions:
            baseClassName: MyRecord
    

    如果你有多个slave服务器,就在ProjectConfiguration中配置在启动的时候选择一个,同时修改Query对象获得得connection名字