• «просматривать список друзей могут все пользователи» – включаем записи, опубликованные друзьями владельца ленты в блогах социальной сети;
• «полный запрет на просмотр друзей» – не включаем записи, опубликованные друзьями владельца ленты в блогах социальной сети.
Настройки доступа к блогам пользователя:
• «просматривать сообщения могут все пользователи» – включаем записи блога в какую-либо ленту;
• «просматривать сообщения могут только друзья пользователя» – прежде чем включить записи блога в какую-либо ленту, необходимо проверить, не является ли текущий пользователь другом владельца блога;
• «просматривать сообщения могут только друзья и друзья друзей пользователя» – прежде чем включить записи блога в какую-либо ленту, необходимо проверить, не является ли текущий пользователь другом или другом друга владельца блога;
• «просматривать сообщения может только владелец блога» – прежде чем включить записи блога в какую-либо ленту, необходимо проверить, не является ли текущий пользователь владельцем этого блога.
Настройки приватности группы:
• «группа видима всем посетителям» – включаем записи, опубликованные в блоге группы без проверки членства текущего пользователя в данной группе;
• «группа не видима всем посетителям» – прежде чем включить записи, опубликованные в блоге группы, нужно проверить, является ли текущий пользователь ее членом.
Настройки доступа к блогам группы:
• «просматривать сообщения блога могут только члены группы» – это означает, что, прежде чем включать записи, опубликованные в блоге группы, нам нужно выяснить, не является ли текущий пользователь ее членом;
• «просматривать сообщения блога могут только владелец группы и модераторы» – прежде чем включать записи, опубликованные в блоге группы, нужно выяснить, является ли пользователь ее владельцем или модератором;
• «просматривать сообщения блога могут все пользователи» – включаем записи блога группы без дополнительной проверки прав;
• «просматривать сообщения блога может только владелец группы» – прежде чем включать записи, опубликованные в блоге группы, нам нужно выяснить, не является ли текущий пользователь ее владельцем.
Все это придется проверять для каждого (!) блога, который будет попадать в чью-либо ленту. Наглядный пример. Допустим, Иван состоит в группе «Любители виски», которая видима всем посетителям сайта, но сообщения блогов могут читать только члены группы, и свой блог Иван разрешает читать только своим друзьям. Петя состоит в группе «Любители молока», которая видима всем посетителям сайта, и сообщения блогов открыты для всех. Петя – друг Ивана и читать сообщения из своего блога тоже разрешает только друзьям. Маша не состоит в указанных группах и сообщения из своего блога разрешает читать всем посетителям сайта. При этом Маша – друг Пети.
Теперь, если Петя захочет почитать ленту Ивана, то ему должны быть доступны только сообщения из блога Ивана. Если же Иван будет читать ленту Пети, то он должен видеть сообщения из блога Пети и из блога группы «Любителей молока». Маша, посетив ленту Ивана, вообще не должна видеть сообщений, а в ленте Пети – видеть только сообщения из группы «Любителей молока». Если Иван или Маша посетят ленту группы «Любителей молока», то они должны видеть сообщения из блога группы и сообщения из блога Пети. В ленте Маши, Вася и Петя должны будут видеть только сообщения из блога Маши.
Таким образом, для каждого посетителя каждой ленты придется генерировать уникальный кэш, что совершенно противопоказано для метода «полного кэширования результата» (когда сохраняется полностью готовый результат и на время жизни кэша он выдается без единого запроса к базе данных и вычислений в рамках логики компонента). Если предположить, что каждая лента будет состоять, скажем, из 10 страниц, а всего активных участников социальной сети (без учета групп!), например, 1000, то только для лент пользователей будет генерироваться 10 страниц ленты × 1000 лент × 1000 пользователей = 10 000 000 кэш-файлов. Если каждый кэш-файл будет занимать порядка 30 000 байт дискового пространства, то суммарный объем кэш-файлов только лент будет составлять 10 000 000 × 30 000 = 300 000 000 000 байт (≈279 Гбайт)! Мягко говоря, немало.
Как вариант, можно было бы использовать метод генерации страниц ленты с частичным, но не значимым кэшированием. Но полумеры не спасают. Нагрузка на сервер возрастает, несущественно снижая объем кэша (в экспериментах – примерно в три раза) и радикально усложняя логику обработки (как минимум придется тщательно заботиться о сбросе некорректного кэша), отладку и сопровождение модуля.
В итоге при создании социальной сети для сайта www.pcmag.ru было принято решение реализовать ленту примерно в том виде, как описано в данной статье (ряд мелких деталей опущен для удобочитаемости). Да и, как показывает практика, особенной надобности в подключении к «Ленте друзей» дополнительных сущностей в общем-то не возникает. При необходимости (например, если все пользователи вдруг дружно возжелали видеть фотографии друг друга) компонент может быть доработан и расширен.
Drupal: разработка модуля
Роман Архаров
Данная статья – продолжение материала, посвященного CMS Drupal (см. PC Magazine/RE, 12/2008). В первой статье подробно рассказано о назначении и возможностях системы, а также приведены примеры сборки сайтов на Drupal с использованием уже существующих модулей. Этот же материал будет больше интересен техническим специалистам, умеющим программировать на языке PHP, знакомым с основами HTML и CSS, и тем, кто хочет больше узнать о методах разработки собственных модулей для этой системы. Предыдущая статья доступна сейчас в Интернете по адресу: www.pcmag.ru/solutions/detail.php?ID=32535. Перед чтением этого материала рекомендуется освежить в памяти информацию, просмотрев ее первые три раздела.
Разработка собственного модуля
Система управления сайтом Drupal построена по модульному принципу: компактный набор служебных функций (ядро) расширяется при помощи модулей – файлов с PHP-кодом. Модули должны содержать «хуки» (hooks) – особым образом именованные функции, которые вызываются ядром Drupal при возникновении каких-либо событий. Каждый модуль имеет системное имя, которое должно состоять из латинских букв, цифр, знака подчеркивания (и начинаться обязательно с буквы). Имя хука должно состоять из двух частей: имени модуля и названия события. При возникновении любого события ядро Drupal в каждом из установленных модулей ищет и выполняет соответствующую функцию, т. е. функцию с именем название_модуля_название_события. Например, при возникновении событий, связанных с учетной записью пользователя (регистрация, авторизация, изменение роли пользователя и др.), ядро Drupal вызывает функции, реализующие хук hook_user, поэтому, чтобы модуль с именем example мог отреагировать на это событие, в нем необходимо объявить функцию с именем example_user(). Список передаваемых в эту функцию аргументов, пример ее использования и информацию обо всех функциях и хуках, доступных в Drupal, можно найти на странице официальной документации http://api.drupal.org или ее русской версии: http://api.drupal.ru.
Каждый модуль для Drupal представляет два файла или более, которые должны находиться в папке sites/all/modules/название_модуля[1].
В файле название_модуля.info должна находиться служебная информация, а в файле название_модуля.module – исходный текст. При наличии этих двух файлов модуль станет доступным на странице установки модулей Drupal (Administer – Modules, admin/build/modules). Кроме того, в этой же папке может находиться необязательный файл название_модуля.install, содержащий реализации хуков, которые будут выполнены при инсталляции модуля. В этом файле обычно располагаются инструкции, создающие новые таблицы в базе данных и задающие значения по умолчанию для настроек модуля.
Для иллюстрации использования системы хуков я приведу пример разработки простого модуля, который формирует блок с информацией о курсах валют. Этот модуль при выполнении соответствующей строки cron-таблицы будет соединяться с сервером ЦБ РФ и получать от него информацию о курсах валют. На основе полученных данных и настроек, заданных через интерфейс управления модулем, а также функций темизации будет генерироваться выходный HTML-код. Он будет кэшироваться стандартными средствами Drupal (благодаря чему администратор при желании сможет перенести этот кэш из базы данных, например, в файловую систему или memcache) и выдаваться по запросу пользователя в виде блока.
Модуль получит название currencies. На первом этапе его разработки необходимо (относительно корня Drupal-сайта) создать папку sites/all/modules/currencies, в которой мы будем сохранять новые файлы.
currencies.info
В .info-файлах модулей содержится служебная информация, без которой модуль не будет виден в системе. Начинаться любой .info-файл должен со строки