<?php
/*
=====================================================
 DataLife Engine - by SoftNews Media Group
-----------------------------------------------------
 https://dle-news.ru/
-----------------------------------------------------
 Copyright (c) 2004-2025 SoftNews Media Group
=====================================================
 This code is protected by copyright
=====================================================
 File: artists.php
-----------------------------------------------------
 Use: artists index + artist tracks
=====================================================
*/

if( !defined('DATALIFEENGINE') ) {
	header( "HTTP/1.1 403 Forbidden" );
	header ( 'Location: ../../' );
	die( "Hacking attempt!" );
}

$nocache = false;
if (isset($_REQUEST['nocache']) AND $_REQUEST['nocache']) {
	$nocache = true;
}

$artist_param = '';
if (isset($_REQUEST['name'])) {
	$artist_param = (string)$_REQUEST['name'];
} elseif (isset($_REQUEST['artist'])) {
	$artist_param = (string)$_REQUEST['artist'];
}

$artist_param = trim(strip_tags(rawurldecode($artist_param)));
$artist_param = preg_replace('/\s+/u', ' ', $artist_param);

// ------------------------------
// Artist detail: show tracks
// ------------------------------
if ($artist_param !== '') {
	$artist_title = $artist_param;
	if (function_exists('dle_substr')) {
		$artist_title = dle_substr($artist_title, 0, 80);
	} else {
		$artist_title = mb_substr($artist_title, 0, 80, 'UTF-8');
	}

	$artist_title_safe = htmlspecialchars($artist_title, ENT_QUOTES, 'UTF-8');

	$metatags['title'] = $artist_title . ' &raquo; ' . $metatags['title'];

	$navigation_first_page = $config['http_home_url'] . "index.php?do=artists&name=" . urlencode($artist_param);
	$url_page = $navigation_first_page . "&cstart={cstart}";
	$canonical = $navigation_first_page;

	// DLE pagination uses cstart as page number in URL, but internally uses offset
	$cstart = isset($_GET['cstart']) ? intval($_GET['cstart']) : 0;
	if ($cstart < 1) $cstart = 0;
	if ($cstart > 9999999) $cstart = 9999999;

	$config['news_number'] = intval($config['news_number']);
	if ($config['news_number'] < 1) $config['news_number'] = 1;

	if ($cstart) {
		$cstart = ($cstart - 1) * $config['news_number'];
	}

	// Same base restrictions logic as engine.php default branch
	$thisdate = date ( "Y-m-d H:i:s", time() );
	if ($config['no_date'] AND !$config['news_future']) {
		$where_date = " AND p.date < '" . $thisdate . "'";
	} else {
		$where_date = "";
	}

	$fixed = $config['allow_fixed'] ? "fixed desc, " : "";

	$news_sort_by = $config['news_sort'] ? $config['news_sort'] : "date";
	$news_direction_by = $config['news_msort'] ? $config['news_msort'] : "DESC";

	$allow_list = explode ( ',', $user_group[$member_id['user_group']]['allow_cats'] );
	$stop_list = "";
	$cat_join = "";
	$cat_join_count = "";
	$extra_join = "LEFT JOIN " . PREFIX . "_post_extras e ON (p.id=e.news_id) ";

	if ($allow_list[0] != "all") {

		if ($config['allow_multi_category']) {

			$cat_join = "INNER JOIN (SELECT DISTINCT " . PREFIX . "_post_extras_cats.news_id FROM " . PREFIX . "_post_extras_cats WHERE cat_id IN (" . implode ( ',', $allow_list ) . ")) c ON (p.id=c.news_id) ";
			$cat_join_count = "p " . $cat_join;

		} else {

			$stop_list = "category IN ('" . implode ( "','", $allow_list ) . "') AND ";

		}

	}

	$not_allow_cats = explode ( ',', $user_group[$member_id['user_group']]['not_allow_cats'] );

	if( $not_allow_cats[0] ) {

		if ($config['allow_multi_category']) {

			$stop_list = "p.id NOT IN ( SELECT DISTINCT(" . PREFIX . "_post_extras_cats.news_id) FROM " . PREFIX . "_post_extras_cats WHERE cat_id IN (" . implode ( ',', $not_allow_cats ) . ") ) AND ";
			$cat_join_count = "p ";

		} else {

			$stop_list = "category NOT IN ('" . implode ( "','", $not_allow_cats ) . "') AND ";

		}

	}

	if( $config['user_in_news'] ) {

		$user_select = ", u.email, u.name, u.user_id, u.news_num, u.comm_num as user_comm_num, u.user_group, u.lastdate, u.reg_date, u.banned, u.allow_mail, u.info, u.signature, u.foto, u.fullname, u.land, u.favorites, u.pm_all, u.pm_unread, u.time_limit, u.xfields as user_xfields ";
		$user_join = "LEFT JOIN " . USERPREFIX . "_users u ON (e.user_id=u.user_id) ";

	} else { $user_select = ""; $user_join = ""; }

	if ($user_group[$member_id['user_group']]['allow_short']) { $stop_list = ""; $cat_join = ""; $cat_join_count = ""; }

	if( !in_array($news_sort_by, array('rating', 'news_read', 'editdate')) ) $extra_join = '';

	// Escape LIKE wildcards and backslashes
	$artist_like = addcslashes($artist_param, "\\%_");
	$artist_like = $db->safesql($artist_like);

	$artist_where = "xf.tagname='artistsong' AND xf.tagvalue LIKE '%{$artist_like}%' ESCAPE '\\\\'";

	$sql_select_ids = "SELECT DISTINCT p.id FROM " . PREFIX . "_post p INNER JOIN " . PREFIX . "_xfsearch xf ON (xf.news_id=p.id) {$cat_join}{$extra_join}WHERE {$stop_list}p.approve=1 AND {$artist_where}{$where_date} ORDER BY " . $fixed . $news_sort_by . " " . $news_direction_by . " LIMIT " . $cstart . "," . $config['news_number'];

	$sql_count = "SELECT COUNT(DISTINCT p.id) as count FROM " . PREFIX . "_post p INNER JOIN " . PREFIX . "_xfsearch xf ON (xf.news_id=p.id) {$cat_join}WHERE {$stop_list}p.approve=1 AND {$artist_where}";

	$sql_select = "SELECT p.id, p.autor, p.date, p.short_story, CHAR_LENGTH(p.full_story) as full_story, p.xfields, p.title, p.descr, p.keywords, p.category, p.alt_name, p.comm_num, p.allow_comm, p.allow_main, p.approve, p.fixed, p.symbol, p.tags, e.news_read, e.allow_rate, e.rating, e.vote_num, e.votes, e.view_edit, e.disable_index, e.editdate, e.editor, e.reason {$user_select}FROM " . PREFIX . "_post p LEFT JOIN " . PREFIX . "_post_extras e ON (p.id=e.news_id) {$user_join}";

	$sql_select_ids = $db->super_query($sql_select_ids, true);
	$tracks_total = 0;
	$seo_text = '';

	if (count($sql_select_ids)) {

		$temp_arr = array();
		foreach ($sql_select_ids as $value) {
			$temp_arr[] = $value['id'];
		}

		$sql_select_ids = implode(',', $temp_arr);

		$sql_select .= "WHERE p.id IN ({$sql_select_ids}) ORDER BY FIND_IN_SET(p.id, '" . $sql_select_ids . "')";

		$count_row = $db->super_query($sql_count . $where_date);
		$tracks_total = isset($count_row['count']) ? (int)$count_row['count'] : 0;
		if ($tracks_total < 0) $tracks_total = 0;

		$seo_text = "Descarcă muzică cu {$artist_title} — {$tracks_total} melodii. Ascultă online și descarcă MP3 pe telefon sau PC.";
		$seo_text_safe = htmlspecialchars($seo_text, ENT_QUOTES, 'UTF-8');
		$metatags['description'] = $seo_text;
		$metatags['keywords'] = "{$artist_title}, {$artist_title} mp3, {$artist_title} melodii, descarca muzica {$artist_title}, asculta {$artist_title}";
		$page_header_info['title'] = $artist_title;
		$page_header_info['description'] = $seo_text;

		// Render track list via show.short.php, then wrap it with a dedicated artist header.
		$prev_content = $tpl->result['content'] ?? '';
		$tpl->result['content'] = '';
		$tpl->result['navigation'] = '';
		include_once (DLEPlugins::Check(ENGINE_DIR . '/modules/show.short.php'));
		$tracks_html = (string)($tpl->result['content'] ?? '');
		$nav_html = (string)($tpl->result['navigation'] ?? '');
		$tracks_html = str_replace('{newsnavigation}', '', $tracks_html);

		$nav_block = '';
		if (trim($nav_html) !== '') {
			$nav_block = '<div class="sect__footer">' . $nav_html . '</div>';
		}

		$tpl->result['content'] = $prev_content . <<<HTML
<div class="artists-page serv" itemscope itemtype="https://schema.org/CollectionPage">
	<div class="page__main d-flex sect">
		<div class="page__main-left">
			<div class="page__img img-block ratio-1-1">
				<img src="{THEME}/images/logo.svg" id="cover" alt="{$artist_title_safe}" loading="lazy" itemprop="image">
			</div>
		</div>
		<div class="page__main-right flex-1 d-flex fd-column r-gap-20">
			<h1 class="playlist__title" itemprop="name">{$artist_title_safe}</h1>
			<div class="page__caption" itemprop="description">{$seo_text_safe}</div>
			<div><i class="fal fa-music"></i> <b>{$tracks_total}</b> melodii</div>
		</div>
	</div>

	<section class="sect">
		<div class="sect__content grid-items" id="grid-items">
			{$tracks_html}
		</div>
		{$nav_block}
	</section>
</div>
HTML;
		$tpl->result['navigation'] = '';

	} else {
		// Fallback: if xfsearch isn't populated yet, try to match from xfields in posts
		DLEXFields::Init();
		$artist_norm = function_exists('dle_strtolower') ? dle_strtolower($artist_param) : mb_strtolower($artist_param, 'UTF-8');
		$artist_norm = trim(preg_replace('/\s+/u', ' ', $artist_norm));

		$matched_ids = array();
		$scanned = 0;
		$max_scan = 20000;

		$fallback_sql = "SELECT p.id, p.xfields FROM " . PREFIX . "_post p {$cat_join}WHERE {$stop_list}p.approve=1 AND p.xfields<>'' AND p.xfields LIKE '%artistsong|%'" . $where_date . " ORDER BY p.date DESC";
		$db->query($fallback_sql);

		while ($row = $db->get_row()) {
			$scanned++;
			if ($scanned > $max_scan) break;

			$xfieldsdata = DLEXFields::xfieldsdataload($row['xfields']);
			if (!isset($xfieldsdata['artistsong']) OR $xfieldsdata['artistsong'] === '') continue;

			$val = trim((string)$xfieldsdata['artistsong']);
			if ($val === '') continue;

			$parts = preg_split('/\s*(?:,|;|&|\\/|\\+|\s+and\s+|\s+feat\\.?\s+|\s+ft\\.?\s+|\s+featuring\s+)\s*/iu', $val, -1, PREG_SPLIT_NO_EMPTY);
			if (!is_array($parts) || !count($parts)) $parts = array($val);

			foreach ($parts as $p) {
				$p = trim(preg_replace('/\s+/u', ' ', (string)$p));
				if ($p === '') continue;
				$p_norm = function_exists('dle_strtolower') ? dle_strtolower($p) : mb_strtolower($p, 'UTF-8');
				$p_norm = trim(preg_replace('/\s+/u', ' ', $p_norm));
				if ($p_norm === $artist_norm) {
					$matched_ids[] = (int)$row['id'];
					break;
				}
			}
		}
		$db->free();

		$total_count = count($matched_ids);
		if ($total_count) {
			$page_ids = array_slice($matched_ids, $cstart, $config['news_number']);
			if (count($page_ids)) {
				$sql_select_ids = implode(',', array_map('intval', $page_ids));
				$sql_select .= "WHERE p.id IN ({$sql_select_ids}) ORDER BY FIND_IN_SET(p.id, '" . $sql_select_ids . "')";
				// show.short.php appends $where_date to $sql_count; use a self-contained count query and clear $where_date.
				$sql_count = "SELECT {$total_count} as count";
				$where_date = '';

				$tracks_total = $total_count;
				$seo_text = "Descarcă muzică cu {$artist_title} — {$tracks_total} melodii. Ascultă online și descarcă MP3 pe telefon sau PC.";
				$seo_text_safe = htmlspecialchars($seo_text, ENT_QUOTES, 'UTF-8');
				$metatags['description'] = $seo_text;
				$metatags['keywords'] = "{$artist_title}, {$artist_title} mp3, {$artist_title} melodii, descarca muzica {$artist_title}, asculta {$artist_title}";
				$page_header_info['title'] = $artist_title;
				$page_header_info['description'] = $seo_text;

				$prev_content = $tpl->result['content'] ?? '';
				$tpl->result['content'] = '';
				$tpl->result['navigation'] = '';
				include_once (DLEPlugins::Check(ENGINE_DIR . '/modules/show.short.php'));
				$tracks_html = (string)($tpl->result['content'] ?? '');
				$nav_html = (string)($tpl->result['navigation'] ?? '');
				$tracks_html = str_replace('{newsnavigation}', '', $tracks_html);

				$nav_block = '';
				if (trim($nav_html) !== '') {
					$nav_block = '<div class="sect__footer">' . $nav_html . '</div>';
				}

				$tpl->result['content'] = $prev_content . <<<HTML
<div class="artists-page serv" itemscope itemtype="https://schema.org/CollectionPage">
	<div class="page__main d-flex sect">
		<div class="page__main-left">
			<div class="page__img img-block ratio-1-1">
				<img src="{THEME}/images/logo.svg" id="cover" alt="{$artist_title_safe}" loading="lazy" itemprop="image">
			</div>
		</div>
		<div class="page__main-right flex-1 d-flex fd-column r-gap-20">
			<h1 class="playlist__title" itemprop="name">{$artist_title_safe}</h1>
					<div class="page__caption" itemprop="description">{$seo_text_safe}</div>
			<div><i class="fal fa-music"></i> <b>{$tracks_total}</b> melodii</div>
		</div>
	</div>

	<section class="sect">
		<div class="sect__content grid-items" id="grid-items">
			{$tracks_html}
		</div>
		{$nav_block}
	</section>
</div>
HTML;
				$tpl->result['navigation'] = '';
			} else {
				$tpl->load_template('info.tpl');
				$tpl->set('{error}', 'No tracks found for this artist.');
				$tpl->set('{title}', $artist_title);
				$tpl->compile('content');
				$tpl->clear();
			}
		} else {
			$tpl->load_template('info.tpl');
			$tpl->set('{error}', 'No tracks found for this artist. If you added tracks earlier, rebuild xfields search index in admin.');
			$tpl->set('{title}', $artist_title);
			$tpl->compile('content');
			$tpl->clear();
		}
	}

	return;
}

