Версия: 6.x
burger close
Мультисайтовость

ReadyScript - мультисайтовая платформа. Это означает, что несколькими сайтами может управлять одна копия платформы и соответственно в одной базе могут храниться данные нескольких сайтов. Если модуль имеет разделы в административной панели, то информация в этих разделах должна отображаться в соответствии с выбранным для администрирования сайтом. В клиентской части интернет-магазина, информация также должна соответствовать текущему сайту.

ReadyScript имеет ряд возможностей, которые позволяют разработчику с наименьшими усилиями добавить поддержку мультисайтовости для своего модуля. Рассмотрим их подробнее.

Получение объекта текущего сайта

Метод RS::Site::Manager::getSite() - возвращает объект текущего сайта Site::Model::Orm::Site. Метод использует следующий алгоритм:

  • Если текущий URL страницы находится в зоне административной части, метод возвращает выбранный пользователем текущий сайт административной панели.
  • Если текущий URL страницы находится в клиентской зоне, происходит анализ URL на предмет соответствия параметрам (доменному имени и папке), указанным в настройкам сайта в разделе Управление → Сайты.

Пример:

$current_site = \RS\Site\Manager::getSite(); //Получаем объект текущего сайта
echo 'ID:'.$current_site['id']; //Выведет ID текущего сайта
echo 'Короткое название:'.$current_site['title']; //Выведет короткое название сайта
echo 'Полное название:'.$current_site['full_title']; //Выведет полное название сайта
//Также есть конструкция для быстрого получения ID текущего сайта
$current_site_id = \RS\Site\Manager::getSiteId(); //Получаем ID текущего сайта

Создание сущностей, привязанных к сайту

Для привязки любой сущности к сайту, при описании ORM объектов следует объявлять поле site_id. Поле должно иметь тип RS::Orm::Type::CurrentSite. В случае, если site_id не задается явно при записи ORM-объекта в базу, будет подставлен ID текущего сайта.

Пример описания мультисайтового ORM-объекта:

namespace Catalog\Model\Orm;
class Dir extends \RS\Orm\OrmObject
{
//...
function _init()
{
parent::_init()->append(array(
'site_id' => new \RS\Orm\Type\CurrentSite(),
'title' => new \RS\Orm\Type\Varchar(array(
'description' => 'Название'
))
//... другие поля
));
}
}

Пример создания сущности, привязанной к сайту:

//Привязка сущности к текущему сайту
$dir = new \Catalog\Model\Orm\Dir(); //Создаем экземпляр ORM объекта
$dir['title'] = 'Название категории';
//Создаем в базе запись. site_id будет подставлено автоматически и равно текущему сайту.
$dir->insert();
//Привязка сущности к заданному сайту
$dir = new \Catalog\Model\Orm\Dir(); //Создаем экземпляр ORM объекта
$dir['site_id'] = 1; // ID сайта явно задан
$dir['title'] = 'Название категории';
//Создаем в базе запись. site_id будет равно 1
$dir->insert();

Такой подход позволяет объявить поле site_id у ORM объекта и далее ReadyScript самостоятельно будет привязывать объекты к сайтам, на которых происходит создание этих объектов.

Настройка класса модели для выборок мультисайтовых ORM-объектов

Визуальные помощники, используемые в административной части активно работают с моделями, обеспечивающими выборки из базы данных.

Чтобы в администартивной части отображались только соответствующие текущему сайту объекты, необходимо сообщить модели о том, что её ORM объект - мультисайтовый, для этого необходимо вызвать метод setMultisite(true) в конструкторе наследника класса RS::Module::AbstractModel::EntityList. Или можно воспользоваться сокращенным синтаксисом:

namespace Catalog\Model;
{
function __construct()
{
parent::__construct(new \Catalog\Model\Orm\Product,
array(
'multisite' => true, //Использовать мультисайтовые выборки
'aliasField' => 'alias', //Свойство, в котором хранится ЧПУ псевдоним объекта
'defaultOrder' => 'dateof DESC' //Сортировка выборок по умолчанию
));
}
//...
}

Пример работы с мультисайтовыми моделями:

$product_api = new \Catalog\Model\Api();
//Произведет SQL запрос: SELECT * FROM product WHERE site_id = 1
$products = $product_api->getList();
//Добавим условий к выборке
$product_api->setFilter(array(
'title:%like%' => 'ВАЗ',
'num:>' => '5'
'public' => 1
));
//Выполнит SQL запрос: SELECT * FROM product WHERE site_id=1 AND title like '%ВАЗ%' AND num > '5' AND public = '1'
$products = $product_api->getList();

Мультисайтовые модели всегда добавляют условие site_id = 'ID сайта' к выборкам объекта из базы

Учет текущего сайта в прямых выборках из базы

Если в модуле используются прямые запросы на выборку данных, имеющих принадлежность к сайту, например через объект RS::Orm::Request, то обязательно следует дописывать условие, которое будет выбирать данные только для текущего сайта.

Пример:

//Получаем товары, у которых ID основной категории = 23 и товары принадлежат текущему сайту
$products = \RS\Orm\Request::make()
->select('*')
->from(new \Catalog\Model\Orm\Product)
->where(array(
'site_id' => \RS\Site\Manager::getSiteId(), //Фильтруем по ID сайта
'maindir' => 23 //Фильруем товары по главной директории
))->objects();

Заключение

Поддержку мультисайтовости можно добавить на любом этапе разработки модуля, для этого необходимо добавить поля site_id в ORM объекта, прописать ["multisite" => true] в конструкторе модели и указать фильтрацию по site_id в местах, где используются прямые выборки с помощью RS::Orm::Request.

Заметки
Модуль обязательно должен реализовываться с поддержкой мультисайтовости, если данные, от которых он зависит - мультисайтовые. Например, если разрабатываемый модуль строит отчет по наиболее продаваемым товарам, то очевидно, для его корректной работы нужна поддержка мультисайтовости, так как объекты отчетности на каждом сайте различные.