Контент


Своя CMS: префиксы?

И снова я о префиксах. Напомню, недавно я задался целью сделать возможным в каждом модуле будущей CMS свои префиксы для таблиц (причем с учетом возможного использования их в самом приложении). Полученное решение довольно громоздкое, и при попытке распространить его даже в пределах одного модуля понял, что пошел не тем путем. Ведь существует такая замечательная вещь, как хуки!

Постановка задачи

Конфигурация подключения к БД имеет конкретную структуру, вот пример из дистрибутива:

$config['default'] = array
(
	'benchmark'     => TRUE,
	'persistent'    => FALSE,
	'connection'    => array
	(
		'type'     => 'mysql',
		'user'     => 'dbuser',
		'pass'     => 'p@ssw0rd',
		'host'     => 'localhost',
		'port'     => FALSE,
		'socket'   => FALSE,
		'database' => 'kohana'
	),
	'character_set' => 'utf8',
	'table_prefix'  => '',
	'object'        => TRUE,
	'cache'         => FALSE,
	'escape'        => TRUE
);

Параметров довольно много, большинство мы и не собираемся трогать. Так почему бы не сделать так, чтобы в каждом модуле указывать только измененные параметры (в нашем случае это table_prefix). А все пропущенные ключи должны браться из массива настроек по умолчанию. Например, профиль для подключения форума в идеале должен выглядеть так:

// modules/forum/config/database.php
$config['forum'] = array
(
	'table_prefix'	=> 'forum_',
);

Звучит довольно логично, не так ли? Так что за работу.

Хук во всей своей красе

Как мы помним, хуки загружаются до первого из событий системы, поэтому мы можем выбрать любое из них для привязки. Возьмем в качестве сигнала к обработке настроек событие с «напрашивающимся» именем system.ready:

// modules/cms/hooks/cms.php
<?php defined('SYSPATH') OR die('No direct access allowed.');
 
class cms {
 
	public function __construct() {
    Event::add('system.ready', array($this, 'fill_configs'));
	}
 
  public function fill_configs() {
    // смотрим все конфиги БД и если каких-то полей нет, дополняем их default'ными
    $configs = Kohana::config('database');
    $default_size = count($configs['default']);
    $default_prefix = strlen($configs['default']['table_prefix']) > 0 ? $configs['default']['table_prefix'] : FALSE;
    foreach ($configs as $name => $config) {
      if ($name === 'default') continue;
      if (count($config) == $default_size) continue;
      $newconfig = arr::overwrite($configs['default'], $config);
      // Для префиксов придется сделать исключение
      $default_prefix !== FALSE AND $newconfig['table_prefix'] = $default_prefix.$newconfig['table_prefix'];
      Kohana::config_set('database.'.$name, $newconfig);
    }
  }
}
 
new cms;

Все достаточно просто — считываем конфигурацию профилей БД и в цикле сверяем профили с default‘ным по количеству элементов (конечно это не на 100% решает все проблемы, но зато довольно просто и быстро). Дополнительно проверяем наши уже порядком надоевшие префиксы, т.к. если они уже используются в стандартном профиле, их надо учитывать.

На всякий случай, если вы этого не знаете: конфигурационные файлы считываются системой по запросу (исключение — файл application/config/config.php), поэтому в принципе мы могли выбрать любое событие до загрузки контроллера (т.к. в конструкторе контроллера уж наверняка будет создано соединение с БД).

Теперь у нас есть полноценные конфиги для каждого модуля, так что можно смело использовать в моделях конструкторы вида:

// modules/forum/models/Forum.php
public function __construct($id = NULL) {
    $this->db = 'forum';
    parent::__construct($id);
  }

И напоследок

Наблюдательные товарищи могут возразить — ведь в массиве $config['default'] есть и вложенный массив $config['default']['connection'], который тоже может быть заполнен не полностью! И в этом случае он не будет работать как надо, т.к. мы его просто не обновим. Согласен, надо это исправить — как раз будет вам домашнее задание. ;)

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в Пишем CMS.

Теги: , , , , .


Комментарии (2)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.

  1. Xobb пишет:

    Не знаю почему, но именно такие хуки радуют меня найбольше. За это можна сказать и любим kohana.

  2. BIakaVeron пишет:

    Я сперва думал, что основная цель хуков — что-то вроде вывода баннеров/счетчиков после system.display :)



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.