// ------------------------------
// Artists index: list artists
// ------------------------------

$normalize_artist_key = function($name) {
	$name = trim(preg_replace('/\s+/u', ' ', (string)$name));
	if ($name === '') return '';
	return function_exists('dle_strtolower') ? dle_strtolower($name) : mb_strtolower($name, 'UTF-8');
};

$split_artists = function($val) {
	$val = trim((string)$val);
	if ($val === '') return array();

	$parts = preg_split('/\s*(?:,|;|&|\\/|\\+|\s+and\s+|\s+feat\\.?\s+|\s+ft\\.?\s+|\s+featuring\s+)\s*/iu', $val, -1, PREG_SPLIT_NO_EMPTY);
	if (!is_array($parts) || !count($parts)) $parts = array($val);

	$out = array();
	foreach ($parts as $p) {
		$p = trim(preg_replace('/\s+/u', ' ', (string)$p));
		if ($p !== '') $out[] = $p;
	}
	return $out;
};

$has_multi_artist_separators = function($val) {
	return (bool)preg_match('/(?:,|;|&|\\/|\\+|\s+and\s+|\s+feat\\.?\s+|\s+ft\\.?\s+|\s+featuring\s+)/iu', (string)$val);
};

$is_change = false;
if (!$config['allow_cache']) { $config['allow_cache'] = 1; $is_change = true; }

