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