<?php

$requested_action = '';
if (isset($_REQUEST['action'])) {
	$requested_action = (string)$_REQUEST['action'];
} elseif (isset($action)) {
	$requested_action = (string)$action;
}

if( !defined( 'DATALIFEENGINE' ) OR ( !defined( 'LOGGED_IN' ) AND $requested_action !== 'bulkupload' ) ) {
	header( "HTTP/1.1 403 Forbidden" );
	header ( 'Location: ../../' );
	die( "Hacking attempt!" );
}

if( $requested_action !== 'bulkupload' ) {
	if( !$user_group[$member_id['user_group']]['admin_addnews'] ) {
		msg( "error", $lang['index_denied'], $lang['index_denied'] );
	}
}

function dle_clean_track_title( $value ) {
	$value = trim((string)$value);
	if( $value === '' ) return '';

	$value = str_replace('_', ' ', $value);
	$value = preg_replace('/\s+/u', ' ', $value);
	$value = preg_replace('/^\s*\d+\s*[\.\-–—_]*\s*/u', '', $value);
	$value = trim($value);

	$dashMatch = null;
	if( preg_match('/^(.+?)\s*[-–—]\s*(.+)$/u', $value, $dashMatch) ) {
		$left = trim((string)$dashMatch[1]);
		$right = trim((string)$dashMatch[2]);
		$left = preg_replace('/[^\p{L}\s]+/u', ' ', $left);
		$right = preg_replace('/[^\p{L}\s]+/u', ' ', $right);
		$left = trim(preg_replace('/\s+/u', ' ', $left));
		$right = trim(preg_replace('/\s+/u', ' ', $right));
		if( $left && $right ) return $left . ' - ' . $right;
		return $left ?: $right;
	}

	$value = preg_replace('/[^\p{L}\s]+/u', ' ', $value);
	$value = trim(preg_replace('/\s+/u', ' ', $value));

	return $value;
}

function dle_clean_filename_part( $value ) {
	$value = trim((string)$value);
	if( $value === '' ) return '';

	$value = str_replace('_', ' ', $value);
	$value = preg_replace('/\s+/u', ' ', $value);
	$value = preg_replace('/^\s*\d+\s*[\.\-–—_]*\s*/u', '', $value);
	$value = preg_replace('/[^\p{L}\s]+/u', ' ', $value);
	$value = trim(preg_replace('/\s+/u', ' ', $value));

	return $value;
}

function dle_parse_track_from_filename( $filename ) {
	$filename = (string)$filename;
	$base = preg_replace('~^.*[\\\\/]~', '', $filename);
	$base = preg_replace('~\\.[^.]+$~', '', $base);
	$base = trim(preg_replace('/\s+/u', ' ', str_replace('_', ' ', $base)));

	$artist = '';
	$song = '';

	if( $base !== '' ) {
		$base = preg_replace('/^\s*\d+\s+/', '', $base);
		$base = preg_replace('/^\s*\d+\s*[\.\-–—_]+\s*/u', '', $base);
		$base = trim(preg_replace('/\s+/u', ' ', $base));

		if( preg_match('/\s[-–—]\s/u', $base) && preg_match('/^(.+?)\s*[-–—]\s*(.+)$/u', $base, $m) ) {
			$artist = dle_clean_filename_part($m[1]);
			$song = dle_clean_filename_part($m[2]);
		} elseif( preg_match('/[-–—]/u', $base) ) {
			$parts = preg_split('/[-–—]+/u', $base);
			$parts = array_values(array_filter(array_map('trim', $parts), function($v){ return $v !== ''; }));
			if( count($parts) >= 3 ) {
				$artist = dle_clean_filename_part($parts[0] . ' ' . $parts[1]);
				$song = dle_clean_filename_part(implode(' ', array_slice($parts, 2)));
			} elseif( count($parts) === 2 ) {
				$artist = dle_clean_filename_part($parts[0]);
				$song = dle_clean_filename_part($parts[1]);
			}
		}

		if( $song === '' ) {
			$song = dle_clean_filename_part($base);
		}
	}

	$postTitle = ($artist !== '' && $song !== '') ? ($artist . ' - ' . $song) : ($song !== '' ? $song : $base);

	return array(
		'artist' => $artist,
		'song' => $song,
		'post_title' => $postTitle
	);
}

function dle_addmp3_ensure_xfields() {
	$defaults = [
		'description' => '',
		'hint' => '',
		'category' => '',
		'allow_add_usergroups' => '',
		'allow_view_usergroups' => '',
		'storage' => -1,
		'type' => 'text',
		'default' => '',
		'not_required' => 1,
		'use_as_links' => 0,
		'use_editor' => 0,
		'safe_mode' => 0,
		'min' => '',
		'max' => '',
		'allow_multi' => 0,
		'select_separator' => '',
		'links_separator' => '',
		'image_sizes' => '',
		'image_size' => '',
		'image_max_size' => '',
		'make_watermark' => 0,
		'make_thumb' => 0,
		'thumb_size' => '',
		'max_images' => '',
		'use_opengraph' => '',
		'image_side' => '',
		'thumb_side' => '',
		'max_files' => '',
		'max_size' => '',
		'files_ext' => '',
		'file_max_size' => '',
		'is_public' => '',
		'condition' => '',
		'date_format' => '',
		'date_view_format' => '',
		'date_local' => '',
		'date_declension' => '',
		'group' => '',
		'allow_in_news' => 0,
		'lazy_load' => '',
	];

	DLEXFields::Init();

	$ensure = function(string $name, array $data) use ($defaults) {
		$current = DLEXFields::GETField($name);
		if (is_array($current) && count($current)) {
			return;
		}
		$data = array_merge($defaults, $data);
		$data['name'] = $name;
		DLEXFields::SaveField($name, $data);
	};

	$ensure('songname', [
		'description' => 'Song name',
		'type' => 'text',
		'not_required' => 0,
		'safe_mode' => 1,
	]);

	$ensure('artistsong', [
		'description' => 'Artist',
		'type' => 'text',
		'not_required' => 0,
		'safe_mode' => 1,
	]);

	$ensure('mp3', [
		'description' => 'MP3 file',
		'type' => 'audio',
		'not_required' => 0,
		'max_files' => 1,
		'max_size' => '',
	]);
}

dle_addmp3_ensure_xfields();

if( $action == "addmp3" ) {

	$duplicateprotection = UniqIDReal(32);

	$js_array[] = "public/js/sortable.js";
	$js_array[] = "public/fileuploader/plupload/plupload.full.min.js";
	$js_array[] = "public/fileuploader/plupload/i18n/{$lang['language_code']}.js";

	if($lang['direction'] == 'rtl') $rtl_prefix ='_rtl'; else $rtl_prefix = '';
	$css_array[] = "public/fileuploader/fileuploader{$rtl_prefix}.css";

	echoheader( "<i class=\"fa fa-music position-left\"></i><span class=\"text-semibold\">Add Mp3</span>", "Add Mp3" );

	$news_id = 0;
	$author = $member_id['name'];

	$xfields = DLEXFields::FieldsList();
	$xf_songname = $xfields['fields']['songname'] ?? '';
	$xf_artistsong = $xfields['fields']['artistsong'] ?? '';
	$xf_mp3 = $xfields['fields']['mp3'] ?? '';

	$categories_list = CategoryNewsSelection( 0, 0 );
	if( $config['allow_multi_category'] ) {
		$category_multiple = "class=\"categoryselect\" multiple";
		$category_size = " size=\"10\"";
	} else {
		$category_multiple = "class=\"uniform\" data-live-search=\"true\" data-none-results-text=\"{$lang['addnews_cat_fault']}\" data-width=\"350\"";
		$category_size = "";
	}

	$fix_input = ( $user_group[$member_id['user_group']]['allow_fixed'] AND $config['allow_fixed'] )
		? "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" id=\"news_fixed\" name=\"news_fixed\" value=\"1\">{$lang['addnews_fix']}</label></div>"
		: "";

	$main_input = $user_group[$member_id['user_group']]['allow_main']
		? "<div class=\"checkbox\" id=\"opt_holder_main\"><label><input class=\"icheck\" type=\"checkbox\" id=\"allow_main\" name=\"allow_main\" value=\"1\" checked>{$lang['addnews_main']}</label></div>"
		: "";

	if( $member_id['user_group'] < 3 ) {
		$disable_index = "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" id=\"disable_index\" name=\"disable_index\" value=\"1\">{$lang['add_disable_index']}</label></div>";
		$disable_search = "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" id=\"disable_search\" name=\"disable_search\" value=\"1\">{$lang['cat_d_search']}</label></div>";

		if( $config['allow_yandex_dzen'] ) {
			$yandex_dzen = "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" name=\"allow_rss_dzen\" id=\"allow_rss_dzen\" value=\"1\" checked>{$lang['allow_rss_dzen']}</label></div>";
		} else {
			$yandex_dzen = "";
		}

		if( $config['allow_rss'] ) {
			$rss_option = <<<HTML
				<div class="row mt-15" id="opt_cat_rss">
					<div class="col-sm-6" style="max-width:21.67em;">
						<div class="checkbox"><label><input class="icheck" type="checkbox" name="allow_rss" value="1" checked>{$lang['allow_rss_news']}</label></div>
					</div>
					<div class="col-sm-6">
						{$yandex_dzen}
					</div>
				</div>
HTML;
		} else {
			$rss_option = "";
		}
	} else {
		$disable_index = "";
		$disable_search = "";
		$rss_option = "";
	}

	echo <<<HTML
<div class="panel panel-default">
	<div class="panel-heading">
		<h6 class="panel-title">Add Mp3</h6>
	</div>
	<form method="post" name="addmp3" id="addmp3" onsubmit="if(checkxf()=='fail') return false;" class="form-horizontal">
		<div class="panel-body">
			<div class="form-group">
				<label class="control-label col-sm-2">{$lang['edit_et']}</label>
				<div class="col-sm-10">
					<input type="text" dir="auto" class="form-control width-550" name="title" id="title" maxlength="250">
				</div>
			</div>
			<div class="form-group">
				<label class="control-label col-sm-2">{$lang['addnews_cat']}</label>
				<div class="col-sm-10">
					<select data-placeholder="{$lang['addnews_cat_sel']}" title="{$lang['addnews_cat_sel']}" name="category[]" id="category" {$category_multiple}{$category_size} style="width:100%;max-width:24.3em;">{$categories_list}</select>
				</div>
			</div>
			{$xf_songname}
			{$xf_artistsong}
			{$xf_mp3}
			<div class="form-group">
				<label class="control-label col-sm-2">{$lang['addnews_full']}</label>
				<div class="col-sm-10">
					<textarea dir="auto" class="classic" style="width:100%;height: 16.25rem;" name="full_story" id="full_story"></textarea>
				</div>
			</div>
			<div class="form-group">
				<label class="control-label col-sm-2">{$lang['addnews_option']}</label>
				<div class="col-sm-10">
					<div class="row">
						<div class="col-sm-6" style="max-width:21.67em;">
							<div class="checkbox"><label><input class="icheck" type="checkbox" id="approve" name="approve" value="1" checked>{$lang['addnews_mod']}</label></div>
							{$main_input}
							<div class="checkbox" id="opt_holder_rating"><label><input class="icheck" type="checkbox" id="allow_rating" name="allow_rating" value="1" checked>{$lang['addnews_allow_rate']}</label></div>
						</div>
						<div class="col-sm-6">
							<div class="checkbox" id="opt_holder_comments"><label><input class="icheck" type="checkbox" id="allow_comm" name="allow_comm" value="1" checked>{$lang['addnews_comm']}</label></div>
							{$fix_input}
							{$disable_index}
							{$disable_search}
						</div>
					</div>
					{$rss_option}
				</div>
			</div>
		</div>
		<div class="panel-footer">
			<button type="submit" class="btn bg-teal btn-sm btn-raised position-left"><i class="fa fa-floppy-o position-left"></i>{$lang['news_add']}</button>
			<input type="hidden" name="mod" value="addmp3">
			<input type="hidden" name="action" value="doaddmp3">
			<input type="hidden" name="duplicateprotection" value="{$duplicateprotection}">
			<input type="hidden" name="user_hash" value="{$dle_login_hash}">
		</div>
	</form>
</div>
<script>
<!--
{$xfields['js_functions']}
jQuery(function($){
	{$xfields['js_scripts']}
	if ($('#category').hasClass('categoryselect') && typeof $.fn.chosen !== 'undefined') {
		$('.categoryselect').chosen({no_results_text: '{$lang['addnews_cat_fault']}'});
	}
});
// -->
</script>
HTML;

	echofooter();
}