$cache_key = $config['skin'];
$cached = false;
if (!$nocache) {
	$cached = dle_cache('artists_index', $cache_key);
}

if ($cached !== false) {
	$artists_items = json_decode($cached, true);
	if (json_last_error() !== JSON_ERROR_NONE || !is_array($artists_items)) {
		$artists_items = array();
	}
} else {
	$artists_items = array();
	$artists_display = array();
	$artists_counts = array();
	$need_fallback_counts = false;

	// Respect date limitation like engine.php
	$thisdate = date("Y-m-d H:i:s", time());
	if ($config['no_date'] AND !$config['news_future']) {
		$where_date = " AND p.date < '" . $thisdate . "'";
	} else {
		$where_date = "";
	}

	// Respect category permissions
	$allow_list = explode(',', $user_group[$member_id['user_group']]['allow_cats']);
	$not_allow_cats = explode(',', $user_group[$member_id['user_group']]['not_allow_cats']);
	$stop_list = "";
	$cat_join = "";

	if (!$user_group[$member_id['user_group']]['allow_short']) {
		if ($allow_list[0] != "all") {
			if ($config['allow_multi_category']) {
				$cat_join = "INNER JOIN (SELECT DISTINCT " . PREFIX . "_post_extras_cats.news_id FROM " . PREFIX . "_post_extras_cats WHERE cat_id IN (" . implode(',', $allow_list) . ")) c ON (p.id=c.news_id) ";
			} else {
				$stop_list = "p.category IN ('" . implode("','", $allow_list) . "') AND ";
			}
		}

		if ($not_allow_cats[0]) {
			if ($config['allow_multi_category']) {
				$stop_list = "p.id NOT IN ( SELECT DISTINCT(" . PREFIX . "_post_extras_cats.news_id) FROM " . PREFIX . "_post_extras_cats WHERE cat_id IN (" . implode(',', $not_allow_cats) . ") ) AND ";
				$cat_join = "";
			} else {
				$stop_list = "p.category NOT IN ('" . implode("','", $not_allow_cats) . "') AND ";
			}
		}
	}

	// Preferred: aggregated counts from xfsearch (fast)
	$db->query(
		"SELECT xf.tagvalue, COUNT(DISTINCT xf.news_id) as cnt " .
		"FROM " . PREFIX . "_xfsearch xf " .
		"INNER JOIN " . PREFIX . "_post p ON (p.id=xf.news_id) " .
		$cat_join .
		"WHERE {$stop_list}p.approve=1 AND xf.tagname='artistsong' AND xf.tagvalue<>''" .
		$where_date .
		" GROUP BY xf.tagvalue"
	);

	while ($row = $db->get_row()) {
		$val = trim((string)$row['tagvalue']);
		if ($val === '') continue;

		$cnt = (int)$row['cnt'];
		if ($cnt < 1) $cnt = 1;

		// If xfsearch stores multi-artist strings, counts will be wrong; fall back.
		if ($has_multi_artist_separators($val)) {
			$need_fallback_counts = true;
			foreach ($split_artists($val) as $p) {
				$key = $normalize_artist_key($p);
				if ($key === '') continue;
				if (!isset($artists_display[$key])) $artists_display[$key] = $p;
			}
			continue;
		}

		$key = $normalize_artist_key($val);
		if ($key === '') continue;
		if (!isset($artists_display[$key])) $artists_display[$key] = $val;
		if (!isset($artists_counts[$key])) $artists_counts[$key] = 0;
		$artists_counts[$key] += $cnt;
	}
	$db->free();

	// Fallback: scan xfields and split artists correctly (accurate)
	if (!count($artists_counts) OR $need_fallback_counts) {
		DLEXFields::Init();
		$artists_display = array();
		$artists_counts = array();

		$db->query(
			"SELECT p.id, p.xfields FROM " . PREFIX . "_post p " .
			$cat_join .
			"WHERE {$stop_list}p.approve=1 AND p.xfields<>'' AND p.xfields LIKE '%artistsong|%'" .
			$where_date
		);
		while ($row = $db->get_row()) {
			$xfieldsdata = DLEXFields::xfieldsdataload($row['xfields']);
			if (!isset($xfieldsdata['artistsong']) OR $xfieldsdata['artistsong'] === '') continue;
			$val = trim((string)$xfieldsdata['artistsong']);
			if ($val === '') continue;

			$per_post = array();
			foreach ($split_artists($val) as $p) {
				$key = $normalize_artist_key($p);
				if ($key === '') continue;
				$per_post[$key] = $p;
			}

			if (!count($per_post)) continue;

			foreach ($per_post as $key => $display) {
				if (!isset($artists_display[$key])) $artists_display[$key] = $display;
				if (!isset($artists_counts[$key])) $artists_counts[$key] = 0;
				$artists_counts[$key] += 1;
			}
		}
		$db->free();
	}

	foreach ($artists_display as $key => $display) {
		$artists_items[] = array(
			'name' => $display,
			'count' => isset($artists_counts[$key]) ? (int)$artists_counts[$key] : 0,
		);
	}

	usort($artists_items, function($a, $b) {
		$ac = isset($a['count']) ? (int)$a['count'] : 0;
		$bc = isset($b['count']) ? (int)$b['count'] : 0;
		if ($ac !== $bc) return ($bc <=> $ac);
		return strnatcasecmp((string)($a['name'] ?? ''), (string)($b['name'] ?? ''));
	});

	// Do not persist empty cache: it blocks the list after new content appears.
	if (count($artists_items)) {
		create_cache('artists_index', json_encode($artists_items, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), $cache_key);
	}
}

