1<?php
2/////////////////////////////////////////////////////////////////
3/// getID3() by James Heinrich <info@getid3.org>               //
4//  available at https://github.com/JamesHeinrich/getID3       //
5//            or https://www.getid3.org                        //
6//            or http://getid3.sourceforge.net                 //
7//                                                             //
8// /demo/demo.mysqli.php - part of getID3()                    //
9// Sample script for recursively scanning directories and      //
10// storing the results in a database                           //
11//  see readme.txt for more details                            //
12//  updated to mysqli by sarang                               ///
13/////////////////////////////////////////////////////////////////
14
15die('Due to a security issue, this demo has been disabled. It can be enabled by removing line '.__LINE__.' in demos/'.basename(__FILE__));
16
17
18// OPTIONS:
19$getid3_demo_mysqli_encoding_getid3 = 'UTF-8';
20$getid3_demo_mysqli_encoding_mysqli = 'utf8';  // https://dev.mysql.com/doc/refman/8.0/en/charset-charsets.html
21$getid3_demo_mysqli_md5_data = false;          // All data hashes are by far the slowest part of scanning, recommended to leave disabled
22$getid3_demo_mysqli_md5_file = false;
23
24define('GETID3_DB_HOST',  'localhost');
25define('GETID3_DB_USER',  'root');
26define('GETID3_DB_PASS',  'password');
27define('GETID3_DB_DB',    'getid3');
28define('GETID3_DB_TABLE', 'files');
29
30// CREATE DATABASE `getid3`;
31
32ob_start();
33if ($con = mysqli_connect(GETID3_DB_HOST, GETID3_DB_USER, GETID3_DB_PASS)){
34	// great
35} else {
36	$errormessage = ob_get_contents();
37	ob_end_clean();
38	die('Could not connect to MySQL host: <blockquote style="background-color: #FF9933; padding: 10px;">'.mysqli_error($con).'</blockquote>');
39}
40
41if (mysqli_select_db($con, GETID3_DB_DB)){
42	// great
43} else {
44	$errormessage = ob_get_contents();
45	ob_end_clean();
46	die('Could not select database: <blockquote style="background-color: #FF9933; padding: 10px;">'.mysqli_error($con).'</blockquote>');
47}
48ob_end_clean();
49
50if (!mysqli_set_charset($con, $getid3_demo_mysqli_encoding_mysqli)) {
51	die('Could not mysqli_set_charset('.htmlentities($getid3_demo_mysqli_encoding_mysqli).')');
52}
53
54$getid3PHP_filename = realpath('../getid3/getid3.php');
55if (!file_exists($getid3PHP_filename) || !include_once($getid3PHP_filename)) {
56	die('Cannot open '.$getid3PHP_filename);
57}
58// Initialize getID3 engine
59$getID3 = new getID3;
60$getID3->setOption(array(
61	'option_md5_data' => $getid3_demo_mysqli_md5_data,
62	'encoding'        => $getid3_demo_mysqli_encoding_getid3,
63));
64
65
66function RemoveAccents($string) {
67	// Revised version by markstewardØhotmail*com
68	return strtr(strtr($string, 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ', 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy'), array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u'));
69}
70
71function BitrateColor($bitrate, $BitrateMaxScale=768) {
72	// $BitrateMaxScale is bitrate of maximum-quality color (bright green)
73	// below this is gradient, above is solid green
74
75	$bitrate *= (256 / $BitrateMaxScale); // scale from 1-[768]kbps to 1-256
76	$bitrate = round(min(max($bitrate, 1), 256));
77	$bitrate--;    // scale from 1-256kbps to 0-255kbps
78
79	$Rcomponent = max(255 - ($bitrate * 2), 0);
80	$Gcomponent = max(($bitrate * 2) - 255, 0);
81	if ($bitrate > 127) {
82		$Bcomponent = max((255 - $bitrate) * 2, 0);
83	} else {
84		$Bcomponent = max($bitrate * 2, 0);
85	}
86	return str_pad(dechex($Rcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Gcomponent), 2, '0', STR_PAD_LEFT).str_pad(dechex($Bcomponent), 2, '0', STR_PAD_LEFT);
87}
88
89function BitrateText($bitrate, $decimals=0) {
90	return '<span style="color: #'.BitrateColor($bitrate).'">'.number_format($bitrate, $decimals).' kbps</span>';
91}
92
93function fileextension($filename, $numextensions=1) {
94	if (strstr($filename, '.')) {
95		$reversedfilename = strrev($filename);
96		$offset = 0;
97		for ($i = 0; $i < $numextensions; $i++) {
98			$offset = strpos($reversedfilename, '.', $offset + 1);
99			if ($offset === false) {
100				return '';
101			}
102		}
103		return strrev(substr($reversedfilename, 0, $offset));
104	}
105	return '';
106}
107
108function RenameFileFromTo($from, $to, &$results) {
109	$success = true;
110	if ($from === $to) {
111		$results = '<span style="color: #FF0000;"><b>Source and Destination filenames identical</b><br>FAILED to rename';
112	} elseif (!file_exists($from)) {
113		$results = '<span style="color: #FF0000;"><b>Source file does not exist</b><br>FAILED to rename';
114	} elseif (file_exists($to) && (strtolower($from) !== strtolower($to))) {
115		$results = '<span style="color: #FF0000;"><b>Destination file already exists</b><br>FAILED to rename';
116	} else {
117		ob_start();
118		if (rename($from, $to)) {
119			ob_end_clean();
120			$SQLquery  = 'DELETE';
121			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
122			$SQLquery .= ' WHERE (`filename` = "'.mysqli_real_escape_string($con, $from).'")';
123			mysqli_query_safe($con, $SQLquery);
124			$results = '<span style="color: #008000;">Successfully renamed';
125		} else {
126			$errormessage = ob_get_contents();
127			ob_end_clean();
128			$results = '<br><span style="color: #FF0000;">FAILED to rename';
129			$success = false;
130		}
131	}
132	$results .= ' from:<br><i>'.$from.'</i><br>to:<br><i>'.$to.'</i></span><hr>';
133	return $success;
134}
135
136if (!empty($_REQUEST['renamefilefrom']) && !empty($_REQUEST['renamefileto'])) {
137
138	$results = '';
139	RenameFileFromTo($_REQUEST['renamefilefrom'], $_REQUEST['renamefileto'], $results);
140	echo $results;
141	exit;
142
143} elseif (!empty($_REQUEST['m3ufilename'])) {
144
145	header('Content-type: audio/x-mpegurl');
146	echo '#EXTM3U'."\n";
147	echo WindowsShareSlashTranslate($_REQUEST['m3ufilename'])."\n";
148	exit;
149
150} elseif (!isset($_REQUEST['m3u']) && !isset($_REQUEST['m3uartist']) && !isset($_REQUEST['m3utitle'])) {
151
152	echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd">';
153	echo '<html><head><title>getID3() demo - /demo/mysql.php</title><style>BODY, TD, TH { font-family: sans-serif; font-size: 10pt; } A { text-decoration: none; } A:hover { text-decoration: underline; } A:visited { font-style: italic; }</style></head><body>';
154
155}
156
157
158function WindowsShareSlashTranslate($filename) {
159	if (substr($filename, 0, 2) == '//') {
160		return str_replace('/', '\\', $filename);
161	}
162	return $filename;
163}
164
165function mysqli_query_safe($con, $SQLquery) {
166	static $TimeSpentQuerying = 0;
167	if ($SQLquery === null) {
168		return $TimeSpentQuerying;
169	}
170	$starttime = microtime(true);
171	$result = mysqli_query($con, $SQLquery);
172	$TimeSpentQuerying += (microtime(true) - $starttime);
173	if (mysqli_error($con)) {
174		die('<div style="color: red; padding: 10px; margin: 10px; border: 3px red ridge;"><div style="font-weight: bold;">SQL error:</div><div style="color: blue; padding: 10px;">'.htmlentities(mysqli_error($con)).'</div><hr size="1"><div style="font-family: monospace;">'.htmlentities($SQLquery, ENT_SUBSTITUTE).'</div></div>');
175	}
176	return $result;
177}
178
179function mysqli_table_exists($con, $tablename) {
180	return (bool) mysqli_query($con, 'DESCRIBE '.$tablename);
181}
182
183function AcceptableExtensions($fileformat, $audio_dataformat='', $video_dataformat='') {
184	static $AcceptableExtensionsAudio = array();
185	if (empty($AcceptableExtensionsAudio)) {
186		$AcceptableExtensionsAudio['mp3']['mp3']  = array('mp3');
187		$AcceptableExtensionsAudio['mp2']['mp2']  = array('mp2');
188		$AcceptableExtensionsAudio['mp1']['mp1']  = array('mp1');
189		$AcceptableExtensionsAudio['asf']['asf']  = array('asf');
190		$AcceptableExtensionsAudio['asf']['wma']  = array('wma');
191		$AcceptableExtensionsAudio['riff']['mp3'] = array('wav');
192		$AcceptableExtensionsAudio['riff']['wav'] = array('wav');
193	}
194	static $AcceptableExtensionsVideo = array();
195	if (empty($AcceptableExtensionsVideo)) {
196		$AcceptableExtensionsVideo['mp3']['mp3']  = array('mp3');
197		$AcceptableExtensionsVideo['mp2']['mp2']  = array('mp2');
198		$AcceptableExtensionsVideo['mp1']['mp1']  = array('mp1');
199		$AcceptableExtensionsVideo['asf']['asf']  = array('asf');
200		$AcceptableExtensionsVideo['asf']['wmv']  = array('wmv');
201		$AcceptableExtensionsVideo['gif']['gif']  = array('gif');
202		$AcceptableExtensionsVideo['jpg']['jpg']  = array('jpg');
203		$AcceptableExtensionsVideo['png']['png']  = array('png');
204		$AcceptableExtensionsVideo['bmp']['bmp']  = array('bmp');
205	}
206	if (!empty($video_dataformat)) {
207		return (isset($AcceptableExtensionsVideo[$fileformat][$video_dataformat]) ? $AcceptableExtensionsVideo[$fileformat][$video_dataformat] : array());
208	} else {
209		return (isset($AcceptableExtensionsAudio[$fileformat][$audio_dataformat]) ? $AcceptableExtensionsAudio[$fileformat][$audio_dataformat] : array());
210	}
211}
212
213
214if (!empty($_REQUEST['scan'])) {
215	if (mysqli_table_exists($con, GETID3_DB_TABLE)) {
216		$SQLquery  = 'DROP TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
217		mysqli_query_safe($con, $SQLquery);
218	}
219}
220if (!mysqli_table_exists($con, GETID3_DB_TABLE)) {
221	$SQLquery  = "CREATE TABLE `".mysqli_real_escape_string($con, GETID3_DB_TABLE)."` (";
222	$SQLquery .= "`ID` int(11) unsigned NOT NULL auto_increment";
223	$SQLquery .= ", `filename` text NOT NULL";
224	$SQLquery .= ", `last_modified` int(11) NOT NULL default '0'";
225	$SQLquery .= ", `md5_file` varchar(32) NOT NULL default ''";
226	$SQLquery .= ", `md5_data` varchar(32) NOT NULL default ''";
227	$SQLquery .= ", `md5_data_source` varchar(32) NOT NULL default ''";
228	$SQLquery .= ", `filesize` int(10) unsigned NOT NULL default '0'";
229	$SQLquery .= ", `fileformat` varchar(255) NOT NULL default ''";
230	$SQLquery .= ", `audio_dataformat` varchar(255) NOT NULL default ''";
231	$SQLquery .= ", `video_dataformat` varchar(255) NOT NULL default ''";
232	$SQLquery .= ", `audio_bitrate` float NOT NULL default '0'";
233	$SQLquery .= ", `video_bitrate` float NOT NULL default '0'";
234	$SQLquery .= ", `playtime_seconds` varchar(255) NOT NULL default ''";
235	$SQLquery .= ", `tags` varchar(255) NOT NULL default ''";
236	$SQLquery .= ", `artist` varchar(255) NOT NULL default ''";
237	$SQLquery .= ", `title` varchar(255) NOT NULL default ''";
238	$SQLquery .= ", `remix` varchar(255) NOT NULL default ''";
239	$SQLquery .= ", `album` varchar(255) NOT NULL default ''";
240	$SQLquery .= ", `genre` varchar(255) NOT NULL default ''";
241	$SQLquery .= ", `comment` text NOT NULL";
242	$SQLquery .= ", `track` varchar(7) NOT NULL default ''";
243	$SQLquery .= ", `comments_all` longblob NOT NULL";
244	$SQLquery .= ", `comments_id3v2` longblob NOT NULL";
245	$SQLquery .= ", `comments_ape` longblob NOT NULL";
246	$SQLquery .= ", `comments_lyrics3` longblob NOT NULL";
247	$SQLquery .= ", `comments_id3v1` blob NOT NULL";
248	$SQLquery .= ", `warning` longtext NOT NULL";
249	$SQLquery .= ", `error` longtext NOT NULL";
250	$SQLquery .= ", `track_volume` float NOT NULL default '0'";
251	$SQLquery .= ", `encoder_options` varchar(255) NOT NULL default ''";
252	$SQLquery .= ", `vbr_method` varchar(255) NOT NULL default ''";
253	$SQLquery .= ", PRIMARY KEY (`ID`)";
254	$SQLquery .= ")";
255	mysqli_query_safe($con, $SQLquery);
256}
257
258$ExistingTableFields = array();
259$result = mysqli_query_safe($con, 'DESCRIBE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`');
260while ($row = mysqli_fetch_array($result)) {
261	$ExistingTableFields[$row['Field']] = $row;
262}
263if (!isset($ExistingTableFields['encoder_options'])) { // Added in 1.7.0b2
264	echo '<b>adding field `encoder_options`</b><br>';
265	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` ADD `encoder_options` VARCHAR(255) default "" NOT NULL AFTER `error`');
266	mysqli_query_safe($con, 'OPTIMIZE TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`');
267}
268if (isset($ExistingTableFields['track']) && ($ExistingTableFields['track']['Type'] != 'varchar(7)')) { // Changed in 1.7.0b2
269	echo '<b>changing field `track` to VARCHAR(7)</b><br>';
270	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `track` `track` VARCHAR(7) default "" NOT NULL');
271	mysqli_query_safe($con, 'OPTIMIZE TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`');
272}
273if (!isset($ExistingTableFields['track_volume'])) { // Added in 1.7.0b5
274	echo '<H1><FONT COLOR="red">WARNING! You should erase your database and rescan everything because the comment storing has been changed since the last version</FONT></H1><hr>';
275	echo '<b>adding field `track_volume`</b><br>';
276	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` ADD `track_volume` FLOAT NOT NULL AFTER `error`');
277	mysqli_query_safe($con, 'OPTIMIZE TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`');
278}
279if (!isset($ExistingTableFields['remix'])) { // Added in 1.7.3b1
280	echo '<b>adding field `encoder_options`, `alternate_name`, `parody`</b><br>';
281	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` ADD `remix` VARCHAR(255) default "" NOT NULL AFTER `title`');
282	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` ADD `alternate_name` VARCHAR(255) default "" NOT NULL AFTER `track`');
283	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` ADD `parody` VARCHAR(255) default "" NOT NULL AFTER `alternate_name`');
284	mysqli_query_safe($con, 'OPTIMIZE TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`');
285}
286if (isset($ExistingTableFields['comments_all']) && ($ExistingTableFields['comments_all']['Type'] != 'longblob')) { // Changed to "longtext" in 1.9.0, changed to "longblob" in 1.9.20-202010140821
287	echo '<b>changing comments fields from text to longtext</b><br>';
288	// no need to change id3v1
289	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `comments_all`     `comments_all`     LONGBLOB NOT NULL');
290	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `comments_id3v2`   `comments_id3v2`   LONGBLOB NOT NULL');
291	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `comments_ape`     `comments_ape`     LONGBLOB NOT NULL');
292	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `comments_lyrics3` `comments_lyrics3` LONGBLOB NOT NULL');
293	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `comments_id3v1`   `comments_id3v1`       BLOB NOT NULL');
294	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `warning`          `warning`          LONGTEXT NOT NULL');
295	mysqli_query_safe($con, 'ALTER TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` CHANGE `error`            `error`            LONGTEXT NOT NULL');
296}
297
298
299function SynchronizeAllTags($filename, $synchronizefrom='all', $synchronizeto='A12', &$errors = array()) {
300	global $getID3;
301
302	set_time_limit(30);
303
304	$ThisFileInfo = $getID3->analyze($filename);
305	$getID3->CopyTagsToComments($ThisFileInfo);
306
307	if ($synchronizefrom == 'all') {
308		$SourceArray = (!empty($ThisFileInfo['comments']) ? $ThisFileInfo['comments'] : array());
309	} elseif (!empty($ThisFileInfo['tags'][$synchronizefrom])) {
310		$SourceArray = (!empty($ThisFileInfo['tags'][$synchronizefrom]) ? $ThisFileInfo['tags'][$synchronizefrom] : array());
311	} else {
312		die('ERROR: $ThisFileInfo[tags]['.$synchronizefrom.'] does not exist');
313	}
314
315	$SQLquery  = 'DELETE';
316	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
317	$SQLquery .= ' WHERE (`filename` = "'.mysqli_real_escape_string($con, $filename).'")';
318	mysqli_query_safe($con, $SQLquery);
319
320
321	$TagFormatsToWrite = array();
322	if ((strpos($synchronizeto, '2') !== false) && ($synchronizefrom != 'id3v2')) {
323		$TagFormatsToWrite[] = 'id3v2.3';
324	}
325	if ((strpos($synchronizeto, 'A') !== false) && ($synchronizefrom != 'ape')) {
326		$TagFormatsToWrite[] = 'ape';
327	}
328	if ((strpos($synchronizeto, 'L') !== false) && ($synchronizefrom != 'lyrics3')) {
329		$TagFormatsToWrite[] = 'lyrics3';
330	}
331	if ((strpos($synchronizeto, '1') !== false) && ($synchronizefrom != 'id3v1')) {
332		$TagFormatsToWrite[] = 'id3v1';
333	}
334
335	getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.php', __FILE__, true);
336	$tagwriter = new getid3_writetags;
337	$tagwriter->filename       = $filename;
338	$tagwriter->tagformats     = $TagFormatsToWrite;
339	$tagwriter->overwrite_tags = true;
340	$tagwriter->tag_encoding   = $getID3->encoding;
341	$tagwriter->tag_data       = $SourceArray;
342
343	if ($tagwriter->WriteTags()) {
344		$errors = $tagwriter->errors;
345		return true;
346	}
347	$errors = $tagwriter->errors;
348	return false;
349}
350
351$IgnoreNoTagFormats = array('', 'png', 'jpg', 'gif', 'bmp', 'swf', 'pdf', 'zip', 'rar', 'mid', 'mod', 'xm', 'it', 's3m');
352
353if (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan']) || !empty($_REQUEST['rescanerrors'])) {
354
355	$SQLquery  = 'DELETE';
356	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
357	$SQLquery .= ' WHERE (`fileformat` = "")';
358	mysqli_query_safe($con, $SQLquery);
359
360	$FilesInDir = array();
361
362	if (!empty($_REQUEST['rescanerrors'])) {
363
364		echo '<a href="'.htmlentities($_SERVER['PHP_SELF']).'">abort</a><hr>';
365
366		echo 'Re-scanning all media files already in database that had errors and/or warnings in last scan<hr>';
367
368		$SQLquery  = 'SELECT `filename`';
369		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
370		$SQLquery .= ' WHERE (`error` <> "")';
371		$SQLquery .= ' OR (`warning` <> "")';
372		$SQLquery .= ' ORDER BY `filename` ASC';
373		$result = mysqli_query_safe($con, $SQLquery);
374		while ($row = mysqli_fetch_array($result)) {
375
376			if (!file_exists($row['filename'])) {
377				echo '<b>File missing: '.$row['filename'].'</b><br>';
378				$SQLquery  = 'DELETE';
379				$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
380				$SQLquery .= ' WHERE (`filename` = "'.mysqli_real_escape_string($con, $row['filename']).'")';
381				mysqli_query_safe($con, $SQLquery);
382			} else {
383				$FilesInDir[] = $row['filename'];
384			}
385
386		}
387
388	} elseif (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan'])) {
389
390		echo '<a href="'.htmlentities($_SERVER['PHP_SELF']).'">abort</a><hr>';
391
392		echo 'Scanning all media files in <b>'.str_replace('\\', '/', realpath(!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : $_REQUEST['newscan'])).'</b> (and subdirectories)<hr>';
393
394		$SQLquery  = 'SELECT COUNT(*) AS `num`, `filename`';
395		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
396		$SQLquery .= ' GROUP BY `filename`';
397		$SQLquery .= ' HAVING (`num` > 1)';
398		$SQLquery .= ' ORDER BY `num` DESC';
399		$result = mysqli_query_safe($con, $SQLquery);
400		$DupesDeleted = 0;
401		while ($row = mysqli_fetch_array($result)) {
402			set_time_limit(30);
403			$SQLquery  = 'DELETE';
404			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
405			$SQLquery .= ' WHERE `filename` LIKE "'.mysqli_real_escape_string($con, $row['filename']).'"';
406			mysqli_query_safe($con, $SQLquery);
407			$DupesDeleted++;
408		}
409		if ($DupesDeleted > 0) {
410			echo 'Deleted <b>'.number_format($DupesDeleted).'</b> duplicate filenames<hr>';
411		}
412
413		if (!empty($_REQUEST['newscan'])) {
414			$AlreadyInDatabase = array();
415			set_time_limit(60);
416			$SQLquery  = 'SELECT `filename`';
417			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
418			$SQLquery .= ' ORDER BY `filename` ASC';
419			$result = mysqli_query_safe($con, $SQLquery);
420			while ($row = mysqli_fetch_array($result)) {
421				//$AlreadyInDatabase[] = strtolower($row['filename']);
422				$AlreadyInDatabase[] = $row['filename'];
423			}
424		}
425
426		$DirectoriesToScan  = array(!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : $_REQUEST['newscan']);
427		$DirectoriesScanned = array();
428		while (count($DirectoriesToScan) > 0) {
429			foreach ($DirectoriesToScan as $DirectoryKey => $startingdir) {
430				if ($dir = opendir($startingdir)) {
431					set_time_limit(30);
432					echo '<b>'.str_replace('\\', '/', $startingdir).'</b><br>';
433					flush();
434					while (($file = readdir($dir)) !== false) {
435						if (($file != '.') && ($file != '..')) {
436							$RealPathName = realpath($startingdir.'/'.$file);
437							if (is_dir($RealPathName)) {
438								if (!in_array($RealPathName, $DirectoriesScanned) && !in_array($RealPathName, $DirectoriesToScan)) {
439									$DirectoriesToScan[] = $RealPathName;
440								}
441							} elseif (is_file($RealPathName)) {
442								if (!empty($_REQUEST['newscan'])) {
443									if (!in_array(str_replace('\\', '/', $RealPathName), $AlreadyInDatabase)) {
444										$FilesInDir[] = $RealPathName;
445									}
446								} elseif (!empty($_REQUEST['scan'])) {
447									$FilesInDir[] = $RealPathName;
448								}
449							}
450						}
451					}
452					closedir($dir);
453				} else {
454					echo '<div style="color: red;">Failed to open directory "<b>'.htmlentities($startingdir).'</b>"</div><br>';
455				}
456				$DirectoriesScanned[] = $startingdir;
457				unset($DirectoriesToScan[$DirectoryKey]);
458			}
459		}
460		echo '<i>List of files to scan complete (added '.number_format(count($FilesInDir)).' files to scan)</i><hr>';
461		flush();
462	}
463
464	$FilesInDir = array_unique($FilesInDir);
465	sort($FilesInDir);
466
467	$starttime = time();
468	$rowcounter = 0;
469	$totaltoprocess = count($FilesInDir);
470
471	foreach ($FilesInDir as $filename) {
472		set_time_limit(300);
473
474		echo '<br>'.date('H:i:s').' ['.number_format(++$rowcounter).' / '.number_format($totaltoprocess).'] '.str_replace('\\', '/', $filename);
475
476		$ThisFileInfo = $getID3->analyze($filename);
477		$getID3->CopyTagsToComments($ThisFileInfo);
478
479		if (file_exists($filename)) {
480			$ThisFileInfo['file_modified_time'] = filemtime($filename);
481			$ThisFileInfo['md5_file']           = ($getid3_demo_mysqli_md5_file ? md5_file($filename) : '');
482		}
483
484		if (empty($ThisFileInfo['fileformat'])) {
485
486			echo ' (<span style="color: #990099;">unknown file type</span>)';
487
488		} else {
489
490			if (!empty($ThisFileInfo['error'])) {
491				echo ' (<span style="color: #FF0000;">errors</span>)';
492			} elseif (!empty($ThisFileInfo['warning'])) {
493				echo ' (<span style="color: #FF9999;">warnings</span>)';
494			} else {
495				echo ' (<span style="color: #009900;">OK</span>)';
496			}
497
498			$this_track_track = '';
499			if (!empty($ThisFileInfo['comments']['track_number'])) {
500				foreach ($ThisFileInfo['comments']['track_number'] as $key => $value) {
501					if (strlen($value) > strlen($this_track_track)) {
502						$this_track_track = str_pad($value, 2, '0', STR_PAD_LEFT);
503					}
504				}
505				if (preg_match('#^([0-9]+)/([0-9]+)$#', $this_track_track, $matches)) {
506					// change "1/5"->"01/05", "3/12"->"03/12", etc
507					$this_track_track = str_pad($matches[1], 2, '0', STR_PAD_LEFT).'/'.str_pad($matches[2], 2, '0', STR_PAD_LEFT);
508				}
509			}
510
511			$this_track_remix = '';
512			$this_track_title = '';
513			if (!empty($ThisFileInfo['comments']['title'])) {
514				foreach ($ThisFileInfo['comments']['title'] as $possible_title) {
515					if (strlen($possible_title) > strlen($this_track_title)) {
516						$this_track_title = $possible_title;
517					}
518				}
519			}
520
521			$ParenthesesPairs = array('()', '[]', '{}');
522			foreach ($ParenthesesPairs as $pair) {
523				if (preg_match_all('/(.*) '.preg_quote($pair[0]).'(([^'.preg_quote($pair).']*[\- '.preg_quote($pair[0]).'])?(cut|dub|edit|version|live|reprise|[a-z]*mix))'.preg_quote($pair[1]).'/iU', $this_track_title, $matches)) {
524					$this_track_title = $matches[1][0];
525					$this_track_remix = implode("\t", $matches[2]);
526				}
527			}
528
529
530
531			if (!empty($_REQUEST['rescanerrors'])) {
532
533				$SQLquery  = 'UPDATE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` SET ';
534				$SQLquery .= '  `last_modified` = "'.   mysqli_real_escape_string($con, !empty($ThisFileInfo['file_modified_time']            ) ?                          $ThisFileInfo['file_modified_time']              : '').'"';
535				$SQLquery .= ', `md5_file` = "'.        mysqli_real_escape_string($con, !empty($ThisFileInfo['md5_file']                      ) ?                          $ThisFileInfo['md5_file']                        : '').'"';
536				$SQLquery .= ', `md5_data` = "'.        mysqli_real_escape_string($con, !empty($ThisFileInfo['md5_data']                      ) ?                          $ThisFileInfo['md5_data']                        : '').'"';
537				$SQLquery .= ', `md5_data_source` = "'. mysqli_real_escape_string($con, !empty($ThisFileInfo['md5_data_source']               ) ?                          $ThisFileInfo['md5_data_source']                 : '').'"';
538				$SQLquery .= ', `filesize` = "'.        mysqli_real_escape_string($con, !empty($ThisFileInfo['filesize']                      ) ?                          $ThisFileInfo['filesize']                        :  0).'"';
539				$SQLquery .= ', `fileformat` = "'.      mysqli_real_escape_string($con, !empty($ThisFileInfo['fileformat']                    ) ?                          $ThisFileInfo['fileformat']                      : '').'"';
540				$SQLquery .= ', `audio_dataformat` = "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['audio']['dataformat']           ) ?                          $ThisFileInfo['audio']['dataformat']             : '').'"';
541				$SQLquery .= ', `video_dataformat` = "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['video']['dataformat']           ) ?                          $ThisFileInfo['video']['dataformat']             : '').'"';
542				$SQLquery .= ', `vbr_method` = "'.      mysqli_real_escape_string($con, !empty($ThisFileInfo['mpeg']['audio']['VBR_method']   ) ?                          $ThisFileInfo['mpeg']['audio']['VBR_method']     : '').'"';
543				$SQLquery .= ', `audio_bitrate` = "'.   mysqli_real_escape_string($con, !empty($ThisFileInfo['audio']['bitrate']              ) ?                 floatval($ThisFileInfo['audio']['bitrate'])               :  0).'"';
544				$SQLquery .= ', `video_bitrate` = "'.   mysqli_real_escape_string($con, !empty($ThisFileInfo['video']['bitrate']              ) ?                 floatval($ThisFileInfo['video']['bitrate'])               :  0).'"';
545				$SQLquery .= ', `playtime_seconds` = "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['playtime_seconds']              ) ?                 floatval($ThisFileInfo['playtime_seconds'])               :  0).'"';
546				$SQLquery .= ', `track_volume` = "'.    mysqli_real_escape_string($con, !empty($ThisFileInfo['replay_gain']['track']['volume']) ?                 floatval($ThisFileInfo['replay_gain']['track']['volume']) :  0).'"';
547				$SQLquery .= ', `comments_all` = "'.    mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']                      ) ?                serialize($ThisFileInfo['comments'])                       : '').'"';
548				$SQLquery .= ', `comments_id3v2` = "'.  mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['id3v2']                 ) ?                serialize($ThisFileInfo['tags']['id3v2'])                  : '').'"';
549				$SQLquery .= ', `comments_ape` = "'.    mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['ape']                   ) ?                serialize($ThisFileInfo['tags']['ape'])                    : '').'"';
550				$SQLquery .= ', `comments_lyrics3` = "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['lyrics3']               ) ?                serialize($ThisFileInfo['tags']['lyrics3'])                : '').'"';
551				$SQLquery .= ', `comments_id3v1` = "'.  mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['id3v1']                 ) ?                serialize($ThisFileInfo['tags']['id3v1'])                  : '').'"';
552				$SQLquery .= ', `warning` = "'.         mysqli_real_escape_string($con, !empty($ThisFileInfo['warning']                       ) ?            implode("\t", $ThisFileInfo['warning'])                        : '').'"';
553				$SQLquery .= ', `error` = "'.           mysqli_real_escape_string($con, !empty($ThisFileInfo['error']                         ) ?            implode("\t", $ThisFileInfo['error'])                          : '').'"';
554				$SQLquery .= ', `album` = "'.           mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['album']             ) ?            implode("\t", $ThisFileInfo['comments']['album'])              : '').'"';
555				$SQLquery .= ', `genre` = "'.           mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['genre']             ) ?            implode("\t", $ThisFileInfo['comments']['genre'])              : '').'"';
556				$SQLquery .= ', `comment` = "'.         mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['comment']           ) ?            implode("\t", $ThisFileInfo['comments']['comment'])            : '').'"';
557				$SQLquery .= ', `artist` = "'.          mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['artist']            ) ?            implode("\t", $ThisFileInfo['comments']['artist'])             : '').'"';
558				$SQLquery .= ', `tags` = "'.            mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']                          ) ? implode("\t", array_keys($ThisFileInfo['tags']))                          : '').'"';
559				$SQLquery .= ', `encoder_options` = "'. mysqli_real_escape_string($con, trim((!empty($ThisFileInfo['audio']['encoder']) ? $ThisFileInfo['audio']['encoder'] : '').' '.(!empty($ThisFileInfo['audio']['encoder_options']) ? $ThisFileInfo['audio']['encoder_options'] : ''))).'"';
560				$SQLquery .= ', `title` = "'.           mysqli_real_escape_string($con, $this_track_title).'"';
561				$SQLquery .= ', `remix` = "'.           mysqli_real_escape_string($con, $this_track_remix).'"';
562				$SQLquery .= ', `track` = "'.           mysqli_real_escape_string($con, $this_track_track).'"';
563				$SQLquery .= ' WHERE (`filename` = "'. mysqli_real_escape_string($con, isset($ThisFileInfo['filenamepath']) ? $ThisFileInfo['filenamepath'] : '').'")';
564
565			} elseif (!empty($_REQUEST['scan']) || !empty($_REQUEST['newscan'])) {
566
567				$SQLquery  = 'INSERT INTO `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'` (`filename`, `last_modified`, `md5_file`, `md5_data`, `md5_data_source`, `filesize`, `fileformat`, `audio_dataformat`, `video_dataformat`, `audio_bitrate`, `video_bitrate`, `playtime_seconds`, `tags`, `artist`, `title`, `remix`, `album`, `genre`, `comment`, `track`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`, `warning`, `error`, `track_volume`, `encoder_options`, `vbr_method`) VALUES (';
568				$SQLquery .=   '"'.mysqli_real_escape_string($con, !empty($ThisFileInfo['filenamepath']                  ) ?                          $ThisFileInfo['filenamepath']                    : '').'"'; // filename
569				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['file_modified_time']            ) ?                          $ThisFileInfo['file_modified_time']              : '').'"'; // last_modified
570				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['md5_file']                      ) ?                          $ThisFileInfo['md5_file']                        : '').'"'; // md5_file
571				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['md5_data']                      ) ?                          $ThisFileInfo['md5_data']                        : '').'"'; // md5_data
572				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['md5_data_source']               ) ?                          $ThisFileInfo['md5_data_source']                 : '').'"'; // md5_data_source
573				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['filesize']                      ) ?                          $ThisFileInfo['filesize']                        :  0).'"'; // filesize
574				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['fileformat']                    ) ?                          $ThisFileInfo['fileformat']                      : '').'"'; // fileformat
575				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['audio']['dataformat']           ) ?                          $ThisFileInfo['audio']['dataformat']             : '').'"'; // audio_dataformat
576				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['video']['dataformat']           ) ?                          $ThisFileInfo['video']['dataformat']             : '').'"'; // video_dataformat
577				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['audio']['bitrate']              ) ?                 floatval($ThisFileInfo['audio']['bitrate'])               :  0).'"'; // audio_bitrate
578				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['video']['bitrate']              ) ?                 floatval($ThisFileInfo['video']['bitrate'])               :  0).'"'; // video_bitrate
579				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['playtime_seconds']              ) ?                 floatval($ThisFileInfo['playtime_seconds'])               :  0).'"'; // playtime_seconds
580				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']                          ) ? implode("\t", array_keys($ThisFileInfo['tags']))                          : '').'"'; // tags
581				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['artist']            ) ?            implode("\t", $ThisFileInfo['comments']['artist'])             : '').'"'; // artist
582				$SQLquery .= ', "'.mysqli_real_escape_string($con,                                                                                    $this_track_title                                    ).'"'; // title
583				$SQLquery .= ', "'.mysqli_real_escape_string($con,                                                                                    $this_track_remix                                    ).'"'; // remix
584				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['album']             ) ?            implode("\t", $ThisFileInfo['comments']['album'])              : '').'"'; // album
585				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['genre']             ) ?            implode("\t", $ThisFileInfo['comments']['genre'])              : '').'"'; // genre
586				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']['comment']           ) ?            implode("\t", $ThisFileInfo['comments']['comment'])            : '').'"'; // comment
587				$SQLquery .= ', "'.mysqli_real_escape_string($con,                                                                                    $this_track_track                                    ).'"'; // track
588				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['comments']                      ) ?                serialize($ThisFileInfo['comments'])                       : '').'"'; // comments_all
589				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['id3v2']                 ) ?                serialize($ThisFileInfo['tags']['id3v2'])                  : '').'"'; // comments_id3v2
590				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['ape']                   ) ?                serialize($ThisFileInfo['tags']['ape'])                    : '').'"'; // comments_ape
591				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['lyrics3']               ) ?                serialize($ThisFileInfo['tags']['lyrics3'])                : '').'"'; // comments_lyrics3
592				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['tags']['id3v1']                 ) ?                serialize($ThisFileInfo['tags']['id3v1'])                  : '').'"'; // comments_id3v1
593				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['warning']                       ) ?            implode("\t", $ThisFileInfo['warning'])                        : '').'"'; // warning
594				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['error']                         ) ?            implode("\t", $ThisFileInfo['error'])                          : '').'"'; // error
595				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['replay_gain']['track']['volume']) ?                 floatval($ThisFileInfo['replay_gain']['track']['volume']) :  0).'"'; // track_volume
596				$SQLquery .= ', "'.mysqli_real_escape_string($con, trim((!empty($ThisFileInfo['audio']['encoder']) ? $ThisFileInfo['audio']['encoder'] : '').' '.(!empty($ThisFileInfo['audio']['encoder_options']) ? $ThisFileInfo['audio']['encoder_options'] : ''))).'"'; // encoder_options
597				$SQLquery .= ', "'.mysqli_real_escape_string($con, !empty($ThisFileInfo['mpeg']['audio']['LAME']) ? 'LAME' : (!empty($ThisFileInfo['mpeg']['audio']['VBR_method']) ? $ThisFileInfo['mpeg']['audio']['VBR_method'] : '')).'"'; // vbr_method
598				$SQLquery .= ')';
599			}
600			flush();
601			mysqli_query_safe($con, $SQLquery);
602		}
603
604	}
605
606	$SQLquery = 'OPTIMIZE TABLE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
607	mysqli_query_safe($con, $SQLquery);
608
609	echo '<hr>Done scanning!<hr>';
610
611} elseif (!empty($_REQUEST['missingtrackvolume'])) {
612
613	$MissingTrackVolumeFilesScanned  = 0;
614	$MissingTrackVolumeFilesAdjusted = 0;
615	$MissingTrackVolumeFilesDeleted  = 0;
616	$SQLquery  = 'SELECT `filename`';
617	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
618	$SQLquery .= ' WHERE (`track_volume` = 0)';
619	$SQLquery .= ' AND (`audio_bitrate` > 0)';
620	$result = mysqli_query_safe($con, $SQLquery);
621	echo 'Scanning <span ID="missingtrackvolumeNowScanning">0</span> / '.number_format(mysqli_num_rows($result)).' files for track volume information:<hr>';
622	while ($row = mysqli_fetch_array($result)) {
623		set_time_limit(30);
624		echo '<script type="text/javascript">if (document.getElementById("missingtrackvolumeNowScanning")) document.getElementById("missingtrackvolumeNowScanning").innerHTML = "'.number_format($MissingTrackVolumeFilesScanned++).'";</script>. ';
625		flush();
626		if (file_exists($row['filename'])) {
627
628			$ThisFileInfo = $getID3->analyze($row['filename']);
629			if (!empty($ThisFileInfo['replay_gain']['track']['volume'])) {
630				$MissingTrackVolumeFilesAdjusted++;
631				$SQLquery  = 'UPDATE `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
632				$SQLquery .= ' SET `track_volume` = "'.$ThisFileInfo['replay_gain']['track']['volume'].'"';
633				$SQLquery .= ' WHERE (`filename` = "'.mysqli_real_escape_string($con, $row['filename']).'")';
634				mysqli_query_safe($con, $SQLquery);
635			}
636
637		} else {
638
639			$MissingTrackVolumeFilesDeleted++;
640			$SQLquery  = 'DELETE';
641			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
642			$SQLquery .= ' WHERE (`filename` = "'.mysqli_real_escape_string($con, $row['filename']).'")';
643			mysqli_query_safe($con, $SQLquery);
644
645		}
646	}
647	echo '<hr>Scanned '.number_format($MissingTrackVolumeFilesScanned).' files with no track volume information.<br>';
648	echo 'Found track volume information for '.number_format($MissingTrackVolumeFilesAdjusted).' of them (could not find info for '.number_format($MissingTrackVolumeFilesScanned - $MissingTrackVolumeFilesAdjusted).' files; deleted '.number_format($MissingTrackVolumeFilesDeleted).' records of missing files)<hr>';
649
650} elseif (!empty($_REQUEST['deadfilescheck'])) {
651
652	$SQLquery  = 'SELECT COUNT(*) AS `num`, `filename`';
653	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
654	$SQLquery .= ' GROUP BY `filename`';
655	$SQLquery .= ' ORDER BY `num` DESC';
656	$result = mysqli_query_safe($con, $SQLquery);
657	$DupesDeleted = 0;
658	while ($row = mysqli_fetch_array($result)) {
659		set_time_limit(30);
660		if ($row['num'] <= 1) {
661			break;
662		}
663		echo '<br>'.htmlentities($row['filename']).' (<font color="#FF9999">duplicate</font>)';
664		$SQLquery  = 'DELETE';
665		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
666		$SQLquery .= ' WHERE `filename` LIKE "'.mysqli_real_escape_string($con, $row['filename']).'"';
667		mysqli_query_safe($con, $SQLquery);
668		$DupesDeleted++;
669	}
670	if ($DupesDeleted > 0) {
671		echo '<hr>Deleted <b>'.number_format($DupesDeleted).'</b> duplicate filenames<hr>';
672	}
673
674	$SQLquery  = 'SELECT `filename`, `filesize`, `last_modified`';
675	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
676	$SQLquery .= ' ORDER BY `filename` ASC';
677	$result = mysqli_query_safe($con, $SQLquery);
678	$totalchecked = 0;
679	$totalremoved = 0;
680	$previousdir = '';
681	while ($row = mysqli_fetch_array($result)) {
682		$totalchecked++;
683		set_time_limit(30);
684		$reason = '';
685		if (!file_exists($row['filename'])) {
686			$reason = 'deleted';
687		} elseif (filesize($row['filename']) != $row['filesize']) {
688			$reason = 'filesize changed';
689		} elseif (filemtime($row['filename']) != $row['last_modified']) {
690			if (abs(filemtime($row['filename']) - $row['last_modified']) != 3600) {
691				// off by exactly one hour == daylight savings time
692				$reason = 'last-modified time changed';
693			}
694		}
695
696		$thisdir = dirname($row['filename']);
697		if ($reason) {
698
699			$totalremoved++;
700			echo '<br>'.htmlentities($row['filename']).' (<font color="#FF9999">'.$reason.'</font>)';
701			flush();
702			$SQLquery  = 'DELETE';
703			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
704			$SQLquery .= ' WHERE (`filename` = "'.mysqli_real_escape_string($con, $row['filename']).'")';
705			mysqli_query_safe($con, $SQLquery);
706
707		} elseif ($thisdir != $previousdir) {
708
709			echo '. ';
710			flush();
711
712		}
713		$previousdir = $thisdir;
714	}
715
716	echo '<hr><b>'.number_format($totalremoved).' of '.number_format($totalchecked).' files in database no longer exist, or have been altered since last scan. Removed from database.</b><hr>';
717
718} elseif (!empty($_REQUEST['encodedbydistribution'])) {
719
720	if (!empty($_REQUEST['m3u'])) {
721
722		header('Content-type: audio/x-mpegurl');
723		echo '#EXTM3U'."\n";
724
725		$SQLquery  = 'SELECT `filename`, `comments_id3v2`';
726		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
727		$SQLquery .= ' WHERE (`encoder_options` = "'.mysqli_real_escape_string($con, $_REQUEST['encodedbydistribution']).'")';
728		$result = mysqli_query_safe($con, $SQLquery);
729		$NonBlankEncodedBy = '';
730		$BlankEncodedBy = '';
731		while ($row = mysqli_fetch_array($result)) {
732			set_time_limit(30);
733			$CommentArray = unserialize($row['comments_id3v2']);
734			if (isset($CommentArray['encoded_by'][0])) {
735				$NonBlankEncodedBy .= WindowsShareSlashTranslate($row['filename'])."\n";
736			} else {
737				$BlankEncodedBy    .= WindowsShareSlashTranslate($row['filename'])."\n";
738			}
739		}
740		echo $NonBlankEncodedBy;
741		echo $BlankEncodedBy;
742		exit;
743
744	} elseif (!empty($_REQUEST['showfiles'])) {
745
746		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?encodedbydistribution='.urlencode('%')).'">show all</a><br>';
747		echo '<table border="1">';
748
749		$SQLquery  = 'SELECT `filename`, `comments_id3v2`';
750		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
751		$result = mysqli_query_safe($con, $SQLquery);
752		while ($row = mysqli_fetch_array($result)) {
753			set_time_limit(30);
754			$CommentArray = unserialize($row['comments_id3v2']);
755			if (($_REQUEST['encodedbydistribution'] == '%') || (!empty($CommentArray['encoded_by'][0]) && ($_REQUEST['encodedbydistribution'] == $CommentArray['encoded_by'][0]))) {
756				echo '<tr><td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename'])).'">m3u</a></td>';
757				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td></tr>';
758			}
759		}
760		echo '</table>';
761
762	} else {
763
764		$SQLquery  = 'SELECT `encoder_options`, `comments_id3v2`';
765		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
766		$SQLquery .= ' ORDER BY (`encoder_options` LIKE "LAME%") DESC, (`encoder_options` LIKE "CBR%") DESC';
767		$result = mysqli_query_safe($con, $SQLquery);
768		$EncodedBy = array();
769		while ($row = mysqli_fetch_array($result)) {
770			set_time_limit(30);
771			$CommentArray = unserialize($row['comments_id3v2']);
772			if (isset($CommentArray['encoded_by'][0])) {
773				if (isset($EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]])) {
774					$EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]]++;
775				} else {
776					$EncodedBy[$row['encoder_options']][$CommentArray['encoded_by'][0]] = 1;
777				}
778			}
779		}
780		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?encodedbydistribution='.urlencode('%').'&m3u=1').'">.m3u version</a><br>';
781		echo '<table border="1"><tr><th>m3u</th><th>Encoder Options</th><th>Encoded By (ID3v2)</th></tr>';
782		foreach ($EncodedBy as $key => $value) {
783			echo '<tr><TD VALIGN="TOP"><a href="'.htmlentities($_SERVER['PHP_SELF'].'?encodedbydistribution='.urlencode($key).'&showfiles=1&m3u=1').'">m3u</a></td>';
784			echo '<TD VALIGN="TOP"><b>'.$key.'</b></td>';
785			echo '<td><table border="0" WIDTH="100%">';
786			arsort($value);
787			foreach ($value as $string => $count) {
788				echo '<tr><TD ALIGN="RIGHT" WIDTH="50"><i>'.number_format($count).'</i></td><td>&nbsp;</td>';
789				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?encodedbydistribution='.urlencode($string).'&showfiles=1').'">'.$string.'</a></td></tr>';
790			}
791			echo '</table></td></tr>';
792		}
793		echo '</table>';
794
795	}
796
797} elseif (!empty($_REQUEST['audiobitrates'])) {
798
799	getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
800	$BitrateDistribution = array();
801	$SQLquery  = 'SELECT ROUND(audio_bitrate / 1000) AS `RoundBitrate`, COUNT(*) AS `num`';
802	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
803	$SQLquery .= ' WHERE (`audio_bitrate` > 0)';
804	$SQLquery .= ' GROUP BY `RoundBitrate`';
805	$result = mysqli_query_safe($con, $SQLquery);
806	while ($row = mysqli_fetch_array($result)) {
807		$this_bitrate = getid3_mp3::ClosestStandardMP3Bitrate($row['RoundBitrate'] * 1000);
808		if (isset($BitrateDistribution[$this_bitrate])) {
809			$BitrateDistribution[$this_bitrate] += $row['num'];
810		} else {
811			$BitrateDistribution[$this_bitrate]  = $row['num'];
812		}
813	}
814
815	echo '<table border="1" cellspacing="0" cellpadding="3">';
816	echo '<tr><th>Bitrate</th><th>Count</th></tr>';
817	foreach ($BitrateDistribution as $Bitrate => $Count) {
818		echo '<tr>';
819		echo '<td align="right">'.round($Bitrate / 1000).' kbps</td>';
820		echo '<td align="right">'.number_format($Count).'</td>';
821		echo '</tr>';
822	}
823	echo '</table>';
824
825
826} elseif (!empty($_REQUEST['emptygenres'])) {
827
828	$SQLquery  = 'SELECT `fileformat`, `filename`, `genre`';
829	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
830	$SQLquery .= ' WHERE (`genre` = "")';
831	$SQLquery .= ' OR (`genre` = "Unknown")';
832	$SQLquery .= ' OR (`genre` = "Other")';
833	$SQLquery .= ' ORDER BY `filename` ASC';
834	$result = mysqli_query_safe($con, $SQLquery);
835
836	if (!empty($_REQUEST['m3u'])) {
837
838		header('Content-type: audio/x-mpegurl');
839		echo '#EXTM3U'."\n";
840		while ($row = mysqli_fetch_array($result)) {
841			if (!in_array($row['fileformat'], $IgnoreNoTagFormats)) {
842				echo WindowsShareSlashTranslate($row['filename'])."\n";
843			}
844		}
845		exit;
846
847	} else {
848
849		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?emptygenres='.urlencode($_REQUEST['emptygenres']).'&m3u=1').'">.m3u version</a><br>';
850		$EmptyGenreCounter = 0;
851		echo '<table border="1" cellspacing="0" cellpadding="3">';
852		echo '<tr><th>m3u</th><th>filename</th></tr>';
853		while ($row = mysqli_fetch_array($result)) {
854			if (!in_array($row['fileformat'], $IgnoreNoTagFormats)) {
855				$EmptyGenreCounter++;
856				echo '<tr>';
857				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">m3u</a></td>';
858				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
859				echo '</tr>';
860			}
861		}
862		echo '</table>';
863		echo '<b>'.number_format($EmptyGenreCounter).'</b> files with empty genres';
864
865	}
866
867} elseif (!empty($_REQUEST['nonemptycomments'])) {
868
869	$SQLquery  = 'SELECT `filename`, `comment`';
870	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
871	$SQLquery .= ' WHERE (`comment` <> "")';
872	$SQLquery .= ' ORDER BY `comment` ASC';
873	$result = mysqli_query_safe($con, $SQLquery);
874
875	if (!empty($_REQUEST['m3u'])) {
876
877		header('Content-type: audio/x-mpegurl');
878		echo '#EXTM3U'."\n";
879		while ($row = mysqli_fetch_array($result)) {
880			echo WindowsShareSlashTranslate($row['filename'])."\n";
881		}
882		exit;
883
884	} else {
885
886		$NonEmptyCommentsCounter = 0;
887		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?nonemptycomments='.urlencode($_REQUEST['nonemptycomments']).'&m3u=1').'">.m3u version</a><br>';
888		echo '<table border="1" cellspacing="0" cellpadding="3">';
889		echo '<tr><th>m3u</th><th>filename</th><th>comments</th></tr>';
890		while ($row = mysqli_fetch_array($result)) {
891			$NonEmptyCommentsCounter++;
892			echo '<tr>';
893			echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">m3u</a></td>';
894			echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
895			if (strlen(trim($row['comment'])) > 0) {
896				echo '<td>'.htmlentities($row['comment']).'</td>';
897			} else {
898				echo '<td><i>space</i></td>';
899			}
900			echo '</tr>';
901		}
902		echo '</table>';
903		echo '<b>'.number_format($NonEmptyCommentsCounter).'</b> files with non-empty comments';
904
905	}
906
907} elseif (!empty($_REQUEST['trackzero'])) {
908
909	$SQLquery  = 'SELECT `filename`, `track`';
910	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
911	$SQLquery .= ' WHERE (`track` <> "")';
912	$SQLquery .= ' AND ((`track` < "1")';
913	$SQLquery .= ' OR (`track` > "99"))';
914	$SQLquery .= ' ORDER BY `filename` ASC';
915	$result = mysqli_query_safe($con, $SQLquery);
916
917	if (!empty($_REQUEST['m3u'])) {
918
919		header('Content-type: audio/x-mpegurl');
920		echo '#EXTM3U'."\n";
921		while ($row = mysqli_fetch_array($result)) {
922			if ((strlen($row['track_number']) > 0) && ($row['track_number'] < 1) || ($row['track_number'] > 99)) {
923				echo WindowsShareSlashTranslate($row['filename'])."\n";
924			}
925		}
926		exit;
927
928	} else {
929
930		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?trackzero='.urlencode($_REQUEST['trackzero']).'&m3u=1').'">.m3u version</a><br>';
931		$TrackZeroCounter = 0;
932		echo '<table border="1" cellspacing="0" cellpadding="3">';
933		echo '<tr><th>m3u</th><th>filename</th><th>track</th></tr>';
934		while ($row = mysqli_fetch_array($result)) {
935			if ((strlen($row['track_number']) > 0) && ($row['track_number'] < 1) || ($row['track_number'] > 99)) {
936				$TrackZeroCounter++;
937				echo '<tr>';
938				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">m3u</a></td>';
939				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
940				echo '<td>'.htmlentities($row['track_number']).'</td>';
941				echo '</tr>';
942			}
943		}
944		echo '</table>';
945		echo '<b>'.number_format($TrackZeroCounter).'</b> files with track "zero"';
946
947	}
948
949
950} elseif (!empty($_REQUEST['titlefeat'])) {
951
952	$SQLquery  = 'SELECT `filename`, `title`';
953	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
954	$SQLquery .= ' WHERE (`title` LIKE "%feat.%")';
955	$SQLquery .= ' ORDER BY `filename` ASC';
956	$result = mysqli_query_safe($con, $SQLquery);
957
958	if (!empty($_REQUEST['m3u'])) {
959
960		header('Content-type: audio/x-mpegurl');
961		echo '#EXTM3U'."\n";
962		while ($row = mysqli_fetch_array($result)) {
963			echo WindowsShareSlashTranslate($row['filename'])."\n";
964		}
965		exit;
966
967	} else {
968
969		echo '<b>'.number_format(mysqli_num_rows($result)).'</b> files with "feat." in the title (instead of the artist)<br><br>';
970		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?titlefeat='.urlencode($_REQUEST['titlefeat']).'&m3u=1').'">.m3u version</a><br>';
971		echo '<table border="1" cellspacing="0" cellpadding="3">';
972		echo '<tr><th>m3u</th><th>filename</th><th>title</th></tr>';
973		while ($row = mysqli_fetch_array($result)) {
974			echo '<tr>';
975			echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">m3u</a></td>';
976			echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
977			echo '<td>'.preg_replace('#(feat\. .*)#i', '<b>\\1</b>', htmlentities($row['title'])).'</td>';
978			echo '</tr>';
979		}
980		echo '</table>';
981
982	}
983
984
985} elseif (!empty($_REQUEST['tracknoalbum'])) {
986
987	$SQLquery  = 'SELECT `filename`, `track`, `album`';
988	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
989	$SQLquery .= ' WHERE (`track` <> "")';
990	$SQLquery .= ' AND (`album` = "")';
991	$SQLquery .= ' ORDER BY `filename` ASC';
992	$result = mysqli_query_safe($con, $SQLquery);
993
994	if (!empty($_REQUEST['m3u'])) {
995
996		header('Content-type: audio/x-mpegurl');
997		echo '#EXTM3U'."\n";
998		while ($row = mysqli_fetch_array($result)) {
999			echo WindowsShareSlashTranslate($row['filename'])."\n";
1000		}
1001		exit;
1002
1003	} else {
1004
1005		echo '<b>'.number_format(mysqli_num_rows($result)).'</b> files with a track number, but no album<br><br>';
1006		echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?tracknoalbum='.urlencode($_REQUEST['tracknoalbum']).'&m3u=1').'">.m3u version</a><br>';
1007		echo '<table border="1" cellspacing="0" cellpadding="3">';
1008		echo '<tr><th>m3u</th><th>filename</th><th>track</th><th>album</th></tr>';
1009		while ($row = mysqli_fetch_array($result)) {
1010			echo '<tr>';
1011			echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">m3u</a></td>';
1012			echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1013			echo '<td>'.htmlentities($row['track_number']).'</td>';
1014			echo '<td>'.htmlentities($row['album']).'</td>';
1015			echo '</tr>';
1016		}
1017		echo '</table>';
1018
1019	}
1020
1021
1022} elseif (!empty($_REQUEST['synchronizetagsfrom']) && !empty($_REQUEST['filename'])) {
1023
1024	echo 'Applying new tags from <b>'.$_REQUEST['synchronizetagsfrom'].'</b> in <b>'.htmlentities($_REQUEST['filename']).'</b><ul>';
1025	$errors = array();
1026	if (SynchronizeAllTags($_REQUEST['filename'], $_REQUEST['synchronizetagsfrom'], 'A12', $errors)) {
1027		echo '<li>Sucessfully wrote tags</li>';
1028	} else {
1029		echo '<li>Tag writing had errors: <ul><li>'.implode('</li><li>', $errors).'</li></ul></li>';
1030	}
1031	echo '</ul>';
1032
1033
1034} elseif (!empty($_REQUEST['unsynchronizedtags'])) {
1035
1036	$NotOKfiles        = 0;
1037	$Autofixedfiles    = 0;
1038	$FieldsToCompare   = array('title', 'artist', 'album', 'year', 'genre', 'comment', 'track_number');
1039	$TagsToCompare     = array('id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false);
1040	$ID3v1FieldLengths = array('title'=>30, 'artist'=>30, 'album'=>30, 'year'=>4, 'genre'=>99, 'comment'=>28);
1041	if (strpos($_REQUEST['unsynchronizedtags'], '2') !== false) {
1042		$TagsToCompare['id3v2'] = true;
1043	}
1044	if (strpos($_REQUEST['unsynchronizedtags'], 'A') !== false) {
1045		$TagsToCompare['ape'] = true;
1046	}
1047	if (strpos($_REQUEST['unsynchronizedtags'], 'L') !== false) {
1048		$TagsToCompare['lyrics3'] = true;
1049	}
1050	if (strpos($_REQUEST['unsynchronizedtags'], '1') !== false) {
1051		$TagsToCompare['id3v1'] = true;
1052	}
1053
1054	echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?unsynchronizedtags='.urlencode($_REQUEST['unsynchronizedtags']).'&autofix=1').'">Auto-fix empty tags</a><br><br>';
1055	echo '<div id="Autofixing"></div>';
1056	echo '<table border="1" cellspacing="0" cellpadding="3">';
1057	echo '<tr>';
1058	echo '<th>View</th>';
1059	echo '<th>Filename</th>';
1060	echo '<th>Combined</th>';
1061	if ($TagsToCompare['id3v2']) {
1062		echo '<th><a href="'.htmlentities($_SERVER['PHP_SELF'].'?unsynchronizedtags='.urlencode($_REQUEST['unsynchronizedtags']).'&autofix=1&autofixforcesource=id3v2&autofixforcedest=A1').'" title="Auto-fix all tags to match ID3v2 contents" onClick="return confirm(\'Are you SURE you want to synchronize all tags to match ID3v2?\');">ID3v2</a></th>';
1063	}
1064	if ($TagsToCompare['ape']) {
1065		echo '<th><a href="'.htmlentities($_SERVER['PHP_SELF'].'?unsynchronizedtags='.urlencode($_REQUEST['unsynchronizedtags']).'&autofix=1&autofixforcesource=ape&autofixforcedest=21').'" title="Auto-fix all tags to match APE contents" onClick="return confirm(\'Are you SURE you want to synchronize all tags to match APE?\');">APE</a></th>';
1066	}
1067	if ($TagsToCompare['lyrics3']) {
1068		echo '<th>Lyrics3</th>';
1069	}
1070	if ($TagsToCompare['id3v1']) {
1071		echo '<th><a href="'.htmlentities($_SERVER['PHP_SELF'].'?unsynchronizedtags='.urlencode($_REQUEST['unsynchronizedtags']).'&autofix=1&autofixforcesource=ape&autofixforcedest=2A').'" title="Auto-fix all tags to match ID3v1 contents" onClick="return confirm(\'Are you SURE you want to synchronize all tags to match ID3v1?\');">ID3v1</a></th>';
1072	}
1073	echo '</tr>';
1074
1075	$SQLquery  = 'SELECT `filename`, `comments_all`, `comments_id3v2`, `comments_ape`, `comments_lyrics3`, `comments_id3v1`';
1076	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1077	$SQLquery .= ' WHERE (`fileformat` = "mp3")';
1078	$SQLquery .= ' ORDER BY `filename` ASC';
1079	$result = mysqli_query_safe($con, $SQLquery);
1080	$lastdir = '';
1081	$serializedCommentsFields = array('all', 'id3v2', 'ape', 'lyrics3', 'id3v1');
1082	while ($row = mysqli_fetch_array($result)) {
1083		set_time_limit(30);
1084		if ($lastdir != dirname($row['filename'])) {
1085			echo '<script type="text/javascript">if (document.getElementById("Autofixing")) document.getElementById("Autofixing").innerHTML = "'.htmlentities($lastdir, ENT_QUOTES).'";</script>';
1086			flush();
1087		}
1088
1089		$FileOK      = true;
1090		$Mismatched  = array('id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false);
1091		$SemiMatched = array('id3v2'=>false, 'ape'=>false, 'lyrics3'=>false, 'id3v1'=>false);
1092		$EmptyTags   = array('id3v2'=>true,  'ape'=>true,  'lyrics3'=>true,  'id3v1'=>true);
1093
1094		foreach ($serializedCommentsFields as $field) {
1095			$Comments[$field] = array();
1096			ob_start();
1097			if ($unserialized = unserialize($row['comments_'.$field])) {
1098				$Comments[$field] = $unserialized;
1099			}
1100			$errormessage = ob_get_contents();
1101			ob_end_clean();
1102		}
1103
1104		if (isset($Comments['ape']['tracknumber'])) {
1105			$Comments['ape']['track_number'] = $Comments['ape']['tracknumber'];
1106			unset($Comments['ape']['tracknumber']);
1107		}
1108		if (isset($Comments['ape']['track'])) {
1109			$Comments['ape']['track_number'] = $Comments['ape']['track'];
1110			unset($Comments['ape']['track']);
1111		}
1112		if (!empty($Comments['all']['track'])) {
1113			$besttrack = '';
1114			foreach ($Comments['all']['track'] as $key => $value) {
1115				if (strlen($value) > strlen($besttrack)) {
1116					$besttrack = $value;
1117				}
1118			}
1119			$Comments['all']['track_number'] = array(0=>$besttrack);
1120		}
1121
1122		$ThisLine  = '<tr>';
1123		$ThisLine .= '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">view</a></td>';
1124		$ThisLine .= '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1125		$tagvalues = '';
1126		foreach ($FieldsToCompare as $fieldname) {
1127			$tagvalues .= $fieldname.' = '.(!empty($Comments['all'][$fieldname]) ? implode(" \n", $Comments['all'][$fieldname]) : '')." \n";
1128		}
1129		$ThisLine .= '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?synchronizetagsfrom=all&filename='.urlencode($row['filename'])).'" title="'.htmlentities(rtrim($tagvalues, "\n"), ENT_QUOTES).'" target="retagwindow">all</a></td>';
1130		foreach ($TagsToCompare as $tagtype => $CompareThisTagType) {
1131			if ($CompareThisTagType) {
1132				$tagvalues = '';
1133				foreach ($FieldsToCompare as $fieldname) {
1134
1135					if ($tagtype == 'id3v1') {
1136
1137						getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true);
1138						if (($fieldname == 'genre') && !empty($Comments['all'][$fieldname][0]) && !getid3_id3v1::LookupGenreID($Comments['all'][$fieldname][0])) {
1139
1140							// non-standard genres can never match, so just ignore
1141							$tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n";
1142
1143						} elseif ($fieldname == 'comment') {
1144
1145							if (isset($Comments[$tagtype][$fieldname][0]) && isset($Comments['all'][$fieldname][0]) && (rtrim(substr($Comments[$tagtype][$fieldname][0], 0, 28)) != rtrim(substr($Comments['all'][$fieldname][0], 0, 28)))) {
1146								$tagvalues .= $fieldname.' = [['.$Comments[$tagtype][$fieldname][0].']]'."\n";
1147								if (trim(strtolower(RemoveAccents(substr($Comments[$tagtype][$fieldname][0], 0, 28)))) == trim(strtolower(RemoveAccents(substr($Comments['all'][$fieldname][0], 0, 28))))) {
1148									$SemiMatched[$tagtype] = true;
1149								} else {
1150									$Mismatched[$tagtype]  = true;
1151								}
1152								$FileOK = false;
1153							} else {
1154								$tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n";
1155							}
1156
1157						} elseif ($fieldname == 'track_number') {
1158
1159							// intval('01/20') == intval('1')
1160							$trackA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '');
1161							$trackB = (isset($Comments['all'][$fieldname][0])    ? $Comments['all'][$fieldname][0]    : '');
1162							if (intval($trackA) != intval($trackB)) {
1163								$tagvalues .= $fieldname.' = [['.$trackA.']]'."\n";
1164								$Mismatched[$tagtype]  = true;
1165								$FileOK = false;
1166							} else {
1167								$tagvalues .= $fieldname.' = '.$trackA."\n";
1168							}
1169
1170						} elseif ((isset($Comments[$tagtype][$fieldname][0]) ? rtrim(substr($Comments[$tagtype][$fieldname][0], 0, 30)) : '') != (isset($Comments['all'][$fieldname][0]) ? rtrim(substr($Comments['all'][$fieldname][0], 0, 30)) : '')) {
1171
1172							$tagvalues .= $fieldname.' = [['.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '').']]'."\n";
1173							if (strtolower(RemoveAccents(trim(substr((isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : ''), 0, 30)))) == strtolower(RemoveAccents(trim(substr((isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : ''), 0, 30))))) {
1174								$SemiMatched[$tagtype] = true;
1175							} else {
1176								$Mismatched[$tagtype]  = true;
1177							}
1178							$FileOK = false;
1179							if (!empty($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) {
1180								$EmptyTags[$tagtype] = false;
1181							}
1182
1183						} else {
1184
1185							$tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n";
1186							if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) {
1187								$EmptyTags[$tagtype] = false;
1188							}
1189
1190						}
1191
1192					} elseif (($tagtype == 'ape') && ($fieldname == 'year')) {
1193
1194						if (((isset($Comments['ape']['date'][0]) ? $Comments['ape']['date'][0] : '') != (isset($Comments['all']['year'][0]) ? $Comments['all']['year'][0] : '')) && ((isset($Comments['ape']['year'][0]) ? $Comments['ape']['year'][0] : '') != (isset($Comments['all']['year'][0]) ? $Comments['all']['year'][0] : ''))) {
1195
1196							$tagvalues .= $fieldname.' = [['.(isset($Comments['ape']['date'][0]) ? $Comments['ape']['date'][0] : '').']]'."\n";
1197							$Mismatched[$tagtype]  = true;
1198							$FileOK = false;
1199							if (isset($Comments['ape']['date'][0]) && (strlen(trim($Comments['ape']['date'][0])) > 0)) {
1200								$EmptyTags[$tagtype] = false;
1201							}
1202
1203						} else {
1204
1205							$tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n";
1206							if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) {
1207								$EmptyTags[$tagtype] = false;
1208							}
1209
1210						}
1211
1212					} elseif (($fieldname == 'genre') && !empty($Comments['all'][$fieldname]) && !empty($Comments[$tagtype][$fieldname]) && in_array($Comments[$tagtype][$fieldname][0], $Comments['all'][$fieldname])) {
1213
1214						$tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n";
1215						if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) {
1216							$EmptyTags[$tagtype] = false;
1217						}
1218
1219					} elseif ((isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '') != (isset($Comments['all'][$fieldname][0]) ? $Comments['all'][$fieldname][0] : '')) {
1220
1221						$skiptracknumberfield = false;
1222						switch ($fieldname) {
1223							case 'track':
1224							case 'tracknumber':
1225							case 'track_number':
1226								$trackA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '');
1227								$trackB = (isset($Comments['all'][$fieldname][0])    ? $Comments['all'][$fieldname][0]    : '');
1228								if (intval($trackA) == intval($trackB)) {
1229									$skiptracknumberfield = true;
1230								}
1231								break;
1232						}
1233						if (!$skiptracknumberfield) {
1234							$tagvalues .= $fieldname.' = [['.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '').']]'."\n";
1235							$tagA = (isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '');
1236							$tagB = (isset($Comments['all'][$fieldname][0])    ? $Comments['all'][$fieldname][0]    : '');
1237							if (trim(strtolower(RemoveAccents($tagA))) == trim(strtolower(RemoveAccents($tagB)))) {
1238								$SemiMatched[$tagtype] = true;
1239							} else {
1240								$Mismatched[$tagtype]  = true;
1241							}
1242							$FileOK = false;
1243							if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) {
1244								$EmptyTags[$tagtype] = false;
1245							}
1246						}
1247
1248					} else {
1249
1250						$tagvalues .= $fieldname.' = '.(isset($Comments[$tagtype][$fieldname][0]) ? $Comments[$tagtype][$fieldname][0] : '')."\n";
1251						if (isset($Comments[$tagtype][$fieldname][0]) && (strlen(trim($Comments[$tagtype][$fieldname][0])) > 0)) {
1252							$EmptyTags[$tagtype] = false;
1253						}
1254
1255					}
1256				}
1257
1258				if ($EmptyTags[$tagtype]) {
1259					$FileOK = false;
1260					$ThisLine .= '<td bgcolor="#0099cc">';
1261				} elseif ($SemiMatched[$tagtype]) {
1262					$ThisLine .= '<td bgcolor="#ff9999">';
1263				} elseif ($Mismatched[$tagtype]) {
1264					$ThisLine .= '<td bgcolor="#ff0000">';
1265				} else {
1266					$ThisLine .= '<td bgcolor="#00cc00">';
1267				}
1268				$ThisLine .= '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?synchronizetagsfrom='.$tagtype.'&filename='.urlencode($row['filename'])).'" title="'.htmlentities(rtrim($tagvalues, "\n"), ENT_QUOTES).'" TARGET="retagwindow">'.$tagtype.'</a>';
1269				$ThisLine .= '</td>';
1270			}
1271		}
1272		$ThisLine .= '</tr>';
1273
1274		if (!$FileOK) {
1275			$NotOKfiles++;
1276
1277			echo '<script type="text/javascript">if (document.getElementById("Autofixing")) document.getElementById("Autofixing").innerHTML = "'.htmlentities($row['filename'], ENT_QUOTES).'";</script>';
1278			flush();
1279
1280			if (!empty($_REQUEST['autofix'])) {
1281
1282				$AnyMismatched = false;
1283				foreach ($Mismatched as $key => $value) {
1284					if ($value && ($EmptyTags["$key"] === false)) {
1285						$AnyMismatched = true;
1286					}
1287				}
1288				if ($AnyMismatched && empty($_REQUEST['autofixforcesource'])) {
1289
1290					echo $ThisLine;
1291
1292				} else {
1293
1294					$TagsToSynch = '';
1295					foreach ($EmptyTags as $key => $value) {
1296						if ($value) {
1297							switch ($key) {
1298								case 'id3v1':
1299									$TagsToSynch .= '1';
1300									break;
1301								case 'id3v2':
1302									$TagsToSynch .= '2';
1303									break;
1304								case 'ape':
1305									$TagsToSynch .= 'A';
1306									break;
1307							}
1308						}
1309					}
1310
1311					$autofixforcesource = (!empty($_REQUEST['autofixforcesource']) ? $_REQUEST['autofixforcesource'] : 'all');
1312					$TagsToSynch        = (!empty($_REQUEST['autofixforcedest'])   ? $_REQUEST['autofixforcedest']   : $TagsToSynch);
1313
1314					$errors = array();
1315					if (SynchronizeAllTags($row['filename'], $autofixforcesource, $TagsToSynch, $errors)) {
1316						$Autofixedfiles++;
1317						echo '<tr bgcolor="#00CC00">';
1318					} else {
1319						echo '<tr bgcolor="#FF0000">';
1320					}
1321					echo '<td>&nbsp;</th>';
1322					echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename'])).'" title="'.htmlentities(implode("\n", $errors), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1323					echo '<td><table border="0">';
1324					echo '<tr><td><b>'.$TagsToSynch.'</b></td></tr>';
1325					echo '</table></td></tr>';
1326				}
1327
1328			} else {
1329
1330				echo $ThisLine;
1331
1332			}
1333		}
1334	}
1335
1336	echo '</table><br>';
1337	echo '<script type="text/javascript">if (document.getElementById("Autofixing")) document.getElementById("Autofixing").innerHTML = "";</script>';
1338	echo 'Found <b>'.number_format($NotOKfiles).'</b> files with unsynchronized tags, and auto-fixed '.number_format($Autofixedfiles).' of them.';
1339
1340} elseif (!empty($_REQUEST['filenamepattern'])) {
1341
1342	$patterns['A'] = 'artist';
1343	$patterns['T'] = 'title';
1344	$patterns['M'] = 'album';
1345	$patterns['N'] = 'track';
1346	$patterns['G'] = 'genre';
1347	$patterns['R'] = 'remix';
1348
1349	$FieldsToUse = explode(' ', wordwrap(preg_replace('#[^A-Z]#i', '', $_REQUEST['filenamepattern']), 1, ' ', 1));
1350	//$FieldsToUse = explode(' ', wordwrap($_REQUEST['filenamepattern'], 1, ' ', 1));
1351	foreach ($FieldsToUse as $FieldID) {
1352		$FieldNames[] = $patterns["$FieldID"];
1353	}
1354
1355	$SQLquery  = 'SELECT `filename`, `fileformat`, '.implode(', ', $FieldNames);
1356	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1357	$SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1358	$SQLquery .= ' ORDER BY `filename` ASC';
1359	$result = mysqli_query_safe($con, $SQLquery);
1360	echo 'Files that do not match naming pattern: (<a href="'.htmlentities($_SERVER['PHP_SELF'].'?filenamepattern='.urlencode($_REQUEST['filenamepattern']).'&autofix=1').'">auto-fix</a>)<br>';
1361	echo '<table border="1" cellspacing="0" cellpadding="3">';
1362	echo '<tr><th>view</th><th>Why</th><td><b>Actual filename</b><br>(click to play/edit file)</td><td><b>Correct filename (based on tags)</b>'.(empty($_REQUEST['autofix']) ? '<br>(click to rename file to this)' : '').'</td></tr>';
1363	$nonmatchingfilenames = 0;
1364	$Pattern = $_REQUEST['filenamepattern'];
1365	$PatternLength = strlen($Pattern);
1366	while ($row = mysqli_fetch_array($result)) {
1367		set_time_limit(10);
1368		$PatternFilename = '';
1369		for ($i = 0; $i < $PatternLength; $i++) {
1370			if (isset($patterns[$Pattern[$i]])) {
1371				$PatternFilename .= trim(strtr($row[$patterns[$Pattern[$i]]], ':\\*<>|', ';-¤«»¦'), ' ');
1372			} else {
1373				$PatternFilename .= $Pattern[$i];
1374			}
1375		}
1376
1377		// Replace "~" with "-" if characters immediately before and after are both numbers,
1378		// "/" has been replaced with "~" above which is good for multi-song medley dividers,
1379		// but for things like 24/7, 7/8ths, etc it looks better if it's 24-7, 7-8ths, etc.
1380		$PatternFilename = preg_replace('#([ a-z]+)/([ a-z]+)#i', '\\1~\\2', $PatternFilename);
1381		$PatternFilename = str_replace('/',  '×',  $PatternFilename);
1382
1383		$PatternFilename = str_replace('?',  '¿',  $PatternFilename);
1384		$PatternFilename = str_replace(' "', ' “', $PatternFilename);
1385		$PatternFilename = str_replace('("', '(“', $PatternFilename);
1386		$PatternFilename = str_replace('-"', '-“', $PatternFilename);
1387		$PatternFilename = str_replace('" ', '” ', $PatternFilename.' ');
1388		$PatternFilename = str_replace('"',  '”',  $PatternFilename);
1389		$PatternFilename = str_replace('  ', ' ',  $PatternFilename);
1390
1391
1392		$ParenthesesPairs = array('()', '[]', '{}');
1393		foreach ($ParenthesesPairs as $pair) {
1394
1395			// multiple remixes are stored tab-seperated in the database.
1396			// change "{2000 Version\tSomebody Remix}" into "{2000 Version} {Somebody Remix}"
1397			while (preg_match('#^(.*)'.preg_quote($pair[0]).'([^'.preg_quote($pair[1]).']*)('."\t".')([^'.preg_quote($pair[0]).']*)'.preg_quote($pair[1]).'#', $PatternFilename, $matches)) {
1398				$PatternFilename = $matches[1].$pair[0].$matches[2].$pair[1].' '.$pair[0].$matches[4].$pair[1];
1399			}
1400
1401			// remove empty parenthesized pairs (probably where no track numbers, remix version, etc)
1402			$PatternFilename = preg_replace('#'.preg_quote($pair).'#', '', $PatternFilename);
1403
1404			// "[01]  - Title With No Artist.mp3"  ==>  "[01] Title With No Artist.mp3"
1405			$PatternFilename = preg_replace('#'.preg_quote($pair[1]).' +\- #', $pair[1].' ', $PatternFilename);
1406
1407		}
1408
1409		// get rid of leading & trailing spaces if end items (artist or title for example) are missing
1410		$PatternFilename  = trim($PatternFilename, ' -');
1411
1412		if (!$PatternFilename) {
1413			// no tags to create a filename from -- skip this file
1414			continue;
1415		}
1416		$PatternFilename .= '.'.$row['fileformat'];
1417
1418		$ActualFilename = basename($row['filename']);
1419		if ($ActualFilename != $PatternFilename) {
1420
1421			$NotMatchedReasons = '';
1422			if (strtolower($ActualFilename) === strtolower($PatternFilename)) {
1423				$NotMatchedReasons .= 'Aa ';
1424			} elseif (RemoveAccents($ActualFilename) === RemoveAccents($PatternFilename)) {
1425				$NotMatchedReasons .= 'ée ';
1426			}
1427
1428
1429			$actualExt  = '.'.fileextension($ActualFilename);
1430			$patternExt = '.'.fileextension($PatternFilename);
1431			$ActualFilenameNoExt  = (($actualExt  != '.') ? substr($ActualFilename,   0, 0 - strlen($actualExt))  : $ActualFilename);
1432			$PatternFilenameNoExt = (($patternExt != '.') ? substr($PatternFilename,  0, 0 - strlen($patternExt)) : $PatternFilename);
1433
1434			if (strpos($PatternFilenameNoExt, $ActualFilenameNoExt) !== false) {
1435				$DifferenceBoldedName  = str_replace($ActualFilenameNoExt, '</b>'.$ActualFilenameNoExt.'<b>', $PatternFilenameNoExt);
1436			} else {
1437				$ShortestNameLength = min(strlen($ActualFilenameNoExt), strlen($PatternFilenameNoExt));
1438				for ($DifferenceOffset = 0; $DifferenceOffset < $ShortestNameLength; $DifferenceOffset++) {
1439					if ($ActualFilenameNoExt[$DifferenceOffset] !== $PatternFilenameNoExt[$DifferenceOffset]) {
1440						break;
1441					}
1442				}
1443				$DifferenceBoldedName  = '</b>'.substr($PatternFilenameNoExt, 0, $DifferenceOffset).'<b>'.substr($PatternFilenameNoExt, $DifferenceOffset);
1444			}
1445			$DifferenceBoldedName .= (($actualExt == $patternExt) ? '</b>'.$patternExt.'<b>' : $patternExt);
1446
1447
1448			echo '<tr>';
1449			echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename'])).'">view</a></td>';
1450			echo '<td>&nbsp;'.$NotMatchedReasons.'</td>';
1451			echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($ActualFilename).'</a></td>';
1452
1453			if (!empty($_REQUEST['autofix'])) {
1454
1455				$results = '';
1456				if (RenameFileFromTo($row['filename'], dirname($row['filename']).'/'.$PatternFilename, $results)) {
1457					echo '<TD BGCOLOR="#009900">';
1458				} else {
1459					echo '<TD BGCOLOR="#FF0000">';
1460				}
1461				echo '<b>'.$DifferenceBoldedName.'</b></td>';
1462
1463
1464			} else {
1465
1466				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?filenamepattern='.urlencode($_REQUEST['filenamepattern']).'&renamefilefrom='.urlencode($row['filename']).'&renamefileto='.urlencode(dirname($row['filename']).'/'.$PatternFilename)).'" title="'.htmlentities(basename($row['filename'])."\n".basename($PatternFilename), ENT_QUOTES).'" target="renamewindow">';
1467				echo '<b>'.$DifferenceBoldedName.'</b></a></td>';
1468
1469			}
1470			echo '</tr>';
1471
1472			$nonmatchingfilenames++;
1473		}
1474	}
1475	echo '</table><br>';
1476	echo 'Found '.number_format($nonmatchingfilenames).' files that do not match naming pattern<br>';
1477
1478
1479} elseif (!empty($_REQUEST['encoderoptionsdistribution'])) {
1480
1481	if (isset($_REQUEST['showtagfiles'])) {
1482		$SQLquery  = 'SELECT `filename`, `encoder_options` FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1483		$SQLquery .= ' WHERE (`encoder_options` LIKE "'.mysqli_real_escape_string($con, $_REQUEST['showtagfiles']).'")';
1484		$SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1485		$SQLquery .= ' ORDER BY `filename` ASC';
1486		$result = mysqli_query_safe($con, $SQLquery);
1487
1488		if (!empty($_REQUEST['m3u'])) {
1489
1490			header('Content-type: audio/x-mpegurl');
1491			echo '#EXTM3U'."\n";
1492			while ($row = mysqli_fetch_array($result)) {
1493				echo WindowsShareSlashTranslate($row['filename'])."\n";
1494			}
1495			exit;
1496
1497		} else {
1498
1499			echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?encoderoptionsdistribution=1').'">Show all Encoder Options</a><hr>';
1500			echo 'Files with Encoder Options <b>'.$_REQUEST['showtagfiles'].'</b>:<br>';
1501			echo '<table border="1" cellspacing="0" cellpadding="3">';
1502			while ($row = mysqli_fetch_array($result)) {
1503				echo '<tr>';
1504				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1505				echo '<td>'.$row['encoder_options'].'</td>';
1506				echo '</tr>';
1507			}
1508			echo '</table>';
1509
1510		}
1511
1512	} elseif (!isset($_REQUEST['m3u'])) {
1513
1514		$SQLquery  = 'SELECT `encoder_options`, COUNT(*) AS `num` FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1515		$SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1516		$SQLquery .= ' GROUP BY `encoder_options`';
1517		$SQLquery .= ' ORDER BY (`encoder_options` LIKE "LAME%") DESC, (`encoder_options` LIKE "CBR%") DESC, `num` DESC, `encoder_options` ASC';
1518		$result = mysqli_query_safe($con, $SQLquery);
1519		echo 'Files with Encoder Options:<br>';
1520		echo '<table border="1" cellspacing="0" cellpadding="3">';
1521		echo '<tr><th>Encoder Options</th><th>Count</th><th>M3U</th></tr>';
1522		while ($row = mysqli_fetch_array($result)) {
1523			echo '<tr>';
1524			echo '<td>'.$row['encoder_options'].'</td>';
1525			echo '<TD ALIGN="RIGHT"><a href="'.htmlentities($_SERVER['PHP_SELF'].'?encoderoptionsdistribution=1&showtagfiles='.($row['encoder_options'] ? urlencode($row['encoder_options']) : '')).'">'.number_format($row['num']).'</a></td>';
1526			echo '<TD ALIGN="RIGHT"><a href="'.htmlentities($_SERVER['PHP_SELF'].'?encoderoptionsdistribution=1&showtagfiles='.($row['encoder_options'] ? urlencode($row['encoder_options']) : '').'&m3u=.m3u').'">m3u</a></td>';
1527			echo '</tr>';
1528		}
1529		echo '</table><hr>';
1530
1531	}
1532
1533} elseif (!empty($_REQUEST['tagtypes'])) {
1534
1535	if (!isset($_REQUEST['m3u'])) {
1536		$SQLquery  = 'SELECT `tags`, COUNT(*) AS `num` FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1537		$SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1538		$SQLquery .= ' GROUP BY `tags`';
1539		$SQLquery .= ' ORDER BY `num` DESC';
1540		$result = mysqli_query_safe($con, $SQLquery);
1541		echo 'Files with tags:<br>';
1542		echo '<table border="1" cellspacing="0" cellpadding="3">';
1543		echo '<tr><th>Tags</th><th>Count</th><th>M3U</th></tr>';
1544		while ($row = mysqli_fetch_array($result)) {
1545			echo '<tr>';
1546			echo '<td>'.$row['tags'].'</td>';
1547			echo '<td align="right"><a href="'.htmlentities($_SERVER['PHP_SELF'].'?tagtypes=1&showtagfiles='.($row['tags'] ? urlencode($row['tags']) : '')).'">'.number_format($row['num']).'</a></td>';
1548			echo '<td align="right"><a href="'.htmlentities($_SERVER['PHP_SELF'].'?tagtypes=1&showtagfiles='.($row['tags'] ? urlencode($row['tags']) : '').'&m3u=.m3u').'">m3u</a></td>';
1549			echo '</tr>';
1550		}
1551		echo '</table><hr>';
1552	}
1553
1554	if (isset($_REQUEST['showtagfiles'])) {
1555		$SQLquery  = 'SELECT `filename`, `tags` FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1556		$SQLquery .= ' WHERE (`tags` LIKE "'.mysqli_real_escape_string($con, $_REQUEST['showtagfiles']).'")';
1557		$SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1558		$SQLquery .= ' ORDER BY `filename` ASC';
1559		$result = mysqli_query_safe($con, $SQLquery);
1560
1561		if (!empty($_REQUEST['m3u'])) {
1562
1563			header('Content-type: audio/x-mpegurl');
1564			echo '#EXTM3U'."\n";
1565			while ($row = mysqli_fetch_array($result)) {
1566				echo WindowsShareSlashTranslate($row['filename'])."\n";
1567			}
1568			exit;
1569
1570		} else {
1571
1572			echo '<table border="1" cellspacing="0" cellpadding="3">';
1573			while ($row = mysqli_fetch_array($result)) {
1574				echo '<tr>';
1575				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1576				echo '<td>'.$row['tags'].'</td>';
1577				echo '</tr>';
1578			}
1579			echo '</table>';
1580
1581		}
1582	}
1583
1584
1585} elseif (!empty($_REQUEST['md5datadupes'])) {
1586
1587	$OtherFormats = '';
1588	$AVFormats    = '';
1589
1590	$SQLquery  = 'SELECT `md5_data`, `filename`, COUNT(*) AS `num`';
1591	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1592	$SQLquery .= ' WHERE (`md5_data` <> "")';
1593	$SQLquery .= ' GROUP BY `md5_data`';
1594	$SQLquery .= ' ORDER BY `num` DESC';
1595	$result = mysqli_query_safe($con, $SQLquery);
1596	while (($row = mysqli_fetch_array($result)) && ($row['num'] > 1)) {
1597		set_time_limit(30);
1598
1599		$filenames = array();
1600		$tags      = array();
1601		$md5_data  = array();
1602		$SQLquery  = 'SELECT `fileformat`, `filename`, `tags`';
1603		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1604		$SQLquery .= ' WHERE (`md5_data` = "'.mysqli_real_escape_string($con, $row['md5_data']).'")';
1605		$SQLquery .= ' ORDER BY `filename` ASC';
1606		$result2 = mysqli_query_safe($con, $SQLquery);
1607		while ($row2 = mysqli_fetch_array($result2)) {
1608			$thisfileformat = $row2['fileformat'];
1609			$filenames[] = $row2['filename'];
1610			$tags[]      = $row2['tags'];
1611			$md5_data[]  = $row['md5_data'];
1612		}
1613
1614		$thisline  = '<tr>';
1615		$thisline .= '<TD VALIGN="TOP" style="font-family: monospace;">'.implode('<br>', $md5_data).'</td>';
1616		$thisline .= '<TD VALIGN="TOP" NOWRAP>'.implode('<br>', $tags).'</td>';
1617		$thisline .= '<TD VALIGN="TOP">'.implode('<br>', $filenames).'</td>';
1618		$thisline .= '</tr>';
1619
1620		if (in_array($thisfileformat, $IgnoreNoTagFormats)) {
1621			$OtherFormats .= $thisline;
1622		} else {
1623			$AVFormats .= $thisline;
1624		}
1625	}
1626	echo 'Duplicated MD5_DATA (Audio/Video files):<table border="1" cellspacing="0" cellpadding="2">';
1627	echo $AVFormats.'</table><hr>';
1628	echo 'Duplicated MD5_DATA (Other files):<table border="1" cellspacing="0" cellpadding="2">';
1629	echo $OtherFormats.'</table><hr>';
1630
1631
1632} elseif (!empty($_REQUEST['artisttitledupes'])) {
1633
1634	if (isset($_REQUEST['m3uartist']) && isset($_REQUEST['m3utitle'])) {
1635
1636		header('Content-type: audio/x-mpegurl');
1637		echo '#EXTM3U'."\n";
1638		$SQLquery  = 'SELECT `filename`';
1639		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1640		$SQLquery .= ' WHERE (`artist` = "'.mysqli_real_escape_string($con, $_REQUEST['m3uartist']).'")';
1641		$SQLquery .= ' AND (`title` = "'.mysqli_real_escape_string($con, $_REQUEST['m3utitle']).'")';
1642		$SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC';
1643		$result = mysqli_query_safe($con, $SQLquery);
1644		while ($row = mysqli_fetch_array($result)) {
1645			echo WindowsShareSlashTranslate($row['filename'])."\n";
1646		}
1647		exit;
1648
1649	}
1650
1651	$SQLquery  = 'SELECT `artist`, `title`, `filename`, COUNT(*) AS `num`';
1652	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1653	$SQLquery .= ' WHERE (`artist` <> "")';
1654	$SQLquery .= ' AND (`title` <> "")';
1655	$SQLquery .= ' GROUP BY `artist`, `title`'.(!empty($_REQUEST['samemix']) ? ', `remix`' : '');
1656	$SQLquery .= ' ORDER BY `num` DESC, `artist` ASC, `title` ASC, `playtime_seconds` ASC, `remix` ASC';
1657	$result = mysqli_query_safe($con, $SQLquery);
1658	$uniquetitles = 0;
1659	$uniquefiles  = 0;
1660
1661	if (!empty($_REQUEST['m3u'])) {
1662
1663		header('Content-type: audio/x-mpegurl');
1664		echo '#EXTM3U'."\n";
1665		while (($row = mysqli_fetch_array($result)) && ($row['num'] > 1)) {
1666			$SQLquery  = 'SELECT `filename`';
1667			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1668			$SQLquery .= ' WHERE (`artist` = "'.mysqli_real_escape_string($con, $row['artist']).'")';
1669			$SQLquery .= ' AND (`title` = "'.mysqli_real_escape_string($con, $row['title']).'")';
1670			if (!empty($_REQUEST['samemix'])) {
1671				$SQLquery .= ' AND (`remix` = "'.mysqli_real_escape_string($con, $row['remix']).'")';
1672			}
1673			$SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC';
1674			$result2 = mysqli_query_safe($con, $SQLquery);
1675			while ($row2 = mysqli_fetch_array($result2)) {
1676				echo WindowsShareSlashTranslate($row2['filename'])."\n";
1677			}
1678		}
1679		exit;
1680
1681	} else {
1682
1683		echo 'Duplicated aritst + title: (<a href="'.htmlentities($_SERVER['PHP_SELF'].'?artisttitledupes=1&samemix=1').'">Identical Mix/Version only</a>)<br>';
1684		echo '(<a href="'.htmlentities($_SERVER['PHP_SELF'].'?artisttitledupes=1&m3u=.m3u').'">.m3u version</a>)<br>';
1685		echo '<table border="1" cellspacing="0" cellpadding="2">';
1686		echo '<tr><th colspan="3">&nbsp;</th><th>Artist</th><th>Title</th><th>Version</th><th>&nbsp;</th><th>&nbsp;</th><th>Filename</th></tr>';
1687
1688		while (($row = mysqli_fetch_array($result)) && ($row['num'] > 1)) {
1689			$uniquetitles++;
1690			set_time_limit(30);
1691
1692			$filenames = array();
1693			$artists   = array();
1694			$titles    = array();
1695			$remixes   = array();
1696			$bitrates  = array();
1697			$playtimes = array();
1698			$SQLquery  = 'SELECT `filename`, `artist`, `title`, `remix`, `audio_bitrate`, `vbr_method`, `playtime_seconds`, `encoder_options`';
1699			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1700			$SQLquery .= ' WHERE (`artist` = "'.mysqli_real_escape_string($con, $row['artist']).'")';
1701			$SQLquery .= ' AND (`title` = "'.mysqli_real_escape_string($con, $row['title']).'")';
1702			$SQLquery .= ' ORDER BY `playtime_seconds` ASC, `remix` ASC, `filename` ASC';
1703			$result2 = mysqli_query_safe($con, $SQLquery);
1704			while ($row2 = mysqli_fetch_array($result2)) {
1705				$uniquefiles++;
1706				$filenames[] = $row2['filename'];
1707				$artists[]   = $row2['artist'];
1708				$titles[]    = $row2['title'];
1709				$remixes[]   = $row2['remix'];
1710				if ($row2['vbr_method']) {
1711					$bitrates[]  = '<B'.($row2['encoder_options'] ? ' style="text-decoration: underline; cursor: help;" title="'.$row2['encoder_options'] : '').'">'.BitrateText($row2['audio_bitrate'] / 1000).'</b>';
1712				} else {
1713					$bitrates[]  = BitrateText($row2['audio_bitrate'] / 1000);
1714				}
1715				$playtimes[] = getid3_lib::PlaytimeString($row2['playtime_seconds']);
1716			}
1717
1718			echo '<tr>';
1719			echo '<td nowrap valign="top">';
1720			foreach ($filenames as $file) {
1721				echo '<a href="'.htmlentities('demo.browse.php?deletefile='.urlencode($file).'&noalert=1').'" onClick="return confirm(\'Are you sure you want to delete '.addslashes($file).'? \n(this action cannot be un-done)\');" title="'.htmlentities('Permanently delete '."\n".$file, ENT_QUOTES).'" target="deletedupewindow">delete</a><br>';
1722			}
1723			echo '</td>';
1724			echo '<td nowrap valign="top">';
1725			foreach ($filenames as $file) {
1726				echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($file)).'">play</a><br>';
1727			}
1728			echo '</td>';
1729			echo '<td valign="middle" align="center" ><a href="'.htmlentities($_SERVER['PHP_SELF'].'?artisttitledupes=1&m3uartist='.urlencode($artists[0]).'&m3utitle='.urlencode($titles[0])).'">play all</a></td>';
1730			echo '<td valign="top" nowrap>'.implode('<br>', $artists).'</td>';
1731			echo '<td valign="top" nowrap>'.implode('<br>', $titles).'</td>';
1732			echo '<td valign="top" nowrap>'.implode('<br>', $remixes).'</td>';
1733			echo '<td valign="top" nowrap align="right">'.implode('<br>', $bitrates).'</td>';
1734			echo '<td valign="top" nowrap align="right">'.implode('<br>', $playtimes).'</td>';
1735
1736			echo '<td valign="top" nowrap align="left"><table border="0" cellspacing="0" cellpadding="0">';
1737			foreach ($filenames as $file) {
1738				echo '<tr><td nowrap align="right"><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($file)).'"><span style="color: #339966;">'.dirname($file).'/</span>'.basename($file).'</a></td></tr>';
1739			}
1740			echo '</table></td>';
1741
1742			echo '</tr>';
1743		}
1744
1745	}
1746	echo '</table>';
1747	echo number_format($uniquefiles).' files with '.number_format($uniquetitles).' unique <i>aritst + title</i><br>';
1748	echo '<hr>';
1749
1750} elseif (!empty($_REQUEST['filetypelist'])) {
1751
1752	list($fileformat, $audioformat) = explode('|', $_REQUEST['filetypelist']);
1753	$SQLquery  = 'SELECT `filename`, `fileformat`, `audio_dataformat`';
1754	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1755	$SQLquery .= ' WHERE (`fileformat` = "'.mysqli_real_escape_string($con, $fileformat).'")';
1756	$SQLquery .= ' AND (`audio_dataformat` = "'.mysqli_real_escape_string($con, $audioformat).'")';
1757	$SQLquery .= ' ORDER BY `filename` ASC';
1758	$result = mysqli_query_safe($con, $SQLquery);
1759	echo 'Files of format <b>'.$fileformat.'.'.$audioformat.'</b>:<table border="1" cellspacing="0" cellpadding="4">';
1760	echo '<tr><th>file</th><th>audio</th><th>filename</th></tr>';
1761	while ($row = mysqli_fetch_array($result)) {
1762		echo '<tr>';
1763		echo '<td>'.$row['fileformat'].'</td>';
1764		echo '<td>'.$row['audio_dataformat'].'</td>';
1765		echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1766		echo '</tr>';
1767	}
1768	echo '</table><hr>';
1769
1770} elseif (!empty($_REQUEST['trackinalbum'])) {
1771
1772	$SQLquery  = 'SELECT `filename`, `album`';
1773	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1774	$SQLquery .= ' WHERE (`album` LIKE "% [%")';
1775	$SQLquery .= ' ORDER BY `album` ASC, `filename` ASC';
1776	$result = mysqli_query_safe($con, $SQLquery);
1777	if (!empty($_REQUEST['m3u'])) {
1778
1779		header('Content-type: audio/x-mpegurl');
1780		echo '#EXTM3U'."\n";
1781		while ($row = mysqli_fetch_array($result)) {
1782			echo WindowsShareSlashTranslate($row['filename'])."\n";
1783		}
1784		exit;
1785
1786	} elseif (!empty($_REQUEST['autofix'])) {
1787
1788		getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true);
1789		getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
1790
1791		while ($row = mysqli_fetch_array($result)) {
1792			set_time_limit(30);
1793			$ThisFileInfo = $getID3->analyze($filename);
1794			$getID3->CopyTagsToComments($ThisFileInfo);
1795
1796			if (!empty($ThisFileInfo['tags'])) {
1797
1798				$Album = trim(str_replace(strstr($ThisFileInfo['comments']['album'][0], ' ['), '', $ThisFileInfo['comments']['album'][0]));
1799				$Track = (string) intval(str_replace(' [', '', str_replace(']', '', strstr($ThisFileInfo['comments']['album'][0], ' ['))));
1800				if ($Track == '0') {
1801					$Track = '';
1802				}
1803				if ($Album && $Track) {
1804					echo '<hr>'.htmlentities($row['filename']).'<br>';
1805					echo '<i>'.htmlentities($Album).'</i> (track #'.$Track.')<br>';
1806					echo '<b>ID3v2:</b> '.(RemoveID3v2($row['filename'], false) ? 'removed' : 'REMOVAL FAILED!').', ';
1807					$WriteID3v1_title   = (isset($ThisFileInfo['comments']['title'][0])   ? $ThisFileInfo['comments']['title'][0]   : '');
1808					$WriteID3v1_artist  = (isset($ThisFileInfo['comments']['artist'][0])  ? $ThisFileInfo['comments']['artist'][0]  : '');
1809					$WriteID3v1_year    = (isset($ThisFileInfo['comments']['year'][0])    ? $ThisFileInfo['comments']['year'][0]    : '');
1810					$WriteID3v1_comment = (isset($ThisFileInfo['comments']['comment'][0]) ? $ThisFileInfo['comments']['comment'][0] : '');
1811					$WriteID3v1_genreid = (isset($ThisFileInfo['comments']['genreid'][0]) ? $ThisFileInfo['comments']['genreid'][0] : '');
1812					echo '<b>ID3v1:</b> '.(WriteID3v1($row['filename'], $WriteID3v1_title, $WriteID3v1_artist, $Album, $WriteID3v1_year, $WriteID3v1_comment, $WriteID3v1_genreid, $Track, false) ? 'updated' : 'UPDATE FAILED').'<br>';
1813				} else {
1814					echo ' . ';
1815				}
1816
1817			} else {
1818
1819				echo '<hr>FAILED<br>'.htmlentities($row['filename']).'<hr>';
1820
1821			}
1822			flush();
1823		}
1824
1825	} else {
1826
1827		echo '<b>'.number_format(mysqli_num_rows($result)).'</b> files with <b>[??]</b>-format track numbers in album field:<br>';
1828		if (mysqli_num_rows($result) > 0) {
1829			echo '(<a href="'.htmlentities($_SERVER['PHP_SELF'].'?trackinalbum=1&m3u=.m3u').'">.m3u version</a>)<br>';
1830			echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?trackinalbum=1&autofix=1').'">Try to auto-fix</a><br>';
1831			echo '<table border="1" cellspacing="0" cellpadding="4">';
1832			while ($row = mysqli_fetch_array($result)) {
1833				echo '<tr>';
1834				echo '<td>'.$row['album'].'</td>';
1835				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1836				echo '</tr>';
1837			}
1838			echo '</table>';
1839		}
1840		echo '<hr>';
1841
1842	}
1843
1844} elseif (!empty($_REQUEST['fileextensions'])) {
1845
1846	$SQLquery  = 'SELECT `filename`, `fileformat`, `audio_dataformat`, `video_dataformat`, `tags`';
1847	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1848	$SQLquery .= ' ORDER BY `filename` ASC';
1849	$result = mysqli_query_safe($con, $SQLquery);
1850	$invalidextensionfiles = 0;
1851	$invalidextensionline  = '<table border="1" cellspacing="0" cellpadding="4">';
1852	$invalidextensionline .= '<tr><th>file</th><th>audio</th><th>video</th><th>tags</th><th>actual</th><th>correct</th><th>filename</th></tr>';
1853	while ($row = mysqli_fetch_array($result)) {
1854		set_time_limit(30);
1855
1856		$acceptableextensions = AcceptableExtensions($row['fileformat'], $row['audio_dataformat'], $row['video_dataformat']);
1857		$actualextension      = strtolower(fileextension($row['filename']));
1858		if ($acceptableextensions && !in_array($actualextension, $acceptableextensions)) {
1859			$invalidextensionfiles++;
1860
1861			$invalidextensionline .= '<tr>';
1862			$invalidextensionline .= '<td>'.$row['fileformat'].'</td>';
1863			$invalidextensionline .= '<td>'.$row['audio_dataformat'].'</td>';
1864			$invalidextensionline .= '<td>'.$row['video_dataformat'].'</td>';
1865			$invalidextensionline .= '<td>'.$row['tags'].'</td>';
1866			$invalidextensionline .= '<td>'.$actualextension.'</td>';
1867			$invalidextensionline .= '<td>'.implode('; ', $acceptableextensions).'</td>';
1868			$invalidextensionline .= '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1869			$invalidextensionline .= '</tr>';
1870		}
1871	}
1872	$invalidextensionline .= '</table><hr>';
1873	echo number_format($invalidextensionfiles).' files with incorrect filename extension:<br>';
1874	echo $invalidextensionline;
1875
1876} elseif (isset($_REQUEST['genredistribution'])) {
1877
1878	if (!empty($_REQUEST['m3u'])) {
1879
1880		header('Content-type: audio/x-mpegurl');
1881		echo '#EXTM3U'."\n";
1882		$SQLquery  = 'SELECT `filename`';
1883		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1884		$SQLquery .= ' WHERE (BINARY `genre` = "'.$_REQUEST['genredistribution'].'")';
1885		$SQLquery .= ' AND (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1886		$SQLquery .= ' ORDER BY `filename` ASC';
1887		$result = mysqli_query_safe($con, $SQLquery);
1888		while ($row = mysqli_fetch_array($result)) {
1889			echo WindowsShareSlashTranslate($row['filename'])."\n";
1890		}
1891		exit;
1892
1893	} else {
1894
1895		if ($_REQUEST['genredistribution'] == '%') {
1896
1897			$SQLquery  = 'SELECT COUNT(*) AS `num`, `genre`';
1898			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1899			$SQLquery .= ' WHERE (`fileformat` NOT LIKE "'.implode('") AND (`fileformat` NOT LIKE "', $IgnoreNoTagFormats).'")';
1900			$SQLquery .= ' GROUP BY `genre`';
1901			$SQLquery .= ' ORDER BY `num` DESC';
1902			$result = mysqli_query_safe($con, $SQLquery);
1903			getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true);
1904			echo '<table border="1" cellspacing="0" cellpadding="4">';
1905			echo '<tr><th>Count</th><th>Genre</th><th>m3u</th></tr>';
1906			while ($row = mysqli_fetch_array($result)) {
1907				$GenreID = getid3_id3v1::LookupGenreID($row['genre']);
1908				if (is_numeric($GenreID)) {
1909					echo '<tr bgcolor="#00FF00;">';
1910				} else {
1911					echo '<tr bgcolor="#FF9999;">';
1912				}
1913				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?genredistribution='.urlencode($row['genre'])).'">'.number_format($row['num']).'</a></td>';
1914				echo '<td nowrap>'.str_replace("\t", '<br>', $row['genre']).'</td>';
1915				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3u=.m3u&genredistribution='.urlencode($row['genre'])).'">.m3u</a></td>';
1916				echo '</tr>';
1917			}
1918			echo '</table><hr>';
1919
1920		} else {
1921
1922			$SQLquery  = 'SELECT `filename`, `genre`';
1923			$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1924			$SQLquery .= ' WHERE (`genre` LIKE "'.mysqli_real_escape_string($con, $_REQUEST['genredistribution']).'")';
1925			$SQLquery .= ' ORDER BY `filename` ASC';
1926			$result = mysqli_query_safe($con, $SQLquery);
1927			echo '<a href="'.htmlentities($_SERVER['PHP_SELF'].'?genredistribution='.urlencode('%')).'">All Genres</a><br>';
1928			echo '<table border="1" cellspacing="0" cellpadding="4">';
1929			echo '<tr><th>Genre</th><th>m3u</th><th>Filename</th></tr>';
1930			while ($row = mysqli_fetch_array($result)) {
1931				echo '<tr>';
1932				echo '<TD NOWRAP>'.str_replace("\t", '<br>', $row['genre']).'</td>';
1933				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename'])).'">m3u</a></td>';
1934				echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1935				echo '</tr>';
1936			}
1937			echo '</table><hr>';
1938
1939		}
1940
1941
1942	}
1943
1944} elseif (!empty($_REQUEST['formatdistribution'])) {
1945
1946	$SQLquery  = 'SELECT `fileformat`, `audio_dataformat`, COUNT(*) AS `num`';
1947	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1948	$SQLquery .= ' GROUP BY `fileformat`, `audio_dataformat`';
1949	$SQLquery .= ' ORDER BY `num` DESC';
1950	$result = mysqli_query_safe($con, $SQLquery);
1951	echo 'File format distribution:<table border="1" cellspacing="0" cellpadding="4">';
1952	echo '<tr><th>Number</th><th>Format</th></tr>';
1953	while ($row = mysqli_fetch_array($result)) {
1954		echo '<tr>';
1955		echo '<TD ALIGN="RIGHT">'.number_format($row['num']).'</td>';
1956		echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?filetypelist='.$row['fileformat'].'|'.$row['audio_dataformat']).'">'.($row['fileformat'] ? $row['fileformat'] : '<i>unknown</i>').(($row['audio_dataformat'] && ($row['audio_dataformat'] != $row['fileformat'])) ? '.'.$row['audio_dataformat'] : '').'</a></td>';
1957		echo '</tr>';
1958	}
1959	echo '</table><hr>';
1960
1961} elseif (!empty($_REQUEST['errorswarnings'])) {
1962
1963	$SQLquery  = 'SELECT `filename`, `error`, `warning`';
1964	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
1965	$SQLquery .= ' WHERE (`error` <> "")';
1966	$SQLquery .= ' OR (`warning` <> "")';
1967	$SQLquery .= ' ORDER BY `filename` ASC';
1968	$result = mysqli_query_safe($con, $SQLquery);
1969
1970	if (!empty($_REQUEST['m3u'])) {
1971
1972		header('Content-type: audio/x-mpegurl');
1973		echo '#EXTM3U'."\n";
1974		while ($row = mysqli_fetch_array($result)) {
1975			echo WindowsShareSlashTranslate($row['filename'])."\n";
1976		}
1977		exit;
1978
1979	} else {
1980
1981		echo number_format(mysqli_num_rows($result)).' files with errors or warnings:<br>';
1982		echo '(<a href="'.htmlentities($_SERVER['PHP_SELF'].'?errorswarnings=1&m3u=.m3u').'">.m3u version</a>)<br>';
1983		echo '<table border="1" cellspacing="0" cellpadding="4">';
1984		echo '<tr><th>Filename</th><th>Error</th><th>Warning</th></tr>';
1985		while ($row = mysqli_fetch_array($result)) {
1986			echo '<tr>';
1987			echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td>';
1988			echo '<td>'.(!empty($row['error'])   ? '<li>'.str_replace("\t", '<li>', htmlentities($row['error'])).'</li>' : '&nbsp;').'</td>';
1989			echo '<td>'.(!empty($row['warning']) ? '<li>'.str_replace("\t", '<li>', htmlentities($row['warning'])).'</li>' : '&nbsp;').'</td>';
1990			echo '</tr>';
1991		}
1992	}
1993	echo '</table><hr>';
1994
1995} elseif (!empty($_REQUEST['fixid3v1padding'])) {
1996
1997	getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'write.id3v1.php', __FILE__, true);
1998	$id3v1_writer = new getid3_write_id3v1;
1999
2000	$SQLquery  = 'SELECT `filename`, `error`, `warning`';
2001	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
2002	$SQLquery .= ' WHERE (`fileformat` = "mp3")';
2003	$SQLquery .= ' AND (`warning` <> "")';
2004	$SQLquery .= ' ORDER BY `filename` ASC';
2005	$result = mysqli_query_safe($con, $SQLquery);
2006	$totaltofix = mysqli_num_rows($result);
2007	$rowcounter = 0;
2008	while ($row = mysqli_fetch_array($result)) {
2009		set_time_limit(30);
2010		if (strpos($row['warning'], 'Some ID3v1 fields do not use NULL characters for padding') !== false) {
2011			set_time_limit(30);
2012			$id3v1_writer->filename = $row['filename'];
2013			echo ($id3v1_writer->FixID3v1Padding() ? '<span style="color: #009900;">fixed - ' : '<span style="color: #FF0000;">error - ');
2014		} else {
2015			echo '<span style="color: #0000FF;">No error? - ';
2016		}
2017		echo '['.++$rowcounter.' / '.$totaltofix.'] ';
2018		echo htmlentities($row['filename']).'</span><br>';
2019		flush();
2020	}
2021
2022} elseif (!empty($_REQUEST['vbrmethod'])) {
2023
2024	if ($_REQUEST['vbrmethod'] == '1') {
2025
2026		$SQLquery  = 'SELECT COUNT(*) AS `num`, `vbr_method`';
2027		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
2028		$SQLquery .= ' GROUP BY `vbr_method`';
2029		$SQLquery .= ' ORDER BY `vbr_method`';
2030		$result = mysqli_query_safe($con, $SQLquery);
2031		echo 'VBR methods:<table border="1" cellspacing="0" cellpadding="4">';
2032		echo '<tr><th>Count</th><th>VBR Method</th></tr>';
2033		while ($row = mysqli_fetch_array($result)) {
2034			echo '<tr>';
2035			echo '<TD ALIGN="RIGHT">'.htmlentities(number_format($row['num'])).'</td>';
2036			if ($row['vbr_method']) {
2037				echo '<td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?vbrmethod='.$row['vbr_method'], ENT_QUOTES).'">'.htmlentities($row['vbr_method']).'</a></td>';
2038			} else {
2039				echo '<td><i>CBR</i></td>';
2040			}
2041			echo '</tr>';
2042		}
2043		echo '</table>';
2044
2045	} else {
2046
2047		$SQLquery  = 'SELECT `filename`';
2048		$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
2049		$SQLquery .= ' WHERE (`vbr_method` = "'.mysqli_real_escape_string($con, $_REQUEST['vbrmethod']).'")';
2050		$result = mysqli_query_safe($con, $SQLquery);
2051		echo number_format(mysqli_num_rows($result)).' files with VBR_method of "'.$_REQUEST['vbrmethod'].'":<table border="1" cellspacing="0" cellpadding="3">';
2052		while ($row = mysqli_fetch_array($result)) {
2053			echo '<tr><td><a href="'.htmlentities($_SERVER['PHP_SELF'].'?m3ufilename='.urlencode($row['filename'])).'">m3u</a></td>';
2054			echo '<td><a href="'.htmlentities('demo.browse.php?filename='.rawurlencode($row['filename']), ENT_QUOTES).'">'.htmlentities($row['filename']).'</a></td></tr>';
2055		}
2056		echo '</table>';
2057
2058	}
2059	echo '<hr>';
2060
2061} elseif (!empty($_REQUEST['correctcase'])) {
2062
2063	$SQLquery  = 'SELECT `filename`, `fileformat`';
2064	$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
2065	$SQLquery .= ' WHERE (`fileformat` <> "")';
2066	$SQLquery .= ' ORDER BY `filename` ASC';
2067	$result = mysqli_query_safe($con, $SQLquery);
2068	echo 'Copy and paste the following into a DOS batch file. You may have to run this script more than once to catch all the changes (remember to scan for deleted/changed files and rescan directory between scans)<hr>';
2069	echo '<PRE>';
2070	$lastdir = '';
2071	while ($row = mysqli_fetch_array($result)) {
2072		set_time_limit(30);
2073		$CleanedFilename = CleanUpFileName($row['filename']);
2074		if ($row['filename'] != $CleanedFilename) {
2075			if (strtolower($lastdir) != strtolower(str_replace('/', '\\', dirname($row['filename'])))) {
2076				$lastdir = str_replace('/', '\\', dirname($row['filename']));
2077				echo 'cd "'.$lastdir.'"'."\n";
2078			}
2079			echo 'ren "'.basename($row['filename']).'" "'.basename(CleanUpFileName($row['filename'])).'"'."\n";
2080		}
2081	}
2082	echo '</PRE>';
2083	echo '<hr>';
2084
2085}
2086
2087function CleanUpFileName($filename) {
2088	$DirectoryName = dirname($filename);
2089	$FileExtension = fileextension(basename($filename));
2090	$BaseFilename  = basename($filename, '.'.$FileExtension);
2091
2092	$BaseFilename = strtolower($BaseFilename);
2093	$BaseFilename = str_replace('_', ' ', $BaseFilename);
2094	//$BaseFilename = str_replace('-', ' - ', $BaseFilename);
2095	$BaseFilename = str_replace('(', ' (', $BaseFilename);
2096	$BaseFilename = str_replace('( ', '(', $BaseFilename);
2097	$BaseFilename = str_replace(')', ') ', $BaseFilename);
2098	$BaseFilename = str_replace(' )', ')', $BaseFilename);
2099	$BaseFilename = str_replace(' \'\'', ' “', $BaseFilename);
2100	$BaseFilename = str_replace('\'\' ', '” ', $BaseFilename);
2101	$BaseFilename = str_replace(' vs ', ' vs. ', $BaseFilename);
2102	while (strstr($BaseFilename, '  ') !== false) {
2103		$BaseFilename = str_replace('  ', ' ', $BaseFilename);
2104	}
2105	$BaseFilename = trim($BaseFilename);
2106
2107	return $DirectoryName.'/'.BetterUCwords($BaseFilename).'.'.strtolower($FileExtension);
2108}
2109
2110function BetterUCwords($string) {
2111	$stringlength = strlen($string);
2112
2113	$string[0] = strtoupper($string[0]);
2114	for ($i = 1; $i < $stringlength; $i++) {
2115		if (($string[$i - 1] == '\'') && ($i > 1) && (($string[$i - 2] == 'O') || ($string[$i - 2] == ' '))) {
2116			// O'Clock, 'Em
2117			$string[$i] = strtoupper($string[$i]);
2118		} elseif (preg_match('#^[\'A-Za-z0-9À-ÿ]$#', $string[$i - 1])) {
2119			$string[$i] = strtolower($string[$i]);
2120		} else {
2121			$string[$i] = strtoupper($string[$i]);
2122		}
2123	}
2124
2125	static $LowerCaseWords = array('vs.', 'feat.');
2126	static $UpperCaseWords = array('DJ', 'USA', 'II', 'MC', 'CD', 'TV', '\'N\'');
2127
2128	$OutputListOfWords = array();
2129	$ListOfWords = explode(' ', $string);
2130	foreach ($ListOfWords as $ThisWord) {
2131		if (in_array(strtolower(str_replace('(', '', $ThisWord)), $LowerCaseWords)) {
2132			$ThisWord = strtolower($ThisWord);
2133		} elseif (in_array(strtoupper(str_replace('(', '', $ThisWord)), $UpperCaseWords)) {
2134			$ThisWord = strtoupper($ThisWord);
2135		} elseif ((substr($ThisWord, 0, 2) == 'Mc') && (strlen($ThisWord) > 2)) {
2136			$ThisWord[2] = strtoupper($ThisWord[2]);
2137		} elseif ((substr($ThisWord, 0, 3) == 'Mac') && (strlen($ThisWord) > 3)) {
2138			$ThisWord[3] = strtoupper($ThisWord[3]);
2139		}
2140		$OutputListOfWords[] = $ThisWord;
2141	}
2142	$UCstring = implode(' ', $OutputListOfWords);
2143	$UCstring = str_replace(' From “', ' from “', $UCstring);
2144	$UCstring = str_replace(' \'n\' ', ' \'N\' ', $UCstring);
2145
2146	return $UCstring;
2147}
2148
2149
2150
2151echo '<hr><form action="'.htmlentities($_SERVER['PHP_SELF'], ENT_QUOTES).'" method="get">';
2152echo '<b>Warning:</b> Scanning a new directory will erase all previous entries in the database!<br>';
2153echo 'Directory: <input type="text" name="scan" size="50" value="'.htmlentities(!empty($_REQUEST['scan']) ? $_REQUEST['scan'] : '', ENT_QUOTES).'"> ';
2154echo '<input type="submit" value="Go" onClick="return confirm(\'Are you sure you want to erase all entries in the database and start scanning again?\');">';
2155echo '</form>';
2156echo '<hr><form action="'.htmlentities($_SERVER['PHP_SELF'], ENT_QUOTES).'" method="get">';
2157echo 'Re-scanning a new directory will only add new, previously unscanned files into the list (and not erase the database).<br>';
2158echo 'Directory: <input type="text" name="newscan" size="50" value="'.htmlentities(!empty($_REQUEST['newscan']) ? $_REQUEST['newscan'] : '', ENT_QUOTES).'"> ';
2159echo '<input type="submit" value="Go">';
2160echo '</form><hr>';
2161echo '<ul>';
2162echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?deadfilescheck=1').'">Remove deleted or changed files from database</a></li>';
2163echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?md5datadupes=1').'">List files with identical MD5_DATA values</a></li>';
2164echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?artisttitledupes=1').'">List files with identical artist + title</a> (<a href="'.$_SERVER['PHP_SELF'].'?artisttitledupes=1&samemix=1">same mix only</a>)</li>';
2165echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?fileextensions=1').'">File with incorrect file extension</a></li>';
2166echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?formatdistribution=1').'">File Format Distribution</a></li>';
2167echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?audiobitrates=1').'">Audio Bitrate Distribution</a></li>';
2168echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?vbrmethod=1').'">VBR_Method Distribution</a></li>';
2169echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?tagtypes=1').'">Tag Type Distribution</a></li>';
2170echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?genredistribution='.urlencode('%')).'">Genre Distribution</a></li>';
2171//echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?missingtrackvolume=1').'">Scan for missing track volume information (update database from pre-v1.7.0b5)</a></li>';
2172echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?encoderoptionsdistribution=1').'">Encoder Options Distribution</a></li>';
2173echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?encodedbydistribution='.urlencode('%')).'">Encoded By (ID3v2) Distribution</a></li>';
2174echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?trackinalbum=1').'">Track number in Album field</a></li>';
2175echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?tracknoalbum=1').'">Track number, but no Album</a></li>';
2176echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?titlefeat=1').'">"feat." in Title field</a></li>';
2177echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?emptygenres=1').'">Blank genres</a></li>';
2178echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?trackzero=1').'">Track "zero"</a></li>';
2179echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?nonemptycomments=1').'">non-empty comments</a></li>';
2180echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?unsynchronizedtags=2A1').'">Tags that are not synchronized</a> (<a href="'.$_SERVER['PHP_SELF'].'?unsynchronizedtags=2A1&autofix=1">autofix</a>)</li>';
2181echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?filenamepattern='.urlencode('[N] A - T {R}')).'">Filenames that don\'t match pattern</a> (<a href="?filenamepattern='.urlencode('[N] A - T {R}').'&autofix=1">auto-fix</a>)</li>';
2182//echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?filenamepattern='.urlencode('A - T')).'">Filenames that don\'t match pattern</a></li>';
2183echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?correctcase=1').'">Correct filename case (Win/DOS)</a></li>';
2184echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?fixid3v1padding=1').'">Fix ID3v1 invalid padding</a></li>';
2185echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?errorswarnings=1').'">Files with Errors and/or Warnings</a></li>';
2186echo '<li><a href="'.htmlentities($_SERVER['PHP_SELF'].'?rescanerrors=1').'">Re-scan only files with Errors and/or Warnings</a></li>';
2187echo '</ul>';
2188
2189$SQLquery  = 'SELECT COUNT(*) AS `TotalFiles`, SUM(`playtime_seconds`) AS `TotalPlaytime`, SUM(`filesize`) AS `TotalFilesize`, AVG(`playtime_seconds`) AS `AvgPlaytime`, AVG(`filesize`) AS `AvgFilesize`, AVG(`audio_bitrate` + `video_bitrate`) AS `AvgBitrate`';
2190$SQLquery .= ' FROM `'.mysqli_real_escape_string($con, GETID3_DB_TABLE).'`';
2191$result = mysqli_query_safe($con, $SQLquery);
2192if ($row = mysqli_fetch_array($result)) {
2193	echo '<hr size="1">';
2194	echo '<div style="float: right;">';
2195	echo 'Spent '.number_format(mysqli_query_safe($con, null), 3).' seconds querying the database<br>';
2196	echo '</div>';
2197	echo '<b>Currently in the database:</b><TABLE>';
2198	echo '<tr><th align="left">Total Files</th><td>'.number_format($row['TotalFiles']).'</td></tr>';
2199	echo '<tr><th align="left">Total Filesize</th><td>'.number_format($row['TotalFilesize'] / 1048576).' MB</td></tr>';
2200	echo '<tr><th align="left">Total Playtime</th><td>'.number_format($row['TotalPlaytime'] / 3600, 1).' hours</td></tr>';
2201	echo '<tr><th align="left">Average Filesize</th><td>'.number_format($row['AvgFilesize'] / 1048576, 1).' MB</td></tr>';
2202	echo '<tr><th align="left">Average Playtime</th><td>'.getid3_lib::PlaytimeString($row['AvgPlaytime']).'</td></tr>';
2203	echo '<tr><th align="left">Average Bitrate</th><td>'.BitrateText($row['AvgBitrate'] / 1000, 1).'</td></tr>';
2204	echo '</table>';
2205	echo '<br clear="all">';
2206}
2207
2208echo '</body></html>';
2209