понедельник, 7 февраля 2011 г.

среда, 2 февраля 2011 г.

Symfony: Doctrine IndexBy field


$posts = Doctrine_Query::create()
->from('Post p INDEXBY id')
->fetchArray()
;

на выходе получаем массив индексированный по реальным значениям id,
а не [0 => array(), 1 => array() ... ]

p.s. спасибо develop7 за наводку

суббота, 29 января 2011 г.

Symfony: doctrine raw sql, get alphabet from i18n model

Задача: получить алфавит из i18n модели, для разных языков.
Показать только те буквы на которые начинаются имена.

in actions.class.php

$lang = $request->getParameter('lang', 'ru');

$query = "
SELECT substring(`name`,1,1) as firstletter
FROM `xxx_translation`
WHERE `lang` = '".$lang."' AND
substring(`name`,1,1) <> ''
GROUP BY substring(`name`,1,1)
";

$pdo = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
$stmt = $pdo->prepare($query);
$stmt->execute();

$this->abc = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);


in template

<?php if ($abc): ?>
<ul id="abcList">
<?php foreach ($abc as $letter): ?>
<li><?php echo link_to($letter, '@user_list?search='.$letter.'&pos=start')?> </li>
<?php endforeach; ?>
</ul>
<br clear="all" />
<?php endif; ?>


Css

ul#abcList li {
float: left;
display: inline;
list-style: none;
padding: 4px;
}

вторник, 21 сентября 2010 г.

Symfony: backend pager



Что бы получше выделить текущую страницу в пейджере далаем небольшие изменения:

1. CSS
.currentPage {
border: 1px solid #ff9900;
padding: 4px;
background: #eeeeff;
}


2. layout.php

jQuery(document).ready(function($){

// try to find pager
pager = $('.sf_admin_pagination').html();
if (pager) {
var re = /(\s+)(\d+)(\s)+/;
var newstr = pager.replace(re, "$2");
$('.sf_admin_pagination').html(newstr);
}

понедельник, 14 декабря 2009 г.

Symfony: settings

Нередко требуется часть настроек из app.yml сделать редактируемыми в backend, напишем простенький класс.
Схема:
Config:
tableName: sf_config
columns:
id: { type: integer(4), primary: true, autoincrement: true }
name: { type: string(32) }
value: { type: string(32) }
description: { type: string(1024) }


Класс /lib/myConfig.class.php:
class myConfig extends sfConfig
{
public static function get($name, $default = null, $description = null)
{
if (!sfConfig::get($name))
{
$res = Doctrine::getTable('Config')->findOneByName($name);
if (!$res)
{
$c = new Config();
$c->setName($name);
$c->setValue($default);
$c->setDescription($description);
$c->save();
}
}

return (isSet(self::$config[$name]) ? self::$config[$name] : $default);
}

}


Данный класс не находя в настройках требуемого параметра, проверяет его наличие в таблице, и в случаее отсутствия добавляет его.

Фильтр /lib/filters/myConfigFilter.class.php:
class myConfigFilter extends sfFilter
{
public function execute ($filterChain)
{
$configs = Doctrine::getTable('Config')->findAll();
foreach ($configs as $config)
{
sfConfig::set($config->getName(), $config->getValue());
}
$filterChain->execute();
}
}


Фильтр экспортирует из БД настройки в sfConfig.

Добавляем в fontend/config/filters.yml

myConfig:
class: myConfigFilter


Используем:
$postDirName = sfConfig::get('sf_upload_dir').'/'.myConfig::get('posts_dir', 'posts');
'max_size' => myConfig::get('post_max_icon_size', '10', 'size in KBytes')*1024, //(10*1024=10KB in bytes)


Сгенерируем управление из backend
$ symfony doctrine:generate-admin backend Config


Используем backend_dev.php/config

понедельник, 26 октября 2009 г.

Symfony: Doctrine slugify кириллица

/lib/Slugify.class.php

class SlugifyClass {
  static function Slugify($title) {
    $gost = array(
     "Є"=>"EH","І"=>"I","і"=>"i","№"=>"#","є"=>"eh",
     "А"=>"A","Б"=>"B","В"=>"V","Г"=>"G","Д"=>"D",
     "Е"=>"E","Ё"=>"JO","Ж"=>"ZH",
     "З"=>"Z","И"=>"I","Й"=>"JJ","К"=>"K","Л"=>"L",
     "М"=>"M","Н"=>"N","О"=>"O","П"=>"P","Р"=>"R",
     "С"=>"S","Т"=>"T","У"=>"U","Ф"=>"F","Х"=>"KH",
     "Ц"=>"C","Ч"=>"CH","Ш"=>"SH","Щ"=>"SHH","Ъ"=>"'",
     "Ы"=>"Y","Ь"=>"","Э"=>"EH","Ю"=>"YU","Я"=>"YA",
     "а"=>"a","б"=>"b","в"=>"v","г"=>"g","д"=>"d",
     "е"=>"e","ё"=>"jo","ж"=>"zh",
     "з"=>"z","и"=>"i","й"=>"jj","к"=>"k","л"=>"l",
     "м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
     "с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"kh",
     "ц"=>"c","ч"=>"ch","ш"=>"sh","щ"=>"shh","ъ"=>"",
     "ы"=>"y","ь"=>"","э"=>"eh","ю"=>"yu","я"=>"ya","«"=>"","»"=>"","—"=>"-"," "=>"-"
    );

    $iso = array(
     "Є"=>"YE","І"=>"I","Ѓ"=>"G","і"=>"i","№"=>"#","є"=>"ye","ѓ"=>"g",
     "А"=>"A","Б"=>"B","В"=>"V","Г"=>"G","Д"=>"D",
     "Е"=>"E","Ё"=>"YO","Ж"=>"ZH",
     "З"=>"Z","И"=>"I","Й"=>"J","К"=>"K","Л"=>"L",
     "М"=>"M","Н"=>"N","О"=>"O","П"=>"P","Р"=>"R",
     "С"=>"S","Т"=>"T","У"=>"U","Ф"=>"F","Х"=>"X",
     "Ц"=>"C","Ч"=>"CH","Ш"=>"SH","Щ"=>"SHH","Ъ"=>"'",
     "Ы"=>"Y","Ь"=>"","Э"=>"E","Ю"=>"YU","Я"=>"YA",
     "а"=>"a","б"=>"b","в"=>"v","г"=>"g","д"=>"d",
     "е"=>"e","ё"=>"yo","ж"=>"zh",
     "з"=>"z","и"=>"i","й"=>"j","к"=>"k","л"=>"l",
     "м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
     "с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"x",
     "ц"=>"c","ч"=>"ch","ш"=>"sh","щ"=>"shh","ъ"=>"",
     "ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya","«"=>"","»"=>"","—"=>"-"," "=>"-"
    );

    $rtl_standard = sfConfig::get('rtl_standard', 'gost') ;

    //to lower case

    $title = mb_strtolower($title, 'UTF-8');
    
    switch ($rtl_standard) {
      case 'off':
          return $title;
      case 'gost':
          $out = trim(strtr($title, $gost), '-');
      default:
          $out = trim(strtr($title, $iso), '-');
    }
    
    // clean slug
    $out = preg_replace('/[^a-z0-9\-]+/i', '', $out);
    return $out;
  }
}



Использование

Post:
  actAs:
    Timestampable: ~
    Taggable: ~
    Sluggable:
      unique: true
      fields: [title]
      canUpdate: true
      builder: [SlugifyClass, Slugify]