$metatags['title'] = 'Artists &raquo; ' . $metatags['title'];

// Page-specific SEO (avoid falling back to global home meta description/keywords)
// Keep this plain-text (no HTML tags).
$metatags['description'] = 'Descoperă toți artiștii disponibili pe site. Alege un artist ca să vezi piesele și să le asculți în playerul global.';
$metatags['keywords'] = 'artisti, artisti muzica, melodii, piese, mp3, asculta muzica';

$per_page = 60;
$page = isset($_GET['cstart']) ? intval($_GET['cstart']) : 1;
if ($page < 1) $page = 1;

$total = count($artists_items);
$total_pages = $total ? (int)ceil($total / $per_page) : 1;
if ($page > $total_pages) $page = $total_pages;

$offset = ($page - 1) * $per_page;
$artists_page = array_slice($artists_items, $offset, $per_page);

$items_html = '';
if (!$total) {
	$items_html = '<li class="artists-item artists-item--empty">No artists found yet.</li>';
}
foreach ($artists_page as $item) {
	$name = isset($item['name']) ? (string)$item['name'] : '';
	$count = isset($item['count']) ? (int)$item['count'] : 0;
	if ($name === '') continue;
	if ($count < 0) $count = 0;

	$href = $config['http_home_url'] . 'index.php?do=artists&name=' . urlencode($name);
	$items_html .= '<li><a class="artists-item" href="' . $href . '"><span class="artists-item__name">' . htmlspecialchars($name, ENT_QUOTES, 'UTF-8') . '</span><span class="artists-item__count">' . $count . ' tracks</span></a></li>';
}

