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


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

Хак делает один запрос к БД и понятно почему - публикации-то нужно откуда-то брать. В среднем, чтобы сформировать профиль пользователя, выполняется 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"


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

Сам замысел очень хорош и используется на множестве популярных проектов, например на http://habrahabr.ru. Но вот использовать ли данную модификацию на сайте под управлением DLE (архитектура движка никудышная) - вопрос спорный.

Идея разработки взялась из вопроса пользователя на dle-faq.ru: http://dle-faq.ru/faq/questmysql/1888-pravilnyy-zapros-na-vyvod-kontenta-v-zaladkah-polzovatelya.html.

Поддержка разработки


Вышеописанная наработка является, по большей части, отправной точкой для дальнейшей разработки более сложной и универсальной модификации. Если вы заинтересовались и хотите получить качественное дополнение схожего или иного рода, то можете обратиться ко мне с ТЗ, согласовать сумму и аспекты дальнейшей работы.

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

Версия: 0.3b
Автор: BR0kEN, Firstvector.org