Желє

  • May 15, 2010 03:00

Давно тут не писав, бо всьо робота. Проте з роботи виніс багато нового, чим хочу поділитись. Отож желє.

Желє!

Jelly — це смачно

Наше желє має дуже приємний смак з самого початку використання. Після джанги мою голову не покидала думка про те, що моделі класно задавати по полях, що власне в желє і відбувається. Давайте для прикладу візьмемо модель категорії і попробуємо її розібрати. Думаю після цього по желє у вас питань не залишиться.

Як ви мабуть зрозуміли, ми маємо модель абстрактної категорії, яка реалізує в собі одразу дві моделі збереження ієрархічної інформації в двувимірній базі даних: Parent id та Materialized Path (пильний читач одразу зрозуміє загвоздку і побачить спільне між uri та materialized path). Так як категорії в нас обновляються не часто, то паттерн parent id цілком та повністю себе оправдовує, поставили в кеш та і ділов. Шось я відволікаюсь. В більшості ORM з parent_id мали б геморою на пару тижнів, а тут все вирішується льогко і непрінуждьонно: – parent_id стає поле BelongsTo (табличці має бути колонка, HasOne і HasMany потребують колонки в табличках, на йде зв’язок) – children власне наше HasMany, яке в’яжиться на ту ж табличку.parent_id. Вуалля, готово.

Jelly — це корисно

Розберемось з менш смачними, але дуже корисними деталями. Желєйка тісно співпрацює з рідним класом Validate, тому правила, фільтри і задаються просто в масиві, який йде аргументом до конструктора поля.

Також зверніть увагу на поля created_at і updated_at — вони проставляться ахтоматично на відповідних подіях. Не забудьте поставити format, бо можете напоротись на таку ж біду, як колись напоровся я.

Хорошою новиною є те, що наразі виявлених багів в бібліотеці немає, тому беріться до тестування, треба їх знайти.

Може вас стримати те, що не підтримується Primary Key, який би складався з двох полів, хоча поки мені така штука не траплялась. Так шо дєрзайте.

Набагато детальніше (проте не так весело) написано в Івана Броткіна. Також офіційна документація не відмінялась.

Zen coding

  • December 6, 2009 03:00

Дякуючи Стюарту Ленгріджу я тепер теж в темі. Дуже сподобалось на тестах, попробую завтра на роботі.

Шо це таке?

Читайте на сторінці проекту zen coding на гуглокодах та дивіться на відео нижче.

Doctrine і Kohana3

  • September 4, 2009 03:00
Doctrine

Doctrine — це бібліотека ORM. По MVC-паттерну код генерований за допомогою Doctrine можна дуже класно використовувати замість kohana ORM або кастомних моделей. Доктрина має ряд няшок, якими б хотілось скористуватись:

  • Автоматична генерація моделей. Потім дуже зручно їх міняти, бо створюється спеціально доктриновський клас від якого наслідується вже ваш, який власне і міняємо.
  • Можливість задавати базу і моделі за допомогою yaml, що є дуже зручно і зрозуміло. SQL створення бази генерується, моделі генеруються, всьо добре.
  • Решту няшок просто пронумерую: раз два три.

Скачати.

Kohana 3

Kohana 3, як показує ссилка ось-ось зарелізиться, але проекти не чекають. Щоб йти в ногу з технологіями потрібно приймати ризиковані новаторські рішення. Більше того, по моїм перечитуванням коду реліз кандидату склалось дуже приємне враження, оптимізували і дуже спростили ядро, не втрачаючи необхідного функціоналу звісно. Скачати останню версію.

Процедура

Власне нам потрібно створити модуль kohana, який буде в собі включати доктріну. Відволікатись на таку просту процедуру ми не будемо, в нас doctrine буде лежати в… ну з конфіга буде краще видно я думаю.