// Build simple pagination compatible with zmusic navigation markup
$navigation = '';
if ($total_pages > 1) {
	$base = $config['http_home_url'] . 'index.php?do=artists&cstart=';

	$pages = '';
	$max_pages = ($tpl->smartphone) ? 5 : 10;

	if ($total_pages <= $max_pages) {
		for ($j = 1; $j <= $total_pages; $j++) {
			if ($j == $page) $pages .= "<span>{$j}</span> ";
			else $pages .= "<a href=\"{$base}{$j}\">{$j}</a> ";
		}
	} else {
		$start = 1;
		$end = $max_pages;

		if ($page > (int)floor($max_pages / 2)) {
			$start = $page - (int)floor($max_pages / 2);
			$end = $start + ($max_pages - 1);
			if ($end > $total_pages) {
				$end = $total_pages;
				$start = $end - ($max_pages - 1);
				if ($start < 1) $start = 1;
			}
		}

		if ($start > 1) {
			$pages .= "<a href=\"{$base}1\">1</a> <span class=\"nav_ext\">{$lang['nav_trennen']}</span> ";
		}

		for ($j = $start; $j <= $end; $j++) {
			if ($j == $page) $pages .= "<span>{$j}</span> ";
			else $pages .= "<a href=\"{$base}{$j}\">{$j}</a> ";
		}

		if ($end < $total_pages) {
			$pages .= "<span class=\"nav_ext\">{$lang['nav_trennen']}</span> <a href=\"{$base}{$total_pages}\">{$total_pages}</a>";
		}
	}

	$prev_link = ($page > 1) ? '<a href="' . $base . ($page - 1) . '"><i class="pagination__btn pagination__btn--prev fal fa-arrow-left"></i></a>' : '<span><i class="pagination__btn pagination__btn--prev fal fa-arrow-left"></i></span>';
	$next_link = ($page < $total_pages) ? '<a href="' . $base . ($page + 1) . '"><i class="pagination__btn pagination__btn--next fal fa-arrow-right"></i></a>' : '<span><i class="pagination__btn pagination__btn--next fal fa-arrow-right"></i></span>';

	$navigation = '<div class="pagination ignore-select d-flex jc-center" id="pagination"><div class="pagination__pages d-flex flex-1">' . $pages . '</div>' . $prev_link . $next_link . '</div>';
}

$tpl->load_template('artists.tpl');
$tpl->set('{artists}', $items_html);
$tpl->set('{navigation}', $navigation);
$tpl->compile('content');
$tpl->clear();

if ($is_change) $config['allow_cache'] = false;

?>
