20.10.13, 11:30
0 комментарий
  DLE Хаки

Публичные закладки. Вывод в профиле.

В DataLife Engine есть компонент, позволяющий всем пользователям, имеющим аккаунт, добавлять понравившиеся публикации в личный каталог избранного контента. "Модуль закладок" - двумя словами. По-умолчанию публикации из избранного доступны только для того аккаунта, с которого были занесены туда. Но может случиться так, что разрабатываемый сайт должен быть глубоко социальный и показывать закладки каждого пользователя. То бишь зашел к Васе на страницу и посмотрел какие публикации ему нравятся. Иногда это и правда удобно, по-этому, под катом, будет описан метод реализации.

Нагрузка и подводные камни

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

Хак делает один запрос к БД и понятно почему - публикации-то нужно откуда-то брать. В среднем, чтобы сформировать профиль пользователя, выполняется 6-7 запросов (+1 для выборки закладок) - это многовато даже для такой малопосещаемой страницы как аккаунт. Вообще в DLE ужасная проектировка БД... Ну да ладно, пост не об этом.

С запросами разобрались и, т. к. их сумма оставляет желать лучшего, мной было предусмотрено кэширование постов для каждого профиля. Вроде-бы это хорошо, но тут и кроется подводный камень. Он, в принципе, очевиден, но я приведу цифры дабы каждый мог оценить ситуацию. Допустим у нас средний сайт с 1000-ей зарегистрированных пользователей. 300-та неактивны и еще 300-та не используют закладки в принципе. В остатке получаем 400 аккаунтов, при просмотре каждого из которых будет создан файл кэша. Теперь представим что кэш очищается редко и все 400 профилей были посещены. Т. е. мы получили 400 файлов. Размер их зависит от кол-ва новостей и их объемности. Сочтем, что приблизительное число постов в избранном 3, а размер каждого из них, включая форматирование - 7 Кб. В итоге, по достаточно скромным подсчетам, получим ~8 Мб кэша. Это тоже "не торт".

Если вы дочитали до этого абзаца, то, несмотря на вышеописанное, решили двигаться дальше и, чтобы немного вас подбодрить, я приведу строку кода, которой будет подключаться модификация (использовать в userinfo.tpl):

{favorites count="2" template="favs" cache}


Примечание:
Параметр template может принимать любое значение которое соответствует существующему
файлу шаблона (.tpl).
Параметр cache может присутствовать либо отсутствовать.
В первом случае посты попадут в кэш, а во втором - нет.
Параметр count отвечает за число публикаций, отображаемых в блоке.
Максимальное число - любое трехзначное.

Шаблонами, кэшем и кол-вом постов можно очень легко управлять - это уже хорошо.

П.С. В шаблоне модификации можно использовать все те же макросы, что и в шаблоне кратких новостей.


Реализация - правим файлы

1. Открыть /engine/modules/functions.php и перед строкой:

function check_ip($ips) { 


добавить следующий блок кода (функцию):

/* User Favorites by BR0kEN, Firstvector.org */
function userFavorites($id, $options) {
	global $db, $config;
 
	$options = stripslashes(trim($options));
 
	$sql_select = "SELECT * FROM ". PREFIX ."_post p LEFT JOIN ". PREFIX ."_post_extras e ON (p.id=e.news_id) WHERE p.id IN ({$id})";
 
	if (preg_match('#template="(.+?)"#', $options, $value)) $custom_template = trim($value[1]);
	else $custom_template = 'shortstory';
 
	if (preg_match('#count="(.+?)"#', $options, $value)) $sql_select .= ' LIMIT 0,' . intval($value[1]);
 
	if (strstr($options, 'cache')) $config['allow_cache'] = 'yes';
	else $config['allow_cache'] = false;
 
	$cache_id = $sql_select . $custom_template;
 
	$tpl->result['content'] = dle_cache('favorites', $cache_id);
 
	if ($tpl->result['content'] !== false) return $tpl->result['content'];
	else {
		$tpl = new dle_template();
		$tpl->dir = TEMPLATE_DIR;				
 
		include (ENGINE_DIR . '/modules/show.custom.php');
 
		if ($config['files_allow'] == 'yes' AND strpos($tpl->result['content'], '[attachment=') !== false) $tpl->result['content'] = show_attach($tpl->result['content'], $attachments);
 
		create_cache('favorites', $tpl->result['content'], $cache_id);
 
		return $tpl->result['content'];
	}
}
/* User Favorites by BR0kEN, Firstvector.org */


2. Открыть /engine/modules/profile.php и после строки:

while ( $row = $db->get_row( $sql_result ) ) { 


добавить:

	if ($row['favorites']) {
 
		$tpl->set('[favorites]', '');
		$tpl->set('[/favorites]', '');
		$tpl->set_block("'[not-favorites](.*?)[/not-favorites]'si", '');
 
		if (stripos($tpl->copy_template, '{favorites}') !== false) $tpl->copy_template = preg_replace("#{favorites}#e", "userFavorites('{$row['favorites']}')", $tpl->copy_template);
		elseif (stripos($tpl->copy_template, '{favorites') !== false) $tpl->copy_template = preg_replace("#{favorites(.+?)}#e", "userFavorites('{$row['favorites']}', '1')", $tpl->copy_template);
 
	} else {
 
		$tpl->set_block("'[favorites](.*?)[/favorites]'si", '');
		$tpl->set('[not-favorites]', '');
		$tpl->set('[/not-favorites]', '');
 
		$tpl->copy_template = preg_replace("#{favorites(.+?)}#e", '', $tpl->copy_template);
 
	}
	/* User Favorites by BR0kEN, Firstvector.org */


Примечание:
Подключая модификацию можно использовать "голый" макрос {favorites} и тогда будут выбираться все посты,
использоваться шаблон shortstory и опция кэширования будет неактивна.
Также, можно поднять любой из параметров или указывать их в произвольном порядке.

Важный момент: если у пользователя нет закладок,
то макрос ничего не выведет и сам не отобразиться.
Помимо этого есть возможность использования макросов

[favorites]Текст[/favorites]


и

[not-favorites]Текст[/not-favorites] 


"текст" промеж первых будет виден если у пользователя есть хотя бы один пост в избранном,
а меж вторыми - если постов в закладках нет.


Расставим точки над "i"

Хак, на данной стадии, сыроват. В него можно добавить пару-тройку интересных возможностей, например: использовать вывод избранного не только в профиле, а и в любом другом месте сайта, делать ротации, подборки, добавить пагинацию и т. п.

Автор: BR0kEN

Напишите своё мнение