Kohana::modules(array(
//    'database'  => MODPATH.'database', Database
//    'kodoc'      => MODPATH.'kodoc',      // Kohana documentation
//    'orm'        => MODPATH.'orm',        // Object Relationship Mapping (not complete)
    'auth'   => MODPATH.'auth',   // Database access
    'pagination' => MODPATH.'pagination', // Paging of results
    'image'      => MODPATH.'image',      // Image manipulation
    'doctrine'   => MODPATH.'doctrine',   // Doctrine ORM
);

Ми виключаємо рідний kohana orm і ActiveRecord і підключаємо натомість doctrine. Далі в папці з модулем доктріни ложимо файлик init.php (вот за що я люблю kohana, тут всьо продумано) з наступним вмістом.

<?php
/* Doctrine integration */
require Kohana::find_file('classes', 'doctrine/Doctrine');
/* Реєструємо аутолоадер. Після розробки доктріну можна скомпілити в один файл
 * розміров 800кб правда. Не думаю шо там можна шось сильно оптимізувати.
 * Суть в тому, що треба виключити буде аутолоадер. якщо буде скомпілений файл.
 */
spl_autoload_register(array('Doctrine', 'autoload'));
// Читаємо конфіги для конекту з базою даних
$db = Kohana::config('database')->doctrine;
// Получаємо менеджер доктріни
$manager = Doctrine_Manager::getInstance();
//Створюємо конект
$manager->connection('mysql://'.$db['user'].':'.$db['password'].'@'.$db['host'].'/'.$db['database'], 'default_connection');
// @see http://www.doctrine-project.org/documentation/manual/1_1/en/configuration
$manager->setAttribute(Doctrine::ATTR_MODEL_LOADING, Doctrine::MODEL_LOADING_CONSERVATIVE);
$manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
$manager->setAttribute(Doctrine::ATTR_DEFAULT_IDENTIFIER_OPTIONS, array('name' => '%s_id', 'type' => 'int', 'length' => 11));
$manager->setAttribute(Doctrine::ATTR_PORTABILITY, Doctrine::PORTABILITY_ALL);
$manager->setAttribute(Doctrine::ATTR_QUOTE_IDENTIFIER, true);
$manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL);
$manager->setAttribute(Doctrine::ATTR_TBLNAME_FORMAT, $db['prefix'].'_%s');
$manager->setAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES, true);
// Доктринові моделі будуть лежати не в classes/ а окремо в MODPATH
Doctrine::loadModels(APPPATH.'models');

Вроді все прокоментовано. Єдине запитання може виникати до конфігураційного файла бази даних. Вот доречі і він:

<?php

return array(
    'doctrine' => array(
        'user'      => 'username',
        'password'  => 'supersecretpasword',
        'host'      => 'localhost',
        'database'  => 'fancy_site',
        'prefix'    => 'wtfpl',
    )
);

Отак отримуємо інтегровану Doctrine в kohana. Опісля, якщо у вас з модулями йдуть моделі доктрини, то в тому ж init.php ставимо наступне:

Doctrine::loadModels(MODPATH.'blog/models');

для модуля блогу наприклад ;)

Бонус

Також викладаю вам спеціально драйвер бібліотеки Auth для використання з doctrine. Розібратись де його поставити зовсім не важко (правда я півдня думав чи його пхати до auth чи до doctrine). Да, ще одне, використовуючи бібліотеку авторизації треба уважно слідкувати за цією сторіночкою.

Код драйвера власне тут. Я думаю резонно його включити в модуль auth, хоча б для того, щоб якщо хтось ще задастся таким питанням, то зможе використати. Да, драйвер ще не тестований, тому можуть бути очевидні завтики, але походу реалізований.

Серія записок безумного архітектора #2

  • June 23, 2009 03:00

Завдання в нас доволі тривіальне: потрібно зробити вивід сторінок типу {host}/page/name з довільною ієрархією (тобто в нас може бути декілька слешів, які зазвичай сприймаються як шлях до сторінки) швидким пошуком, щоб генерація сторінки займала як-омога менше часу і щоб це було просто і очевидно. В інтернеті куча інформації на цю тему, готових рішень не менше. Проте я придумав свого велосипеда, про якого піде мова далі.