elseif( $action == "addbulkmp3" ) {

	$duplicateprotection = UniqIDReal(32);

	$js_array[] = "public/js/sortable.js";
	$js_array[] = "public/fileuploader/plupload/plupload.full.min.js";
	$js_array[] = "public/fileuploader/plupload/i18n/{$lang['language_code']}.js";

	if($lang['direction'] == 'rtl') $rtl_prefix ='_rtl'; else $rtl_prefix = '';
	$css_array[] = "public/fileuploader/fileuploader{$rtl_prefix}.css";

	echoheader( "<i class=\"fa fa-music position-left\"></i><span class=\"text-semibold\">Bulk Upload Mp3</span>", "Bulk Upload Mp3" );

	$author = $member_id['name'];

	$ftp_user_folder = totranslit($member_id['name'], true, false, $config['translit_url']);
	$ftp_user_folder = trim($ftp_user_folder);
	if( !$ftp_user_folder ) $ftp_user_folder = "user_" . intval($member_id['user_id']);
	$ftp_rel_folder = 'public_files/bulkzip/' . $ftp_user_folder . '/';
	$ftp_abs_folder = ROOT_DIR . '/uploads/' . $ftp_rel_folder;
	if( !is_dir($ftp_abs_folder) ) {
		@mkdir($ftp_abs_folder, 0777, true);
		@chmod($ftp_abs_folder, 0777);
		@file_put_contents($ftp_abs_folder . 'index.html', '<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title> </title></head><body></body></html>');
		@chmod($ftp_abs_folder . 'index.html', 0666);
	}

	$categories_list = CategoryNewsSelection( 0, 0 );
	if( $config['allow_multi_category'] ) {
		$category_multiple = "class=\"categoryselect\" multiple";
		$category_size = " size=\"10\"";
	} else {
		$category_multiple = "class=\"uniform\" data-live-search=\"true\" data-none-results-text=\"{$lang['addnews_cat_fault']}\" data-width=\"350\"";
		$category_size = "";
	}

	$fix_input = ( $user_group[$member_id['user_group']]['allow_fixed'] AND $config['allow_fixed'] )
		? "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" id=\"news_fixed\" name=\"news_fixed\" value=\"1\">{$lang['addnews_fix']}</label></div>"
		: "";

	$main_input = $user_group[$member_id['user_group']]['allow_main']
		? "<div class=\"checkbox\" id=\"opt_holder_main\"><label><input class=\"icheck\" type=\"checkbox\" id=\"allow_main\" name=\"allow_main\" value=\"1\" checked>{$lang['addnews_main']}</label></div>"
		: "";

	if( $member_id['user_group'] < 3 ) {
		$disable_index = "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" id=\"disable_index\" name=\"disable_index\" value=\"1\">{$lang['add_disable_index']}</label></div>";
		$disable_search = "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" id=\"disable_search\" name=\"disable_search\" value=\"1\">{$lang['cat_d_search']}</label></div>";

		if( $config['allow_yandex_dzen'] ) {
			$yandex_dzen = "<div class=\"checkbox\"><label><input class=\"icheck\" type=\"checkbox\" name=\"allow_rss_dzen\" id=\"allow_rss_dzen\" value=\"1\" checked>{$lang['allow_rss_dzen']}</label></div>";
		} else {
			$yandex_dzen = "";
		}

		if( $config['allow_rss'] ) {
			$rss_option = <<<HTML
				<div class="row mt-15" id="opt_cat_rss">
					<div class="col-sm-6" style="max-width:21.67em;">
						<div class="checkbox"><label><input class="icheck" type="checkbox" name="allow_rss" value="1" checked>{$lang['allow_rss_news']}</label></div>
					</div>
					<div class="col-sm-6">
						{$yandex_dzen}
					</div>
				</div>
HTML;
		} else {
			$rss_option = "";
		}
	} else {
		$disable_index = "";
		$disable_search = "";
		$rss_option = "";
	}

	echo <<<HTML
<div class="panel panel-default">
	<div class="panel-heading">
		<h6 class="panel-title">Bulk Upload Mp3</h6>
	</div>
	<form method="post" name="addbulkmp3" id="addbulkmp3" class="form-horizontal">
		<div class="panel-body">
			<div class="form-group">
				<label class="control-label col-sm-2">{$lang['addnews_cat']}</label>
				<div class="col-sm-10">
					<select data-placeholder="{$lang['addnews_cat_sel']}" title="{$lang['addnews_cat_sel']}" name="category[]" id="category" {$category_multiple}{$category_size} style="width:100%;max-width:24.3em;">{$categories_list}</select>
				</div>
			</div>
			<div class="form-group">
				<label class="control-label col-sm-2">{$lang['addnews_option']}</label>
				<div class="col-sm-10">
					<div class="row">
						<div class="col-sm-6" style="max-width:21.67em;">
							<div class="checkbox"><label><input class="icheck" type="checkbox" id="approve" name="approve" value="1" checked>{$lang['addnews_mod']}</label></div>
							{$main_input}
							<div class="checkbox" id="opt_holder_rating"><label><input class="icheck" type="checkbox" id="allow_rating" name="allow_rating" value="1" checked>{$lang['addnews_allow_rate']}</label></div>
						</div>
						<div class="col-sm-6">
							<div class="checkbox" id="opt_holder_comments"><label><input class="icheck" type="checkbox" id="allow_comm" name="allow_comm" value="1" checked>{$lang['addnews_comm']}</label></div>
							{$fix_input}
							{$disable_index}
							{$disable_search}
							<div class="checkbox"><label><input class="icheck" type="checkbox" id="delete_zip" name="delete_zip" value="1" checked>Delete ZIP after unzip</label></div>
						</div>
					</div>
					{$rss_option}
				</div>
			</div>

			<div class="form-group">
				<label class="control-label col-sm-2">Files</label>
				<div class="col-sm-10">
					<div class="alert alert-info" style="margin-bottom:12px;">
						<b>FTP ZIP inbox</b><br>
						Upload ZIP via FTP to: <span class="text-semibold">uploads/public_files/bulkzip/{$ftp_user_folder}</span><br>
						Then click <b>Refresh</b> and <b>Register &amp; Extract</b> below.
					</div>
					<div class="well" style="padding:10px;margin-bottom:12px;">
						<div class="row" style="margin-left:-5px;margin-right:-5px;">
							<div class="col-sm-6" style="padding-left:5px;padding-right:5px;">
								<select class="form-control" id="bulk_ftp_zip_select"></select>
							</div>
							<div class="col-sm-6" style="padding-left:5px;padding-right:5px;">
								<button type="button" class="btn btn-sm bg-slate" id="bulk_ftp_zip_refresh"><i class="fa fa-refresh position-left"></i>Refresh</button>
								<button type="button" class="btn btn-sm bg-teal" id="bulk_ftp_zip_register"><i class="fa fa-cloud-download position-left"></i>Register &amp; Extract</button>
							</div>
						</div>
						<div id="bulk_ftp_zip_status" class="text-muted" style="margin-top:8px;"></div>
					</div>

					<div id="bulk_uploader" class="xfieldsfile_uploader">
						<button type="button" class="qq-upload-button btn btn-sm bg-teal btn-raised" id="bulk_upload_button"><i class="fa fa-upload position-left"></i>Select files</button>
						<div class="qq-upload-drop-area drop-area-absolute" id="bulk_drop_area"><span>Drop files here</span></div>
						<div class="xfieldsfile_uploader_message" id="bulk_status" style="margin-top:10px;display:none;"></div>
						<div class="xfieldsfile_uploader_list" id="bulk_filelist" style="margin-top:10px;"></div>
					</div>
				</div>
			</div>

			<div class="form-group">
				<label class="control-label col-sm-2">Tracks</label>
				<div class="col-sm-10">
					<div class="table-responsive">
						<table class="table table-striped table-xs" id="bulk_tracks_table">
							<thead>
								<tr>
									<th style="width:38px;"></th>
									<th>File</th>
									<th style="width:220px;">Artist</th>
									<th style="width:260px;">Title</th>
									<th style="width:320px;">Post title</th>
									<th style="width:90px;"></th>
								</tr>
							</thead>
							<tbody></tbody>
						</table>
					</div>
					<div id="bulk_tracks_empty" class="text-muted" style="padding:8px 0;">No tracks uploaded yet.</div>
				</div>
			</div>
		</div>
		<div class="panel-footer">
			<button type="submit" class="btn bg-teal btn-sm btn-raised position-left"><i class="fa fa-floppy-o position-left"></i>Create posts</button>
			<input type="hidden" name="mod" value="addmp3">
			<input type="hidden" name="action" value="doaddbulkmp3">
			<input type="hidden" name="duplicateprotection" value="{$duplicateprotection}">
			<input type="hidden" name="user_hash" value="{$dle_login_hash}">
		</div>
	</form>
</div>
<script>
<!--
jQuery(function($){
(function(){
	var userHash = "{$dle_login_hash}";
	var userId = "{$member_id['user_id']}";
	var author = "{$author}";
	var uploadUrl = "admin.php?mod=addmp3&action=bulkupload";
	var ftpListUrl = "admin.php?mod=addmp3&action=bulkftpziplist";
	var ftpRegisterUrl = "admin.php?mod=addmp3&action=bulkftpzipregister";
	var trackIndex = 0;

	var hasUnicodeProps = false;
	try { new RegExp("\\\\p{L}", "u"); hasUnicodeProps = true; } catch (e) { hasUnicodeProps = false; }

	function keepLettersSpaces(value) {
		value = (value || '').toString();
		if (hasUnicodeProps) {
			return value.replace(/[^\p{L}\s]+/gu, ' ');
		}
		return value.replace(/[^A-Za-zĂÂÎȘŞȚŢăâîșşțţ\s]+/g, ' ');
	}

	function cleanPart(value) {
		value = (value || '').toString();
		value = value.replace(/_+/g, ' ').replace(/\s+/g, ' ').trim();
		value = value.replace(/^\s*\d+\s*[\.\-–—_]*\s*/g, '');
		value = keepLettersSpaces(value);
		value = value.replace(/\s+/g, ' ').trim();
		return value;
	}

	function parseFromFilename(filename) {
		filename = (filename || '').toString();
		var base = filename.replace(/^.*[\\\/]/, '').replace(/\.[^.]+$/, '');
		base = base.replace(/_+/g, ' ').replace(/\s+/g, ' ').trim();
		if (!base) return { artist: '', song: '', postTitle: '' };

		base = base.replace(/^\s*\d+\s+/, '').replace(/^\s*\d+\s*[\.\-–—_]+\s*/g, '').trim();
		var artist = '';
		var song = '';
		var hasSpacedDash = /\s[-–—]\s/.test(base);
		if (hasSpacedDash) {
			var match = base.match(/^(.+?)\s*[-–—]\s*(.+)$/);
			if (match) {
				artist = cleanPart(match[1]);
				song = cleanPart(match[2]);
			}
		} else if (/[-–—]/.test(base)) {
			var parts = base.split(/[-–—]+/).map(function(s) { return s.trim(); }).filter(Boolean);
			if (parts.length >= 3) {
				artist = cleanPart(parts[0] + ' ' + parts[1]);
				song = cleanPart(parts.slice(2).join(' '));
			} else if (parts.length === 2) {
				artist = cleanPart(parts[0]);
				song = cleanPart(parts[1]);
			}
		}
		if (!song) song = cleanPart(base);

		var postTitle = (artist && song) ? (artist + ' - ' + song) : (song || base);
		return { artist: artist, song: song, postTitle: postTitle };
	}

	function addTrackRow(track) {
		var tbody = document.querySelector('#bulk_tracks_table tbody');
		var emptyEl = document.getElementById('bulk_tracks_empty');
		if (emptyEl) emptyEl.style.display = 'none';

		var parsed = parseFromFilename(track.original || track.file || '');
		var artist = track.artist || parsed.artist || '';
		var song = track.song || parsed.song || '';
		var postTitle = track.title || parsed.postTitle || '';

		var tr = document.createElement('tr');
		tr.setAttribute('data-track-index', String(trackIndex));

		var tdCheck = document.createElement('td');
		tdCheck.innerHTML = '<input type="checkbox" class="icheck" checked>';
		tr.appendChild(tdCheck);

		var tdFile = document.createElement('td');
		tdFile.textContent = (track.original || track.file || '').toString();
		tr.appendChild(tdFile);

		var tdArtist = document.createElement('td');
		tdArtist.innerHTML = '<input type="text" class="form-control input-sm" name="tracks['+trackIndex+'][artistsong]" value="'+escapeHtml(artist)+'">';
		tr.appendChild(tdArtist);

		var tdSong = document.createElement('td');
		tdSong.innerHTML = '<input type="text" class="form-control input-sm" name="tracks['+trackIndex+'][songname]" value="'+escapeHtml(song)+'">';
		tr.appendChild(tdSong);

		var tdTitle = document.createElement('td');
		tdTitle.innerHTML = '<input type="text" class="form-control input-sm" name="tracks['+trackIndex+'][title]" value="'+escapeHtml(postTitle)+'">';
		tr.appendChild(tdTitle);

		var tdActions = document.createElement('td');
		tdActions.innerHTML = '<button type="button" class="btn btn-xs bg-danger">Remove</button>';
		tr.appendChild(tdActions);

		var hidden = document.createElement('div');
		hidden.className = 'bulk-hidden';
		hidden.style.display = 'none';
		hidden.innerHTML =
			'<input type="hidden" name="tracks['+trackIndex+'][xfvalue]" value="'+escapeHtml(track.xfvalue || '')+'">' +
			'<input type="hidden" name="tracks['+trackIndex+'][original]" value="'+escapeHtml(track.original || track.file || '')+'">';
		tdActions.appendChild(hidden);

		tbody.appendChild(tr);

		tdActions.querySelector('button').addEventListener('click', function() {
			removeTrackRow(tr);
		});

		trackIndex++;
	}

	function escapeHtml(s) {
		return (s || '').toString()
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;')
			.replace(/'/g, '&#039;');
	}

	function removeTrackRow(tr) {
		var xfvalueInput = tr.querySelector('input[type="hidden"][name$="[xfvalue]"]');
		var xfvalue = xfvalueInput ? (xfvalueInput.value || '') : '';
		var parts = xfvalue.split('|');
		var fileId = parts.length >= 2 ? parts[1] : '';

		tr.parentNode.removeChild(tr);
		if (!document.querySelector('#bulk_tracks_table tbody tr')) {
			var emptyEl = document.getElementById('bulk_tracks_empty');
			if (emptyEl) emptyEl.style.display = '';
		}

		fileId = (fileId || '').toString().trim();
		if (!fileId) return;

		var formData = new FormData();
		formData.append('subaction', 'deluploads');
		formData.append('user_hash', userHash);
		formData.append('news_id', '0');
		formData.append('author', author);
		formData.append('files[]', fileId);

		try {
			fetch("index.php?controller=ajax&mod=upload", { method: 'POST', body: formData, credentials: 'same-origin' });
		} catch (e) {}
	}

	function setStatus(text, isError) {
		var el = document.getElementById('bulk_status');
		if (!el) return;
		el.style.display = text ? '' : 'none';
		el.className = 'xfieldsfile_uploader_message ' + (isError ? 'text-danger' : 'text-success');
		el.textContent = text || '';
	}

	function setFtpStatus(text, isError) {
		var el = document.getElementById('bulk_ftp_zip_status');
		if (!el) return;
		el.className = isError ? 'text-danger' : 'text-muted';
		el.textContent = text || '';
	}

	function renderZipActions(box, zipId) {
		if (!box) return;
		var actions = box.querySelector('.bulk-zip-actions');
		if (!actions) {
			actions = document.createElement('div');
			actions.className = 'bulk-zip-actions';
			actions.style.marginTop = '8px';
			box.appendChild(actions);
		}

		actions.innerHTML =
			'<button type="button" class="btn btn-xs bg-teal" data-action="extract">Extract</button> ' +
			'<button type="button" class="btn btn-xs bg-danger" data-action="delete">Delete ZIP</button>';

		var extractBtn = actions.querySelector('button[data-action="extract"]');
		var deleteBtn = actions.querySelector('button[data-action="delete"]');

		if (extractBtn) {
			extractBtn.addEventListener('click', function() {
				setStatus('Extracting ZIP...', false);
				var fd = new FormData();
				fd.append('user_hash', userHash);
				fd.append('zip_id', String(zipId));
				fd.append('delete_zip', (document.getElementById('delete_zip') && document.getElementById('delete_zip').checked) ? '1' : '0');
				fetch('admin.php?mod=addmp3&action=bulkextract', { method: 'POST', body: fd, credentials: 'same-origin' })
					.then(function(r){ return r.text(); })
					.then(function(t){
						var j = null;
						try { j = JSON.parse(t); } catch (e) { j = null; }
						if (!j) { setStatus('Extract failed: invalid JSON response. ' + t.slice(0, 200), true); return; }
						if (j.error) { setStatus(j.error, true); return; }
						if (!j.success) { setStatus('Extract failed', true); return; }
						if (j.tracks && j.tracks.length) {
							for (var i = 0; i < j.tracks.length; i++) addTrackRow(j.tracks[i]);
							setStatus('ZIP extracted: ' + j.tracks.length + ' tracks', false);
						} else {
							setStatus('ZIP extracted but no supported audio files found (mp3/flac/aac/ogg).', true);
						}
						if (j.deleted_zip) {
							actions.innerHTML = '<span class="text-muted">ZIP deleted</span>';
						}
					});
			});
		}

		if (deleteBtn) {
			deleteBtn.addEventListener('click', function() {
				setStatus('Deleting ZIP...', false);
				var fd = new FormData();
				fd.append('user_hash', userHash);
				fd.append('zip_id', String(zipId));
				fetch('admin.php?mod=addmp3&action=bulkdeletezip', { method: 'POST', body: fd, credentials: 'same-origin' })
					.then(function(r){ return r.text(); })
					.then(function(t){
						var j = null;
						try { j = JSON.parse(t); } catch (e) { j = null; }
						if (!j) { setStatus('Delete failed: invalid JSON response. ' + t.slice(0, 200), true); return; }
						if (j.error) { setStatus(j.error, true); return; }
						if (!j.success) { setStatus('Delete failed', true); return; }
						actions.innerHTML = '<span class="text-muted">ZIP deleted</span>';
						setStatus('ZIP deleted from server.', false);
					});
			});
		}
	}

	function refreshFtpZipList() {
		setFtpStatus('Loading ZIP list...', false);
		var fd = new FormData();
		fd.append('user_hash', userHash);
		fetch(ftpListUrl, { method: 'POST', body: fd, credentials: 'same-origin' })
			.then(function(r){ return r.text(); })
			.then(function(t){
				var j = null;
				try { j = JSON.parse(t); } catch (e) { j = null; }
				if (!j) { setFtpStatus('List failed: invalid JSON response. ' + t.slice(0, 200), true); return; }
				if (j.error) { setFtpStatus(j.error, true); return; }
				if (!j.success) { setFtpStatus('List failed', true); return; }
				var sel = document.getElementById('bulk_ftp_zip_select');
				if (!sel) return;
				sel.innerHTML = '';
				var items = j.items || [];
				if (!items.length) {
					var opt = document.createElement('option');
					opt.value = '';
					opt.textContent = '(No ZIP files found)';
					sel.appendChild(opt);
					setFtpStatus('No ZIP files found in inbox.', false);
					return;
				}
				for (var i = 0; i < items.length; i++) {
					var it = items[i];
					var opt2 = document.createElement('option');
					opt2.value = String(it.name || '');
					opt2.textContent = String(it.name || '') + (it.size_h ? (' (' + it.size_h + ')') : '');
					sel.appendChild(opt2);
				}
				setFtpStatus('Found ' + items.length + ' ZIP file(s).', false);
			});
	}

	function registerAndExtractSelectedZip() {
		var sel = document.getElementById('bulk_ftp_zip_select');
		if (!sel) return;
		var name = (sel.value || '').toString().trim();
		if (!name || name === '(No ZIP files found)') {
			setFtpStatus('Select a ZIP first.', true);
			return;
		}
		setFtpStatus('Registering ZIP in DLE...', false);

		var fd = new FormData();
		fd.append('user_hash', userHash);
		fd.append('zip_name', name);
		fetch(ftpRegisterUrl, { method: 'POST', body: fd, credentials: 'same-origin' })
			.then(function(r){ return r.text(); })
			.then(function(t){
				var j = null;
				try { j = JSON.parse(t); } catch (e) { j = null; }
				if (!j) { setFtpStatus('Register failed: invalid JSON response. ' + t.slice(0, 200), true); return; }
				if (j.error) { setFtpStatus(j.error, true); return; }
				if (!j.success || !j.zip_id) { setFtpStatus('Register failed', true); return; }
				setFtpStatus('ZIP registered. Extracting...', false);

				// create a visual box in the same list
				var box = document.createElement('div');
				box.className = 'file-box';
				box.innerHTML = '<span class="qq-upload-file-status">FTP</span><span class="qq-upload-file">&nbsp;' + escapeHtml(name) + '</span>';
				var list = document.getElementById('bulk_filelist');
				if (list) list.appendChild(box);

				renderZipActions(box, j.zip_id);
				// auto-click extract
				var extractBtn = box.querySelector('.bulk-zip-actions button[data-action="extract"]');
				if (extractBtn) extractBtn.click();
			});
	}

	var uploader = new plupload.Uploader({
		runtimes : 'html5',
		file_data_name: "qqfile",
		browse_button: 'bulk_upload_button',
		container: document.getElementById('bulk_uploader'),
		drop_element: document.getElementById('bulk_drop_area'),
		url: uploadUrl,
		multipart_params: {
			"user_hash": userHash,
			"user_id": userId,
			"delete_zip": (document.getElementById('delete_zip') && document.getElementById('delete_zip').checked) ? "1" : "0"
		},
		chunk_size: '5mb',
		filters : {
			max_file_size : '2048mb',
			mime_types: [
				{title : "Files", extensions : "mp3,flac,aac,ogg,mp4,zip,jpg,jpeg,png,gif,webp,bmp,avif"}
			]
		},
		init: {
			BeforeUpload: function(up, file) {
				up.settings.multipart_params.delete_zip = (document.getElementById('delete_zip') && document.getElementById('delete_zip').checked) ? "1" : "0";
			},
			FilesAdded: function(up, files) {
				plupload.each(files, function(file) {
					var box = document.createElement('div');
					box.id = 'bulk-upload-' + file.id;
					box.className = 'file-box';
					box.innerHTML = '<span class="qq-upload-file-status">{$lang['media_upload_st6']}</span><span class="qq-upload-file">&nbsp;'+escapeHtml(file.name)+'</span>&nbsp;<span class="qq-status"><span class="qq-upload-spinner"></span> <span class="qq-upload-size"></span></span><div class="progress"><div class="progress-bar progress-blue" style="width: 0%"><span>0%</span></div></div>';
					document.getElementById('bulk_filelist').appendChild(box);
				});
				setStatus('', false);
				up.start();
				up.refresh();
			},
			UploadProgress: function(up, file) {
				var box = document.getElementById('bulk-upload-' + file.id);
				if (!box) return;
				var sizeEl = box.querySelector('.qq-upload-size');
				var bar = box.querySelector('.progress-bar');
				if (sizeEl) sizeEl.textContent = plupload.formatSize(file.loaded) + ' {$lang['media_upload_st8']} ' + plupload.formatSize(file.origSize);
				if (bar) {
					bar.style.width = file.percent + '%';
					var span = bar.querySelector('span');
					if (span) span.textContent = file.percent + '%';
				}
			},
			FileUploaded: function(up, file, result) {
				var box = document.getElementById('bulk-upload-' + file.id);
				if (box) {
					var statusEl = box.querySelector('.qq-status');
					if (statusEl) statusEl.innerHTML = '{$lang['media_upload_st9']}';
				}

				var response = null;
				try { response = JSON.parse(result.response); } catch (e) { response = null; }
				if (!response) {
					var raw = (result && result.response) ? String(result.response) : '';
					setStatus('Upload response is not valid JSON. Check server/PHP logs. ' + (raw ? ('Response: ' + raw.slice(0, 200)) : ''), true);
					return;
				}
				if (response.result && response.result === 'chunk uploaded') return;
				if (response.error) {
					setStatus(response.error, true);
					return;
				}
				if (!response.success) return;

				var fileNameLower = (file && file.name) ? String(file.name).toLowerCase() : '';
				var isZip = fileNameLower.endsWith('.zip') || response.type === 'zip';

				if (isZip && response.zip_id && box) {
					// ZIP uploaded. Let user trigger extraction explicitly.
					var actions = box.querySelector('.bulk-zip-actions');
					if (!actions) {
						actions = document.createElement('div');
						actions.className = 'bulk-zip-actions';
						actions.style.marginTop = '8px';
						box.appendChild(actions);
					}

					actions.innerHTML =
						'<button type="button" class="btn btn-xs bg-teal" data-action="extract">Extract</button> ' +
						'<button type="button" class="btn btn-xs bg-danger" data-action="delete">Delete ZIP</button>';

					var zipId = String(response.zip_id);
					var extractBtn = actions.querySelector('button[data-action="extract"]');
					var deleteBtn = actions.querySelector('button[data-action="delete"]');

					if (extractBtn) {
						extractBtn.addEventListener('click', function() {
							setStatus('Extracting ZIP...', false);
							var fd = new FormData();
							fd.append('user_hash', userHash);
							fd.append('zip_id', zipId);
							fd.append('delete_zip', (document.getElementById('delete_zip') && document.getElementById('delete_zip').checked) ? '1' : '0');
							fetch('admin.php?mod=addmp3&action=bulkextract', { method: 'POST', body: fd, credentials: 'same-origin' })
								.then(function(r){ return r.text(); })
								.then(function(t){
									var j = null;
									try { j = JSON.parse(t); } catch (e) { j = null; }
									if (!j) { setStatus('Extract failed: invalid JSON response. ' + t.slice(0, 200), true); return; }
									if (j.error) { setStatus(j.error, true); return; }
									if (!j.success) { setStatus('Extract failed', true); return; }
									if (j.tracks && j.tracks.length) {
										for (var i = 0; i < j.tracks.length; i++) addTrackRow(j.tracks[i]);
										setStatus('ZIP extracted: ' + j.tracks.length + ' tracks', false);
									} else {
										setStatus('ZIP extracted but no supported files found (mp3/flac/aac/ogg/mp4/jpg/jpeg/png/gif/webp/bmp/avif).', true);
									}
									if (j.deleted_zip) {
										actions.innerHTML = '<span class="text-muted">ZIP deleted</span>';
									}
								});
						});
					}

					if (deleteBtn) {
						deleteBtn.addEventListener('click', function() {
							setStatus('Deleting ZIP...', false);
							var fd = new FormData();
							fd.append('user_hash', userHash);
							fd.append('zip_id', zipId);
							fetch('admin.php?mod=addmp3&action=bulkdeletezip', { method: 'POST', body: fd, credentials: 'same-origin' })
								.then(function(r){ return r.text(); })
								.then(function(t){
									var j = null;
									try { j = JSON.parse(t); } catch (e) { j = null; }
									if (!j) { setStatus('Delete failed: invalid JSON response. ' + t.slice(0, 200), true); return; }
									if (j.error) { setStatus(j.error, true); return; }
									if (!j.success) { setStatus('Delete failed', true); return; }
									actions.innerHTML = '<span class="text-muted">ZIP deleted</span>';
									setStatus('ZIP deleted from server.', false);
								});
						});
					}

					setStatus('ZIP uploaded. Click Extract to list tracks.', false);
					return;
				}

				// Regular audio file: add as a track immediately
				if (response.xfvalue) {
					addTrackRow({ xfvalue: response.xfvalue, original: (file && file.name) ? file.name : '' });
				}
			},
			Error: function(up, err) {
				setStatus((err && err.message) ? err.message : 'Upload error', true);
			}
		}
	});

	uploader.init();

	var btnRefresh = document.getElementById('bulk_ftp_zip_refresh');
	if (btnRefresh) btnRefresh.addEventListener('click', refreshFtpZipList);
	var btnRegister = document.getElementById('bulk_ftp_zip_register');
	if (btnRegister) btnRegister.addEventListener('click', registerAndExtractSelectedZip);
	// initial load
	refreshFtpZipList();

	document.getElementById('addbulkmp3').addEventListener('submit', function(e) {
		var rows = document.querySelectorAll('#bulk_tracks_table tbody tr');
		if (!rows.length) {
			e.preventDefault();
			setStatus('Upload at least one track.', true);
			return false;
		}

		for (var i = 0; i < rows.length; i++) {
			var row = rows[i];
			var cb = row.querySelector('td input[type="checkbox"]');
			if (!cb) continue;
			var idx = row.getAttribute('data-track-index');
			var hidden = row.querySelector('div.bulk-hidden');
			if (hidden) {
				var skip = !cb.checked;
				var skipInput = hidden.querySelector('input[name="tracks['+idx+'][skip]"]');
				if (!skipInput) {
					skipInput = document.createElement('input');
					skipInput.type = 'hidden';
					skipInput.name = 'tracks['+idx+'][skip]';
					hidden.appendChild(skipInput);
				}
				skipInput.value = skip ? '1' : '0';
			}
		}
	});

	if ($('#category').hasClass('categoryselect') && typeof $.fn.chosen !== 'undefined') {
		$('.categoryselect').chosen({no_results_text: '{$lang['addnews_cat_fault']}'});
	}
})();
});
// -->
</script>
HTML;

	echofooter();
}

elseif( $action == "bulkupload" ) {

	@header('Content-Type: application/json; charset=utf-8');

	$user_hash = isset($_REQUEST['user_hash']) ? (string)$_REQUEST['user_hash'] : '';
	$auth_ok = false;

	if ( defined('LOGGED_IN') && LOGGED_IN ) {
		if( $user_hash AND isset($dle_login_hash) AND $user_hash === $dle_login_hash ) {
			$auth_ok = true;
		}
	} else {
		$user_id = isset($_REQUEST['user_id']) ? intval($_REQUEST['user_id']) : 0;
		if( $user_id > 0 AND $user_hash ) {
			$user_row = $db->super_query( "SELECT user_id, name, user_group, password, hash, logged_ip FROM " . USERPREFIX . "_users WHERE user_id='{$user_id}' LIMIT 1" );
			if( isset($user_row['user_id']) AND intval($user_row['user_id']) === $user_id ) {
				$expected = sha1( SECURE_AUTH_KEY . $user_row['user_id'] . sha1($user_row['password']) . $user_row['hash'] );
				$match = function_exists('hash_equals') ? hash_equals($expected, $user_hash) : ($expected === $user_hash);

				if( $match ) {
					if( $config['ip_control'] == '1' AND !check_netz( $user_row['logged_ip'], $_IP ) ) {
						$auth_ok = false;
					} else {
						if( !defined('LOGGED_IN') ) {
							define( 'LOGGED_IN', true );
						}
						$member_id = is_array($member_id) ? array_merge($member_id, $user_row) : $user_row;
						$dle_login_hash = $expected;
						$auth_ok = true;
					}
				}
			}
		}
	}

	if( !$auth_ok ) {
		die( json_encode(array('error' => $lang['sess_error'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	if( !$user_group[$member_id['user_group']]['admin_addnews'] ) {
		die( json_encode(array('error' => $lang['index_denied'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	include_once ENGINE_DIR . '/classes/uploads/upload.class.php';

	$temp_files_type = $user_group[$member_id['user_group']]['files_type'];
	$temp_allow_public = $user_group[$member_id['user_group']]['allow_public_file_upload'];
	$temp_allow_file_upload = $user_group[$member_id['user_group']]['allow_file_upload'];
	$temp_max_file_size = $user_group[$member_id['user_group']]['max_file_size'];

	$user_group[$member_id['user_group']]['files_type'] = 'mp3,flac,aac,ogg,mp4,zip,jpg,jpeg,png,gif,webp,bmp,avif';
	$user_group[$member_id['user_group']]['allow_public_file_upload'] = 1;
	$user_group[$member_id['user_group']]['allow_file_upload'] = 1;
	$user_group[$member_id['user_group']]['max_file_size'] = 0;
	$_REQUEST['public_file'] = 1;

	$uploader = new FileUploader('xfieldsaudio', 0, $member_id['name'], 0, 0, false, false, 0, 0, false, false);
	$result = $uploader->FileUpload();

	$user_group[$member_id['user_group']]['files_type'] = $temp_files_type;
	$user_group[$member_id['user_group']]['allow_public_file_upload'] = $temp_allow_public;
	$user_group[$member_id['user_group']]['allow_file_upload'] = $temp_allow_file_upload;
	$user_group[$member_id['user_group']]['max_file_size'] = $temp_max_file_size;

	$data = json_decode($result, true);
	if( !is_array($data) ) {
		die( json_encode(array('error' => $lang['upload_error_3'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	// Respect chunked uploads: do not post-process until final chunk
	if( isset($data['result']) AND $data['result'] === 'chunk uploaded' ) {
		die( $result );
	}

	if( isset($data['error']) ) {
		die( $result );
	}

	// Detect file type reliably (including chunked uploads)
	$xfvalue = isset($data['xfvalue']) ? (string)$data['xfvalue'] : '';
	$parts = explode('|', $xfvalue);
	$fileId = isset($parts[1]) ? intval($parts[1]) : 0;

	$originalName = '';
	if (isset($_FILES['qqfile']['name'])) {
		$originalName = (string)$_FILES['qqfile']['name'];
	}
	if( !$originalName && isset($_REQUEST['name']) ) {
		$originalName = (string)$_REQUEST['name'];
	}

	$fileExt = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
	$fileNameFromDb = '';
	if( $fileId ) {
		$rowInfo = $db->super_query( "SELECT id, name, onserver FROM " . PREFIX . "_files WHERE id='{$fileId}' LIMIT 1" );
		if( isset($rowInfo['id']) AND intval($rowInfo['id']) === $fileId ) {
			$fileNameFromDb = (string)$rowInfo['name'];
			$extDb = strtolower(pathinfo((string)$rowInfo['onserver'], PATHINFO_EXTENSION));
			if( !$extDb ) $extDb = strtolower(pathinfo((string)$rowInfo['name'], PATHINFO_EXTENSION));
			if( $extDb ) $fileExt = $extDb;
		}
	}

	// For ZIP we do not auto-extract here. Upload ZIP, then user clicks Extract.
	if( $fileExt === 'zip' ) {
		$data['zip_id'] = $fileId;
		$data['type'] = 'zip';
		$data['original'] = $fileNameFromDb ? $fileNameFromDb : $originalName;
		die( json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	die( $result );
}

elseif( $action == "bulkftpziplist" ) {

	@header('Content-Type: application/json; charset=utf-8');

	$user_hash = isset($_REQUEST['user_hash']) ? (string)$_REQUEST['user_hash'] : '';
	$auth_ok = false;

	if ( defined('LOGGED_IN') && LOGGED_IN ) {
		if( $user_hash AND isset($dle_login_hash) AND $user_hash === $dle_login_hash ) {
			$auth_ok = true;
		}
	}

	if( !$auth_ok ) {
		die( json_encode(array('error' => $lang['sess_error'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	if( !$user_group[$member_id['user_group']]['admin_addnews'] ) {
		die( json_encode(array('error' => $lang['index_denied'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$folderName = totranslit($member_id['name'], true, false, $config['translit_url']);
	$folderName = trim($folderName);
	if( !$folderName ) $folderName = "user_" . intval($member_id['user_id']);
	$relFolder = 'public_files/bulkzip/' . $folderName . '/';
	$absFolder = ROOT_DIR . '/uploads/' . $relFolder;

	if( !is_dir($absFolder) ) {
		@mkdir($absFolder, 0777, true);
		@chmod($absFolder, 0777);
	}

	$items = array();
	if( is_dir($absFolder) ) {
		$dh = @opendir($absFolder);
		if( $dh ) {
			while( false !== ($file = readdir($dh)) ) {
				if( $file === '.' OR $file === '..' ) continue;
				if( $file === 'index.html' ) continue;
				if( preg_match('/\\.zip$/i', $file) ) {
					$full = $absFolder . $file;
					if( is_file($full) ) {
						$size = @filesize($full);
						$items[] = array(
							'name' => $file,
							'size' => $size ? intval($size) : 0,
							'size_h' => $size ? formatsize($size) : '0',
							'mtime' => @filemtime($full) ?: 0
						);
					}
				}
			}
			@closedir($dh);
		}
	}

	// newest first
	usort($items, function($a, $b) {
		return intval($b['mtime']) <=> intval($a['mtime']);
	});

	die( json_encode(array(
		'success' => true,
		'folder' => $relFolder,
		'items' => $items
	), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
}

elseif( $action == "bulkftpzipregister" ) {

	@header('Content-Type: application/json; charset=utf-8');

	$user_hash = isset($_REQUEST['user_hash']) ? (string)$_REQUEST['user_hash'] : '';
	$zip_name = isset($_REQUEST['zip_name']) ? (string)$_REQUEST['zip_name'] : '';

	$auth_ok = false;
	if ( defined('LOGGED_IN') && LOGGED_IN ) {
		if( $user_hash AND isset($dle_login_hash) AND $user_hash === $dle_login_hash ) {
			$auth_ok = true;
		}
	}

	if( !$auth_ok ) {
		die( json_encode(array('error' => $lang['sess_error'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	if( !$user_group[$member_id['user_group']]['admin_addnews'] ) {
		die( json_encode(array('error' => $lang['index_denied'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$zip_name = trim(str_replace(array(chr(0), "\\\\", "/"), '', $zip_name));
	if( !$zip_name OR !preg_match('/\\.zip$/i', $zip_name) ) {
		die( json_encode(array('error' => 'Invalid ZIP name'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$folderName = totranslit($member_id['name'], true, false, $config['translit_url']);
	$folderName = trim($folderName);
	if( !$folderName ) $folderName = "user_" . intval($member_id['user_id']);
	$relFolder = 'public_files/bulkzip/' . $folderName . '/';
	$absFolder = ROOT_DIR . '/uploads/' . $relFolder;

	$absFile = $absFolder . $zip_name;
	if( !is_file($absFile) ) {
		die( json_encode(array('error' => 'ZIP not found in FTP inbox'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$onserver = 'bulkzip/' . $folderName . '/' . $zip_name;
	$onserver_sql = $db->safesql($onserver);

	$existing = $db->super_query( "SELECT id, author, news_id FROM " . PREFIX . "_files WHERE onserver='{$onserver_sql}' LIMIT 1" );
	if( isset($existing['id']) AND intval($existing['id']) ) {
		if( intval($existing['news_id']) !== 0 ) {
			die( json_encode(array('error' => 'ZIP already attached to a post'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
		}
		if( (string)$existing['author'] !== (string)$member_id['name'] ) {
			die( json_encode(array('error' => 'ZIP already registered by another user'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
		}
		die( json_encode(array('success' => true, 'zip_id' => intval($existing['id']) ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$sizeBytes = @filesize($absFile);
	if( !$sizeBytes ) $sizeBytes = 0;
	$md5 = @md5_file($absFile);
	if( !$md5 ) $md5 = '';
	$added_time = time();

	$db_file_name = str_replace(chr(0), '', strip_tags( html_entity_decode( $zip_name , ENT_QUOTES | ENT_HTML5, 'utf-8') ) );
	$db_file_name = preg_replace("/\s+/u", " ", $db_file_name);
	$db_file_name = $db->safesql( trim($db_file_name) );

	$db->query( "INSERT INTO " . PREFIX . "_files (news_id, name, onserver, author, date, size, checksum, driver, is_public) values ('0', '{$db_file_name}', '{$onserver_sql}', '".$db->safesql($member_id['name'])."', '{$added_time}', '".intval($sizeBytes)."', '".$db->safesql($md5)."', '0', '1')" );
	$newId = $db->insert_id();

	die( json_encode(array('success' => true, 'zip_id' => intval($newId)), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
}

elseif( $action == "bulkextract" ) {

	@header('Content-Type: application/json; charset=utf-8');

	$user_hash = isset($_REQUEST['user_hash']) ? (string)$_REQUEST['user_hash'] : '';
	$zipFileId = isset($_REQUEST['zip_id']) ? intval($_REQUEST['zip_id']) : 0;
	$deleteZip = isset($_REQUEST['delete_zip']) ? intval($_REQUEST['delete_zip']) : 0;

	if( !$zipFileId ) {
		die( json_encode(array('error' => 'ZIP id is required'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	if( !class_exists('ZipArchive') ) {
		die( json_encode(array('error' => 'PHP extension zip (ZipArchive) is not enabled on the server.'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$auth_ok = false;
	if ( defined('LOGGED_IN') && LOGGED_IN ) {
		if( $user_hash AND isset($dle_login_hash) AND $user_hash === $dle_login_hash ) {
			$auth_ok = true;
		}
	}

	if( !$auth_ok ) {
		die( json_encode(array('error' => $lang['sess_error'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	if( !$user_group[$member_id['user_group']]['admin_addnews'] ) {
		die( json_encode(array('error' => $lang['index_denied'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$row = $db->super_query( "SELECT id, name, onserver, driver, is_public, author, news_id FROM " . PREFIX . "_files WHERE id='{$zipFileId}' LIMIT 1" );

	if( !isset($row['id']) OR !$row['id'] OR $row['author'] != $member_id['name'] OR intval($row['news_id']) !== 0 ) {
		die( json_encode(array('error' => 'ZIP not found'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$zipPath = 'public_files/' . $row['onserver'];
	$driver = intval($row['driver']);
	DLEFiles::init($driver, $config['local_on_fail']);

	$tmpZip = tempnam(ENGINE_DIR . "/cache/system/", "DLEZIP");
	if( !$tmpZip ) {
		die( json_encode(array('error' => 'Unable to create temp file'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$stream = DLEFiles::ReadStream($zipPath, $driver);
	if( DLEFiles::$error OR !is_resource($stream) ) {
		@unlink($tmpZip);
		die( json_encode(array('error' => (DLEFiles::$error ?: 'Unable to read ZIP') ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$out = @fopen($tmpZip, 'wb');
	if( !$out ) {
		@fclose($stream);
		@unlink($tmpZip);
		die( json_encode(array('error' => 'Unable to write temp ZIP'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	while( !feof($stream) ) {
		$buf = fread($stream, 8192);
		if( $buf === false ) break;
		fwrite($out, $buf);
	}

	@fclose($stream);
	@fclose($out);

	$zip = new ZipArchive();
	$opened = $zip->open($tmpZip);
	if( $opened !== true ) {
		@unlink($tmpZip);
		die( json_encode(array('error' => 'Unable to open ZIP'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$allowedExt = array('mp3','flac','aac','ogg','mp4','jpg','jpeg','png','gif','webp','bmp','avif');
	$entries = [];
	$roots = [];
	for ($i=0; $i < $zip->numFiles; $i++) {
		$stat = $zip->statIndex($i);
		if( !isset($stat['name']) ) continue;
		$name = (string)$stat['name'];
		if( substr($name, -1) === '/' ) continue;
		$extEntry = strtolower(pathinfo($name, PATHINFO_EXTENSION));
		if( !in_array($extEntry, $allowedExt, true) ) continue;
		$entries[] = $name;
		$seg = explode('/', str_replace('\\', '/', $name));
		if( count($seg) > 1 && $seg[0] !== '' ) $roots[] = $seg[0];
	}

	$zipRoot = '';
	if( count($roots) ) {
		$unique = array_values(array_unique($roots));
		if( count($unique) === 1 ) $zipRoot = $unique[0] . '/';
	}

	$http_url = DLEFiles::GetBaseURL($driver);
	$tracks = [];
	$prefix = date("Y-m") . "/";

	foreach ($entries as $entryName) {
		$relative = str_replace('\\', '/', $entryName);
		if( $zipRoot && stripos($relative, $zipRoot) === 0 ) {
			$relative = substr($relative, strlen($zipRoot));
		}
		$relative = ltrim($relative, '/');

		$baseName = pathinfo($relative, PATHINFO_BASENAME);
		$dirName = pathinfo($relative, PATHINFO_DIRNAME);
		if( $dirName === '.' ) $dirName = '';

		$folder = '';
		$firstSegment = '';
		if( $dirName ) {
			$partsDir = explode('/', $dirName);
			$firstSegment = isset($partsDir[0]) ? trim((string)$partsDir[0]) : '';
		}

		if( $firstSegment && preg_match('/^\s*(\d{1,6})\b/', $firstSegment, $m) ) {
			$folder = $m[1];
		} elseif( preg_match('/^\s*(\d{1,6})\b/', $baseName, $m) ) {
			$folder = $m[1];
		} elseif( $firstSegment ) {
			$folder = totranslit($firstSegment, true, false, $config['translit_url']);
		}

		$folder = trim($folder);
		$subdir = $folder ? ($folder . "/") : "";

		$extFile = strtolower(pathinfo($baseName, PATHINFO_EXTENSION));
		$nameOnly = pathinfo($baseName, PATHINFO_FILENAME);
		$nameOnly = totranslit($nameOnly);
		$extFile = totranslit($extFile);
		if( !$extFile ) continue;
		if( dle_strlen($nameOnly) > 200 ) $nameOnly = dle_substr($nameOnly, 0, 200);
		if( !$nameOnly ) $nameOnly = time() . rand(1, 100);
		$finalName = $nameOnly . "." . $extFile;

		DLEFiles::CreateDirectory('public_files/' . $prefix . $subdir, $driver);

		$targetPath = 'public_files/' . $prefix . $subdir . $finalName;
		if( DLEFiles::FileExists($targetPath) ) {
			$finalName = UniqIDReal() . "_" . $finalName;
			$targetPath = 'public_files/' . $prefix . $subdir . $finalName;
		}

		$zstream = $zip->getStream($entryName);
		if( !is_resource($zstream) ) continue;

		DLEFiles::WriteStream($targetPath, $zstream, $driver);
		@fclose($zstream);

		if( DLEFiles::$error ) continue;

		$sizeBytes = DLEFiles::Size($targetPath, $driver);
		$md5 = DLEFiles::Checksum($targetPath, $driver);
		$added_time = time();

		$bads = array('<', '>', ':', '«', '|', '?', '*', '[', ']', ';', '|', '=', '\\', ',', '/', '#', '%', '"', '\'');
		$db_file_name = str_replace(chr(0), '', strip_tags( html_entity_decode( $baseName , ENT_QUOTES | ENT_HTML5, 'utf-8') ) );
		$db_file_name = str_ireplace($bads, '', $db_file_name);
		$db_file_name = preg_replace("/\s+/u", " ", $db_file_name);
		$db_file_name = $db->safesql( trim($db_file_name) );

		$onserver = $prefix . $subdir . $finalName;
		$db->query( "INSERT INTO " . PREFIX . "_files (news_id, name, onserver, author, date, size, checksum, driver, is_public) values ('0', '{$db_file_name}', '{$onserver}', '".$db->safesql($member_id['name'])."', '{$added_time}', '{$sizeBytes}', '".$db->safesql($md5)."', '{$driver}', '1')" );
		$newId = $db->insert_id();

		$tracks[] = array(
			'xfvalue' => $http_url . 'public_files/' . $onserver . '|' . $newId . '|' . formatsize($sizeBytes),
			'original' => $baseName
		);
	}

	$zip->close();
	@unlink($tmpZip);

	$deleted_zip = false;
	if( $deleteZip ) {
		DLEFiles::Delete($zipPath, $driver);
		$db->query("DELETE FROM " . PREFIX . "_files WHERE id='{$zipFileId}'");
		$deleted_zip = true;
	}

	die( json_encode(array('success' => true, 'type' => 'zip', 'tracks' => $tracks, 'deleted_zip' => $deleted_zip), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
}

elseif( $action == "bulkdeletezip" ) {

	@header('Content-Type: application/json; charset=utf-8');

	$user_hash = isset($_REQUEST['user_hash']) ? (string)$_REQUEST['user_hash'] : '';
	$zipFileId = isset($_REQUEST['zip_id']) ? intval($_REQUEST['zip_id']) : 0;

	if( !$zipFileId ) {
		die( json_encode(array('error' => 'ZIP id is required'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$auth_ok = false;
	if ( defined('LOGGED_IN') && LOGGED_IN ) {
		if( $user_hash AND isset($dle_login_hash) AND $user_hash === $dle_login_hash ) {
			$auth_ok = true;
		}
	}

	if( !$auth_ok ) {
		die( json_encode(array('error' => $lang['sess_error'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	if( !$user_group[$member_id['user_group']]['admin_addnews'] ) {
		die( json_encode(array('error' => $lang['index_denied'] ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$row = $db->super_query( "SELECT id, onserver, driver, author, news_id FROM " . PREFIX . "_files WHERE id='{$zipFileId}' LIMIT 1" );
	if( !isset($row['id']) OR !$row['id'] OR $row['author'] != $member_id['name'] OR intval($row['news_id']) !== 0 ) {
		die( json_encode(array('error' => 'ZIP not found'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
	}

	$zipPath = 'public_files/' . $row['onserver'];
	$driver = intval($row['driver']);
	DLEFiles::init($driver, $config['local_on_fail']);
	DLEFiles::Delete($zipPath, $driver);
	$db->query("DELETE FROM " . PREFIX . "_files WHERE id='{$zipFileId}'");

	die( json_encode(array('success' => true), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES ) );
}

elseif( $action == "doaddmp3" ) {

	if( !$_REQUEST['user_hash'] OR $_REQUEST['user_hash'] != $dle_login_hash ) {
		msg( "error", array('javascript:history.go(-1)' => 'Add Mp3', '' => $lang['addnews_error'] ), $lang['sess_error'], "javascript:history.go(-1)" );
	}

	if( !isset($_POST['duplicateprotection']) OR (isset($_SESSION['dp']['dp_'.md5($_POST['duplicateprotection'])]) AND $_SESSION['dp']['dp_'.md5($_POST['duplicateprotection'])] === true ) ) {
		msg( "error", array('javascript:history.go(-1)' => 'Add Mp3', '' => $lang['addnews_error'] ), $lang['duplicate_protect'], "javascript:history.go(-1)" );
	}

	@header('X-XSS-Protection: 0;');

	$parsed_fields = DLEXFields::Parse();

	if(DLEXFields::$error) {
		msg("error", "error", DLEXFields::$error, "javascript:history.go(-1)");
	}

	$filecontents = $parsed_fields['filecontents'];
	$xf_search_words = $parsed_fields['search_words'];
	$all_xf_content = $parsed_fields['all_xf_content'];
	unset($parsed_fields);

	$parse = new ParseFilter();

	$allow_comm = isset( $_POST['allow_comm'] ) ? intval( $_POST['allow_comm'] ) : 0;
	$approve = isset( $_POST['approve'] ) ? intval( $_POST['approve'] ) : 0;
	$allow_rating = isset( $_POST['allow_rating'] ) ? intval( $_POST['allow_rating'] ) : 0;
	$news_fixed = isset( $_POST['news_fixed'] ) ? intval( $_POST['news_fixed'] ) : 0;
	$disable_index = isset( $_POST['disable_index'] ) ? intval( $_POST['disable_index'] ) : 0;
	$disable_search = isset( $_POST['disable_search'] ) ? intval( $_POST['disable_search'] ) : 0;
	$need_pass = 0;
	$allow_rss = isset( $_POST['allow_rss'] ) ? intval( $_POST['allow_rss'] ) : 0;
	$allow_rss_dzen = isset( $_POST['allow_rss_dzen'] ) ? intval( $_POST['allow_rss_dzen'] ) : 0;
	$allowed_country = '';
	$not_allowed_country = '';
	$related_ids = '';
	$group_regel = '';

	$category = isset($_POST['category']) ? $_POST['category'] : array();
	if( !is_array($category) ) $category = array ();
	if( !count($category) ) $category[] = '0';

	$category_list = array();
	foreach ( $category as $value ) {
		$category_list[] = intval($value);
	}

	$allow_main = 0;
	if( $user_group[$member_id['user_group']]['allow_main'] ) {
		$allow_main = isset($_POST['allow_main']) ? intval($_POST['allow_main']) : 0;
	}

	if( !$config['allow_fixed'] OR !$user_group[$member_id['user_group']]['allow_fixed'] ) {
		$news_fixed = 0;
	}

	$disable_rss_dzen = 0;

	if( $member_id['user_group'] > 2 ) {
		$disable_index = 0;
		$disable_search = 0;
		$need_pass = 0;
		$allow_rss = 1;
		$allow_rss_dzen = 1;
		$allowed_country = '';
		$not_allowed_country = '';
	}

	if( !$config['allow_rss'] ) { $allow_rss = 1; }
	if( !$config['allow_yandex_dzen'] ) { $allow_rss_dzen = 0; }
	if( !$allow_rss ) { $allow_rss_dzen = 0; }

	if($member_id['cat_add']) $allow_list = explode( ',', $member_id['cat_add'] );
	else $allow_list = explode( ',', $user_group[$member_id['user_group']]['cat_add'] );

	$mail_send = false;

	if( $member_id['cat_allow_addnews']) $allow_list_add = explode( ',', $member_id['cat_allow_addnews'] );
	else $allow_list_add = explode( ',', $user_group[$member_id['user_group']]['cat_allow_addnews'] );

	foreach ( $category_list as $selected ) {
		if( $allow_list_add[0] != "all" AND !in_array( $selected, $allow_list_add ) ) {
			msg( "error", array('javascript:history.go(-1)' => 'Add Mp3', '' => $lang['addnews_error'] ), $lang['news_err_41'], "javascript:history.go(-1)" );
		}
		if(isset($cat_info[$selected]['disable_main']) AND $cat_info[$selected]['disable_main']) {
			$allow_main = 0;
		}
		if(isset($cat_info[$selected]['disable_comments']) AND $cat_info[$selected]['disable_comments']) {
			$allow_comm = 1;
		}
		if(isset($cat_info[$selected]['disable_rating']) AND $cat_info[$selected]['disable_rating']) {
			$allow_rating = 0;
		}

		if( $member_id['user_group'] > 2 ) {
			if( isset($cat_info[$selected]['enable_dzen']) AND !$cat_info[$selected]['enable_dzen'] ) {
				$disable_rss_dzen++;
			}
		}
		if( $allow_list[0] != "all" AND !in_array( $selected, $allow_list ) ) {
			$approve = 0;
			$mail_send = true;
		}
	}

	if( $member_id['user_group'] > 2 ) {
		if( $disable_rss_dzen > 0 AND $disable_rss_dzen == count($category_list) ) {
			$allow_rss_dzen = 0;
		}
	}

	$category_list = $db->safesql( implode( ',', $category_list ) );

	if( !$user_group[$member_id['user_group']]['moderation'] ) {
		$approve = 0;
		$mail_send = true;
	}

	$songname = isset($_POST['xfield']['songname']) ? trim((string)$_POST['xfield']['songname']) : '';
	$artistsong = isset($_POST['xfield']['artistsong']) ? trim((string)$_POST['xfield']['artistsong']) : '';

	$title_raw = isset($_POST['title']) ? trim((string)$_POST['title']) : '';
	if (!$title_raw) {
		$parts = [];
		if ($songname) $parts[] = $songname;
		if ($artistsong) $parts[] = $artistsong;
		$title_raw = implode(' - ', $parts);
	}
	$title_raw = dle_clean_track_title($title_raw);

	$title = $parse->process( trim( strip_tags ($title_raw) ) );

	$_POST['full_story'] = isset($_POST['full_story']) ? (string)$_POST['full_story'] : '';
	$parse->allow_code = false;
	$full_story = $parse->process( $_POST['full_story'] );
	$full_story = $db->safesql( $parse->BB_Parse( $full_story ) );
	$short_story = '';

	if( $parse->not_allowed_text ) {
		msg( "error", array('javascript:history.go(-1)' => 'Add Mp3', '' => $lang['addnews_error'] ), $lang['news_err_39'], "javascript:history.go(-1)" );
	}

	if( !$title ) {
		msg( "error", array('javascript:history.go(-1)' => 'Add Mp3', '' => $lang['addnews_error'] ), $lang['addnews_alert'], "javascript:history.go(-1)" );
	}

	if( dle_strlen( $title ) > 255 ) {
		msg( "error", array('javascript:history.go(-1)' => 'Add Mp3', '' => $lang['addnews_error'] ), $lang['addnews_ermax'], "javascript:history.go(-1)" );
	}

	$alt_name = totranslit( stripslashes( $title ), true, false, $config['translit_url'] );

	$title = $db->safesql( $title );
	$alt_name = $db->safesql( $alt_name );

	$catalog_url = $db->safesql( dle_substr( htmlspecialchars( strip_tags( stripslashes( trim( $_POST['catalog_url'] ?? '' ) ) ), ENT_QUOTES, 'UTF-8' ), 0, 3 ) );
	if ($config['create_catalog'] AND !$catalog_url) $catalog_url = $db->safesql( dle_substr( htmlspecialchars( strip_tags( stripslashes( $title ) ), ENT_QUOTES, 'UTF-8' ), 0, 1 ) );

	$added_time = time();
	$thistime = date( "Y-m-d H:i:s", $added_time );

	$author = $member_id['name'];
	$userid = $member_id['user_id'];

	if (dle_strlen($full_story) > 12) $all_xf_content = stripslashes($full_story) . ' ' . $all_xf_content;
	else $all_xf_content = $all_xf_content;

	$metatags = create_metatags($all_xf_content);

	$db->query( "INSERT INTO " . PREFIX . "_post (date, autor, short_story, full_story, xfields, title, descr, keywords, category, alt_name, allow_comm, approve, allow_main, fixed, allow_br, symbol, tags, metatitle) values ('{$thistime}', '{$author}', '{$short_story}', '{$full_story}', '{$filecontents}', '{$title}', '{$metatags['description']}', '{$metatags['keywords']}', '{$category_list}', '{$alt_name}', '{$allow_comm}', '{$approve}', '{$allow_main}', '{$news_fixed}', '0', '{$catalog_url}', '', '{$metatags['title']}')" );

	$id = $db->insert_id();

	$db->query( "INSERT INTO " . PREFIX . "_post_extras (news_id, allow_rate, votes, disable_index, related_ids, access, user_id, disable_search, need_pass, allow_rss, allow_rss_dzen, allowed_country, not_allowed_country) VALUES('{$id}', '{$allow_rating}', '0', '{$disable_index}', '{$related_ids}', '{$group_regel}', '{$userid}', '{$disable_search}', '{$need_pass}', '{$allow_rss}', '{$allow_rss_dzen}', '{$allowed_country}', '{$not_allowed_country}')" );

	if( $category_list AND $approve ) {

		$cat_ids = array ();

		$cat_ids_arr = explode( ",", $category_list );

		foreach ( $cat_ids_arr as $value ) {

			$cat_ids[] = "('" . $id . "', '" . trim( $value ) . "')";
		}

		$cat_ids = implode( ", ", $cat_ids );
		$db->query( "INSERT INTO " . PREFIX . "_post_extras_cats (news_id, cat_id) VALUES " . $cat_ids );

	}

	if ( count($xf_search_words) AND $approve ) {

		$temp_array = array();

		foreach ( $xf_search_words as $value ) {
			$temp_array[] = "('" . $id . "', '" . $value[0] . "', '" . $value[1] . "')";
		}

		$xf_search_words = implode( ", ", $temp_array );
		$db->query( "INSERT INTO " . PREFIX . "_xfsearch (news_id, tagname, tagvalue) VALUES " . $xf_search_words );
	}

	$db->query( "UPDATE " . PREFIX . "_images SET news_id='{$id}', author = '{$author}' WHERE author = '{$member_id['name']}' AND news_id = '0'" );
	$db->query( "UPDATE " . PREFIX . "_files SET news_id='{$id}', author = '{$author}' WHERE author = '{$member_id['name']}' AND news_id = '0'" );
	$db->query( "UPDATE " . USERPREFIX . "_users SET news_num=news_num+1 WHERE user_id='{$userid}'" );

	$db->query( "INSERT INTO " . USERPREFIX . "_admin_logs (name, date, ip, action, extras) values ('".$db->safesql($member_id['name'])."', '{$_TIME}', '{$_IP}', '1', '{$title}')" );

	clear_cache( array('news_', 'tagscloud_', 'archives_', 'calendar_', 'topnews_', 'rss', 'stats') );

	$_SESSION['dp']['dp_'.md5($_POST['duplicateprotection'])] = true;

	$row = $db->super_query( "SELECT id, date, category, alt_name FROM " . PREFIX . "_post WHERE id='{$id}' LIMIT 1" );
	$row['date'] = strtotime($row['date']);
	$full_link = DLEUrl::BuildUrl('showfull', ['category' => get_url($row['category']), 'year' => date('Y', $row['date']), 'month' => date('m', $row['date']), 'day' => date('d', $row['date']), 'news_name' => $row['alt_name'], 'newsid' => $row['id']]);

	msg( "success", $lang['addnews_ok'], $lang['addnews_ok_1'] . " \"" . stripslashes( stripslashes( $title ) ) . "\" " . $lang['addnews_ok_2'], array('?mod=addmp3&action=addmp3' => $lang['add_s_1'], '?mod=editnews&action=editnews&id='.$id => $lang['add_s_2'], '?mod=editnews&action=list' => $lang['add_s_3'], $full_link => $lang['add_s_5'] ) );
}

elseif( $action == "doaddbulkmp3" ) {

	if( !$_REQUEST['user_hash'] OR $_REQUEST['user_hash'] != $dle_login_hash ) {
		msg( "error", array('javascript:history.go(-1)' => 'Bulk Upload Mp3', '' => $lang['addnews_error'] ), $lang['sess_error'], "javascript:history.go(-1)" );
	}

	if( !isset($_POST['duplicateprotection']) OR (isset($_SESSION['dp']['dp_'.md5($_POST['duplicateprotection'])]) AND $_SESSION['dp']['dp_'.md5($_POST['duplicateprotection'])] === true ) ) {
		msg( "error", array('javascript:history.go(-1)' => 'Bulk Upload Mp3', '' => $lang['addnews_error'] ), $lang['duplicate_protect'], "javascript:history.go(-1)" );
	}

	@header('X-XSS-Protection: 0;');

	$parse = new ParseFilter();

	$allow_comm = isset( $_POST['allow_comm'] ) ? intval( $_POST['allow_comm'] ) : 0;
	$approve = isset( $_POST['approve'] ) ? intval( $_POST['approve'] ) : 0;
	$allow_rating = isset( $_POST['allow_rating'] ) ? intval( $_POST['allow_rating'] ) : 0;
	$news_fixed = isset( $_POST['news_fixed'] ) ? intval( $_POST['news_fixed'] ) : 0;
	$disable_index = isset( $_POST['disable_index'] ) ? intval( $_POST['disable_index'] ) : 0;
	$disable_search = isset( $_POST['disable_search'] ) ? intval( $_POST['disable_search'] ) : 0;
	$need_pass = 0;
	$allow_rss = isset( $_POST['allow_rss'] ) ? intval( $_POST['allow_rss'] ) : 0;
	$allow_rss_dzen = isset( $_POST['allow_rss_dzen'] ) ? intval( $_POST['allow_rss_dzen'] ) : 0;
	$allowed_country = '';
	$not_allowed_country = '';
	$related_ids = '';
	$group_regel = '';

	$category = isset($_POST['category']) ? $_POST['category'] : array();
	if( !is_array($category) ) $category = array ();
	if( !count($category) ) $category[] = '0';

	$category_list_arr = array();
	foreach ( $category as $value ) {
		$category_list_arr[] = intval($value);
	}

	$allow_main = 0;
	if( $user_group[$member_id['user_group']]['allow_main'] ) {
		$allow_main = isset($_POST['allow_main']) ? intval($_POST['allow_main']) : 0;
	}

	if( !$config['allow_fixed'] OR !$user_group[$member_id['user_group']]['allow_fixed'] ) {
		$news_fixed = 0;
	}

	$disable_rss_dzen = 0;

	if( $member_id['user_group'] > 2 ) {
		$disable_index = 0;
		$disable_search = 0;
		$need_pass = 0;
		$allow_rss = 1;
		$allow_rss_dzen = 1;
		$allowed_country = '';
		$not_allowed_country = '';
	}

	if( !$config['allow_rss'] ) { $allow_rss = 1; }
	if( !$config['allow_yandex_dzen'] ) { $allow_rss_dzen = 0; }
	if( !$allow_rss ) { $allow_rss_dzen = 0; }

	if($member_id['cat_add']) $allow_list = explode( ',', $member_id['cat_add'] );
	else $allow_list = explode( ',', $user_group[$member_id['user_group']]['cat_add'] );

	$mail_send = false;

	if( $member_id['cat_allow_addnews']) $allow_list_add = explode( ',', $member_id['cat_allow_addnews'] );
	else $allow_list_add = explode( ',', $user_group[$member_id['user_group']]['cat_allow_addnews'] );

	foreach ( $category_list_arr as $selected ) {
		if( $allow_list_add[0] != "all" AND !in_array( $selected, $allow_list_add ) ) {
			msg( "error", array('javascript:history.go(-1)' => 'Bulk Upload Mp3', '' => $lang['addnews_error'] ), $lang['news_err_41'], "javascript:history.go(-1)" );
		}
		if(isset($cat_info[$selected]['disable_main']) AND $cat_info[$selected]['disable_main']) {
			$allow_main = 0;
		}
		if(isset($cat_info[$selected]['disable_comments']) AND $cat_info[$selected]['disable_comments']) {
			$allow_comm = 1;
		}
		if(isset($cat_info[$selected]['disable_rating']) AND $cat_info[$selected]['disable_rating']) {
			$allow_rating = 0;
		}

		if( $member_id['user_group'] > 2 ) {
			if( isset($cat_info[$selected]['enable_dzen']) AND !$cat_info[$selected]['enable_dzen'] ) {
				$disable_rss_dzen++;
			}
		}
		if( $allow_list[0] != "all" AND !in_array( $selected, $allow_list ) ) {
			$approve = 0;
			$mail_send = true;
		}
	}

	if( $member_id['user_group'] > 2 ) {
		if( $disable_rss_dzen > 0 AND $disable_rss_dzen == count($category_list_arr) ) {
			$allow_rss_dzen = 0;
		}
	}

	$category_list = $db->safesql( implode( ',', $category_list_arr ) );

	if( !$user_group[$member_id['user_group']]['moderation'] ) {
		$approve = 0;
		$mail_send = true;
	}

	$tracks = isset($_POST['tracks']) && is_array($_POST['tracks']) ? $_POST['tracks'] : array();
	if( !count($tracks) ) {
		msg( "error", array('javascript:history.go(-1)' => 'Bulk Upload Mp3', '' => $lang['addnews_error'] ), "No tracks", "javascript:history.go(-1)" );
	}

	$author = $member_id['name'];
	$userid = $member_id['user_id'];
	$added_posts = 0;
	$added_time = time();
	$thistime = date( "Y-m-d H:i:s", $added_time );

	foreach ($tracks as $track) {

		if( isset($track['skip']) && intval($track['skip']) ) continue;

		$xfvalue = isset($track['xfvalue']) ? trim((string)$track['xfvalue']) : '';
		if( !$xfvalue ) continue;
		$parts = explode('|', $xfvalue);
		if( count($parts) < 3 ) continue;
		$fileId = intval($parts[1]);
		if( !$fileId ) continue;

		$fileRow = $db->super_query( "SELECT id, name, onserver, author, news_id FROM " . PREFIX . "_files WHERE id='{$fileId}' LIMIT 1" );
		if( !isset($fileRow['id']) OR !$fileRow['id'] OR $fileRow['author'] != $author OR intval($fileRow['news_id']) !== 0 ) {
			continue;
		}

		$songname = isset($track['songname']) ? trim((string)$track['songname']) : '';
		$artistsong = isset($track['artistsong']) ? trim((string)$track['artistsong']) : '';
		$title_raw = isset($track['title']) ? trim((string)$track['title']) : '';
		$original = isset($track['original']) ? trim((string)$track['original']) : '';

		if( $songname === '' || $artistsong === '' || $title_raw === '' ) {
			$parsed = dle_parse_track_from_filename($original ?: ($fileRow['name'] ?? ''));
			if( $artistsong === '' && $parsed['artist'] !== '' ) $artistsong = $parsed['artist'];
			if( $songname === '' && $parsed['song'] !== '' ) $songname = $parsed['song'];
			if( $title_raw === '' && $parsed['post_title'] !== '' ) $title_raw = $parsed['post_title'];
		}

		if( !$title_raw ) {
			$partsTitle = [];
			if ($artistsong) $partsTitle[] = $artistsong;
			if ($songname) $partsTitle[] = $songname;
			$title_raw = implode(' - ', $partsTitle);
		}

		if( !$title_raw && $original ) {
			$title_raw = $original;
		}

		$title_raw = dle_clean_track_title($title_raw);
		$title = $parse->process( trim( strip_tags ($title_raw) ) );
		if( !$title ) continue;
		if( dle_strlen( $title ) > 255 ) continue;

		$alt_name = totranslit( stripslashes( $title ), true, false, $config['translit_url'] );
		$title_db = $db->safesql( $title );
		$alt_name = $db->safesql( $alt_name );

		$catalog_url = $db->safesql( dle_substr( htmlspecialchars( strip_tags( stripslashes( trim( $_POST['catalog_url'] ?? '' ) ) ), ENT_QUOTES, 'UTF-8' ), 0, 3 ) );
		if ($config['create_catalog'] AND !$catalog_url) $catalog_url = $db->safesql( dle_substr( htmlspecialchars( strip_tags( stripslashes( trim( $title ) ) ), ENT_QUOTES, 'UTF-8' ), 0, 1 ) );

		$songnameVal = trim(htmlspecialchars(strip_tags(stripslashes($songname)), ENT_QUOTES, 'UTF-8'));
		$artistsongVal = trim(htmlspecialchars(strip_tags(stripslashes($artistsong)), ENT_QUOTES, 'UTF-8'));
		$mp3Val = trim(htmlspecialchars(strip_tags(stripslashes($xfvalue)), ENT_QUOTES, 'UTF-8'));

		$songnameVal = str_replace(array("{", "["), array("&#123;", "&#91;"), $songnameVal);
		$artistsongVal = str_replace(array("{", "["), array("&#123;", "&#91;"), $artistsongVal);
		$mp3Val = str_replace(array("{", "["), array("&#123;", "&#91;"), $mp3Val);

		$filecontentsParts = [];
		if( $songnameVal !== '' ) {
			$filecontentsParts[] = "songname|" . str_replace("|", "&#124;", str_replace("\n", "__NEWL__", str_replace("\r", "", $songnameVal)));
		}
		if( $artistsongVal !== '' ) {
			$filecontentsParts[] = "artistsong|" . str_replace("|", "&#124;", str_replace("\n", "__NEWL__", str_replace("\r", "", $artistsongVal)));
		}
		$filecontentsParts[] = "mp3|" . str_replace("|", "&#124;", str_replace("\n", "__NEWL__", str_replace("\r", "", $mp3Val)));
		$filecontents = $db->safesql( implode("||", $filecontentsParts) );

		$all_xf_content = trim($songnameVal . " " . $artistsongVal);
		$metatags = create_metatags($all_xf_content);

		$full_story = '';
		$short_story = '';

		$db->query( "INSERT INTO " . PREFIX . "_post (date, autor, short_story, full_story, xfields, title, descr, keywords, category, alt_name, allow_comm, approve, allow_main, fixed, allow_br, symbol, tags, metatitle) values ('{$thistime}', '{$author}', '{$short_story}', '{$full_story}', '{$filecontents}', '{$title_db}', '{$metatags['description']}', '{$metatags['keywords']}', '{$category_list}', '{$alt_name}', '{$allow_comm}', '{$approve}', '{$allow_main}', '{$news_fixed}', '0', '{$catalog_url}', '', '{$metatags['title']}')" );
		$id = $db->insert_id();
		if( !$id ) continue;

		$db->query( "INSERT INTO " . PREFIX . "_post_extras (news_id, allow_rate, votes, disable_index, related_ids, access, user_id, disable_search, need_pass, allow_rss, allow_rss_dzen, allowed_country, not_allowed_country) VALUES('{$id}', '{$allow_rating}', '0', '{$disable_index}', '{$related_ids}', '{$group_regel}', '{$userid}', '{$disable_search}', '{$need_pass}', '{$allow_rss}', '{$allow_rss_dzen}', '{$allowed_country}', '{$not_allowed_country}')" );

		if( $category_list AND $approve ) {
			$cat_ids = array ();
			$cat_ids_arr = explode( ",", $category_list );
			foreach ( $cat_ids_arr as $value ) {
				$cat_ids[] = "('" . $id . "', '" . trim( $value ) . "')";
			}
			if( count($cat_ids) ) {
				$db->query( "INSERT INTO " . PREFIX . "_post_extras_cats (news_id, cat_id) VALUES " . implode( ", ", $cat_ids ) );
			}
		}

		$db->query( "UPDATE " . PREFIX . "_files SET news_id='{$id}', author = '{$author}' WHERE id='{$fileId}' AND author = '{$author}' AND news_id = '0'" );

		$db->query( "INSERT INTO " . USERPREFIX . "_admin_logs (name, date, ip, action, extras) values ('".$db->safesql($member_id['name'])."', '{$_TIME}', '{$_IP}', '1', '{$title_db}')" );

		$added_posts++;
	}

	if( !$added_posts ) {
		msg( "error", array('javascript:history.go(-1)' => 'Bulk Upload Mp3', '' => $lang['addnews_error'] ), "No posts created", "javascript:history.go(-1)" );
	}

	$db->query( "UPDATE " . USERPREFIX . "_users SET news_num=news_num+{$added_posts} WHERE user_id='{$userid}'" );
	clear_cache( array('news_', 'tagscloud_', 'archives_', 'calendar_', 'topnews_', 'rss', 'stats') );
	$_SESSION['dp']['dp_'.md5($_POST['duplicateprotection'])] = true;

	msg( "success", $lang['addnews_ok'], "Created {$added_posts} posts.", array('?mod=addmp3&action=addbulkmp3' => 'Bulk Upload', '?mod=editnews&action=list' => $lang['add_s_3'] ) );
}

?>