Вирішувати його будемо простеньким хуком. Приступимо зразу до коду, пояснення будуть потім.


<?php

// Вішаємось на післяроутингу

// це викличе нашу функцію коли роутинг закінчиться

Event::add('system.post_routing' ,'call_fallback_page');

function call_fallback_page()

{

    
// визначаємо чи наразі визначений контроллер

    
if (Router::$controller === NULL) {

        // контроллера нема, якраз наш випадок!

        
Router::$controller 'page';

        
// встановлюємо наш контроллер ^ і метод, якмй показуватиме статичну сторінку

        Router::$method 'show';

        
// знаходимо шлях до контроллера

        
Router::$controller_path Kohana::find_file('controllers''page');

    }

}

// перший профіт!

Тепер діло в контроллері. Ми повинні перевірити, чи така сторінка існує, а якщо ні показати 404-ту сторіночку.


<?php

// Сторінки розмічені маркдауном

require Kohana::find_file('vendor''Markdown');

// Власне контроллер. Я використовую Template_Controller свого приготування,

// не забудьте поміняти свого парента

class Page_Controller extends Website_Controller {

    
public function show()

    {

        
$page ORM::factory('page'Router::$current_uri;);

        // orm модель має перевизначений метод unique_id()

        
if ($page->id 0) {

            
//сторінка знайдена!

            //змінні как бе намєкають нам на правильну SEO оптимізацію

            
$this->template->keywords $page->keywords;

            $this->template->description $page->description;

            
$this->template->content = new View('page');

            $this->template->content->title $page->title;                

            
$this->template->content->text Markdown($page->body);            

            $this->template->content->modified $page->modified;

        } else {

            
// ніц не знайшли, показуємо 404-ту помилку.

            Kohana::instance()->show_404();

        }

    }

}


Я думаю модель створити і відповідні в’юшки — не проблема. На крайняк їх можна подивитись в репозиторії цього сайту.

З цього починається люба CMS.

Як копіюють музику на плеєр

  • June 14, 2009 03:00

Ото йду на прогулку і рішив закинути собі дейва на плеєр. Не всього (не влізе банально), а тільки то, шо сподобалось раніше. Благо Quodlibet сам випасає шо мені подобається, а що ні по очевидному алгоритму, з яким я згідний. Без компромісів. Писати плагіна на пітоні в неділю ввечері — забити на прогулку. Тому ми скористались тим що було. Активовуємо плагін Export to HTML плеєра, ставимо в плейлісті тільки колонку Path to file і також відмічаємо Show Full Path to file. Вже згенерований плейліст через пошук, як я писав в першому(?) пості в цьому блозі експортуємо в html в папочку. Відкриваємо текстовим редактором, html до першого рядка таблиці і з останнього, зберігаємо, йдемо до кроку два бігом!

Саме цікаве. В папочці створюємо файлик player.php, в який ставимо наступний вміст:


<?php

//Шлях до файла.

$files file('songs.html');

//рахуємо кількість файлів

$count count($files);

//Понеслись!

for ($i 0$i $count$i++) {

    
//Забрали теги нафіг і стрімили перевод строчки

    
$source trim(strip_tags($files[$i]));

    
// Написали якусь каляку шо робиться

    
echo "copying file: ".$source."\n";

    
// Копіюєм $файл в шлях. в мене /media/disk/muzik/dmb/. У вас скоріш за все що інший

    
exec("cp \"".$source."\" \"/media/disk/muzik/dmb/".pathinfo($sourcePATHINFO_BASENAME)."\"");

}

// Раз два три — закінчили

echo "FUKKEN SAVED!!!!!!!1111111\n";

Уважно читаємо коментарі, міняємо керуючись здоровим глуздом.

потім в терміналі

php player.php

Чекаєм характерного повідомлення, відключаємо плеєр і йдем гуляти, гарного вечора.

Коменти виключаються

  • June 8, 2009 03:00

Коментарі в цьому блозі не потрібні. Зі спамом я вже навчився боротись, але це не значить, шо ці падли повинні гадити тут. Коментарі людей залишаться в мому серці назавжди =)

Відтак це не означає, що коментарі відміняються в двигунці блогу. Їх можна буде включити опціонально.

Я знаю хто прийде жалітись, тому пишіть в жаббер.

Authorize.net CIM Kohana library

  • May 28, 2009 03:00

Надокучаю з постами сьогодні, розписався аж нема куда і нічого по ділу. Шойно запакував і виклад модулем Kohana Authorize.net CIM. Думаю передруковувати мануал як підключати модуль не треба. Як і говорилось попередньо, бібліотека НЕ ПОВНІСТЮ реалізує API, а тільки ті частини, які мені потрібні в робочому проекті. З часом проект буде рости, вот і будуть реалізовуватись решта методів.

Наразі доступні такі методи:

  • create_customer(User_Model $user, Profile_Model $profile, Location_Model $location, $credit_card, $expiration_date)
  • create_customer_profile(Profile_Model $profile, $credit_card)
  • get_customer_profile($authorize_customer_id)
  • delete_customer_profile($authorize_customer_id, $customer_profile_id)
  • create_customer_transaction($authorize_customer_id, $amount)

API не кинсистентне, проте можна вже користуватись. Набити решту методів нема проблеми, логіка побудови модуля думаю дуже зрозуміла навіть для початківця. Тепер стукатиму zomborу нехай добавляє до проектів, а вже буде репозиторій можна буде допиляти до нормального стану.

Робивши цю білбіотеку заодно навчився пакувати модулі для kohana. Все дуже просто. У вас бібліотека називається XXX. В папці libraries/drivers створюєте файл Xxx.php в якому описуєте інтерфейс драйвера (з аналогічного файлу) і створюєте Xxx/drivername.php власне сам драйвер, який має реалізовувати інтерфейс.

Зараз є два драйвера fsockopen і curl. В конфігураційному файлі зазначаєте який використовувати.

Питання

  • May 26, 2009 03:00

Є сервіс з користувачами, які роблять на ньому шось (купують чи продають нерухомість для прикладу). При появленні нерухомості в фідах потрібно розіслати всім підпизчикам фіду емейли з тим, що появилась нерухомість в фіді.

Досі не доводилось займатись такими речами, тому якщо хтось знає відповідь на це питання — залиште коментар. А я собі погуглю ще ;)

P.S. про модуль Authorize.net CIM: Не хочу оформляти окремим топіком, теж по темі. Основна частина API вже зроблена (замічу шо реалізовував не все, а тільки те що потрібно наразі мені по роботі), тому напевне на даному етапі відрефакторю код і викладу. Це я хочу встигнути зробити ще в двадцять, так шо на цьому тижні.

По роботі

  • May 20, 2009 03:00

Поступив в конвеєр на розробку модуль для роботи з Authorize.net CIM для kohana framework. По завершенню проекта очікується реліз на офіційному репозиторії.

Наразі модуль вміє тільки створювати користувачів, зате має вже два драйвера — curl і fsockopen. Код базується на класі Authorize.net CIM PHP, правда вже гарно розбитим на власне бібліотеку і в’юшки генерації xml. Нажаль вищезгаданий клас в мене з полпінка не запрацював (ага, навіть тести які були запаковані з ним не спрацювали), тому родилась ідея велосипедостроєнія.

А у вас є шось законтрібутити в opensource?

Пофікшені баги

  • May 6, 2009 14:45

Пофіксив деякі баги на адмінці (фронтенд вроді не чіпав) і поміняв важкий FCKEditor на markitup. Раз jquery — завжди jquery.