23 if (!defined(
'GETID3_INCLUDEPATH')) {
24 throw new Exception(
'getid3.php MUST be included before calling getid3_writetags');
26 if (!include_once(GETID3_INCLUDEPATH.
'getid3.lib.php')) {
27 throw new Exception(
'write.php depends on getid3.lib.php, which is missing.');
74 if (empty($this->filename)) {
75 $this->errors[] =
'filename is undefined in getid3_writetags';
77 } elseif (!file_exists($this->filename)) {
78 $this->errors[] =
'filename set to non-existant file "'.$this->filename.
'" in getid3_writetags';
82 if (!is_array($this->tagformats)) {
83 $this->errors[] =
'tagformats must be an array in getid3_writetags';
87 $TagFormatsToRemove = array();
88 if (filesize($this->filename) == 0) {
92 $this->ThisFileInfo = array(
'fileformat'=>
'');
93 $AllowedTagFormats = array(
'id3v1',
'id3v2.2',
'id3v2.3',
'id3v2.4',
'ape',
'lyrics3');
99 $this->ThisFileInfo = $getID3->analyze($this->filename);
102 switch (isset($this->ThisFileInfo[
'fileformat']) ? $this->ThisFileInfo[
'fileformat'] :
'') {
107 $AllowedTagFormats = array(
'id3v1',
'id3v2.2',
'id3v2.3',
'id3v2.4',
'ape',
'lyrics3');
111 $AllowedTagFormats = array(
'ape');
115 $AllowedTagFormats = array(
'metaflac');
119 $AllowedTagFormats = array(
'real');
123 switch (isset($this->ThisFileInfo[
'audio'][
'dataformat']) ? $this->ThisFileInfo[
'audio'][
'dataformat'] :
'') {
126 $this->errors[] =
'metaflac is not (yet) compatible with OggFLAC files';
130 $AllowedTagFormats = array(
'vorbiscomment');
133 $this->errors[] =
'metaflac is not (yet) compatible with Ogg files other than OggVorbis';
140 $AllowedTagFormats = array();
143 foreach ($this->tagformats as $requested_tag_format) {
144 if (!in_array($requested_tag_format, $AllowedTagFormats)) {
145 $errormessage =
'Tag format "'.$requested_tag_format.
'" is not allowed on "'.(isset($this->ThisFileInfo[
'fileformat']) ? $this->ThisFileInfo[
'fileformat'] :
'');
146 $errormessage .= (isset($this->ThisFileInfo[
'audio'][
'dataformat']) ?
'.'.$this->ThisFileInfo[
'audio'][
'dataformat'] :
'');
147 $errormessage .=
'" files';
148 $this->errors[] = $errormessage;
154 if ($this->remove_other_tags) {
155 foreach ($AllowedTagFormats as $AllowedTagFormat) {
156 switch ($AllowedTagFormat) {
160 if (!in_array(
'id3v2', $TagFormatsToRemove) && !in_array(
'id3v2.2', $this->tagformats) && !in_array(
'id3v2.3', $this->tagformats) && !in_array(
'id3v2.4', $this->tagformats)) {
161 $TagFormatsToRemove[] =
'id3v2';
166 if (!in_array($AllowedTagFormat, $this->tagformats)) {
167 $TagFormatsToRemove[] = $AllowedTagFormat;
175 $WritingFilesToInclude = array_merge($this->tagformats, $TagFormatsToRemove);
178 foreach ($WritingFilesToInclude as $tagformat) {
179 switch ($tagformat) {
187 case 'vorbiscomment':
203 $this->errors[] =
'unknown tag format "'.$tagformat.
'" in $tagformats in WriteTags()';
211 if (!is_array($this->tag_data)) {
212 $this->errors[] =
'$this->tag_data is not an array in WriteTags()';
216 foreach ($this->tag_data as $tag_key => $tag_array) {
217 if (strtoupper($tag_key) !== $tag_key) {
218 $this->tag_data[strtoupper($tag_key)] = $this->tag_data[$tag_key];
219 unset($this->tag_data[$tag_key]);
223 if (!empty($this->ThisFileInfo[
'tags'])) {
224 foreach ($this->ThisFileInfo[
'tags'] as $tag_format => $tag_data_array) {
225 foreach ($tag_data_array as $tag_key => $tag_array) {
226 if (strtoupper($tag_key) !== $tag_key) {
227 $this->ThisFileInfo[
'tags'][$tag_format][strtoupper($tag_key)] = $this->ThisFileInfo[
'tags'][$tag_format][$tag_key];
228 unset($this->ThisFileInfo[
'tags'][$tag_format][$tag_key]);
235 if (isset($this->tag_data[
'TRACK']) && !isset($this->tag_data[
'TRACKNUMBER'])) {
236 $this->tag_data[
'TRACKNUMBER'] = $this->tag_data[
'TRACK'];
237 unset($this->tag_data[
'TRACK']);
241 if ($this->remove_other_tags) {
246 foreach ($this->tagformats as $tagformat) {
248 switch ($tagformat) {
251 if (($ape_writer->tag_data = $this->FormatDataForAPE()) !==
false) {
253 if ((
$success = $ape_writer->WriteAPEtag()) ===
false) {
254 $this->errors[] =
'WriteAPEtag() failed with message(s):<pre><ul><li>'.str_replace(
"\n",
'</li><li>', htmlentities(trim(implode(
"\n", $ape_writer->errors)))).
'</li></ul></pre>';
257 $this->errors[] =
'FormatDataForAPE() failed';
263 if (($id3v1_writer->tag_data = $this->FormatDataForID3v1()) !==
false) {
265 if ((
$success = $id3v1_writer->WriteID3v1()) ===
false) {
266 $this->errors[] =
'WriteID3v1() failed with message(s):<pre><ul><li>'.str_replace(
"\n",
'</li><li>', htmlentities(trim(implode(
"\n", $id3v1_writer->errors)))).
'</li></ul></pre>';
269 $this->errors[] =
'FormatDataForID3v1() failed';
277 $id3v2_writer->majorversion = intval(substr($tagformat, -1));
279 if (($id3v2_writer->tag_data = $this->FormatDataForID3v2($id3v2_writer->majorversion)) !==
false) {
281 if ((
$success = $id3v2_writer->WriteID3v2()) ===
false) {
282 $this->errors[] =
'WriteID3v2() failed with message(s):<pre><ul><li>'.str_replace(
"\n",
'</li><li>', htmlentities(trim(implode(
"\n", $id3v2_writer->errors)))).
'</li></ul></pre>';
285 $this->errors[] =
'FormatDataForID3v2() failed';
289 case 'vorbiscomment':
291 if (($vorbiscomment_writer->tag_data = $this->FormatDataForVorbisComment()) !==
false) {
293 if ((
$success = $vorbiscomment_writer->WriteVorbisComment()) ===
false) {
294 $this->errors[] =
'WriteVorbisComment() failed with message(s):<pre><ul><li>'.str_replace(
"\n",
'</li><li>', htmlentities(trim(implode(
"\n", $vorbiscomment_writer->errors)))).
'</li></ul></pre>';
297 $this->errors[] =
'FormatDataForVorbisComment() failed';
303 if (($metaflac_writer->tag_data = $this->FormatDataForMetaFLAC()) !==
false) {
305 if ((
$success = $metaflac_writer->WriteMetaFLAC()) ===
false) {
306 $this->errors[] =
'WriteMetaFLAC() failed with message(s):<pre><ul><li>'.str_replace(
"\n",
'</li><li>', htmlentities(trim(implode(
"\n", $metaflac_writer->errors)))).
'</li></ul></pre>';
309 $this->errors[] =
'FormatDataForMetaFLAC() failed';
315 if (($real_writer->tag_data = $this->FormatDataForReal()) !==
false) {
317 if ((
$success = $real_writer->WriteReal()) ===
false) {
318 $this->errors[] =
'WriteReal() failed with message(s):<pre><ul><li>'.str_replace(
"\n",
'</li><li>', htmlentities(trim(implode(
"\n", $real_writer->errors)))).
'</li></ul></pre>';
321 $this->errors[] =
'FormatDataForReal() failed';
326 $this->errors[] =
'Invalid tag format to write: "'.$tagformat.
'"';
340 foreach ($TagFormatsToDelete as $DeleteTagFormat) {
342 switch ($DeleteTagFormat) {
346 if ((
$success = $id3v1_writer->RemoveID3v1()) ===
false) {
347 $this->errors[] =
'RemoveID3v1() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $id3v1_writer->errors)).
'</LI></UL></PRE>';
354 if ((
$success = $id3v2_writer->RemoveID3v2()) ===
false) {
355 $this->errors[] =
'RemoveID3v2() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $id3v2_writer->errors)).
'</LI></UL></PRE>';
362 if ((
$success = $ape_writer->DeleteAPEtag()) ===
false) {
363 $this->errors[] =
'DeleteAPEtag() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $ape_writer->errors)).
'</LI></UL></PRE>';
367 case 'vorbiscomment':
370 if ((
$success = $vorbiscomment_writer->DeleteVorbisComment()) ===
false) {
371 $this->errors[] =
'DeleteVorbisComment() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $vorbiscomment_writer->errors)).
'</LI></UL></PRE>';
378 if ((
$success = $metaflac_writer->DeleteMetaFLAC()) ===
false) {
379 $this->errors[] =
'DeleteMetaFLAC() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $metaflac_writer->errors)).
'</LI></UL></PRE>';
386 if ((
$success = $lyrics3_writer->DeleteLyrics3()) ===
false) {
387 $this->errors[] =
'DeleteLyrics3() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $lyrics3_writer->errors)).
'</LI></UL></PRE>';
394 if ((
$success = $real_writer->RemoveReal()) ===
false) {
395 $this->errors[] =
'RemoveReal() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $real_writer->errors)).
'</LI></UL></PRE>';
400 $this->errors[] =
'Invalid tag format to delete: "'.$tagformat.
'"';
414 if ($this->overwrite_tags) {
417 throw new Exception(
'$this->overwrite_tags=false is known to be buggy in this version of getID3. Will be fixed in the near future, check www.getid3.org for a newer version.');
418 if (!isset($this->ThisFileInfo[
'tags'][$TagFormat])) {
421 $tag_data = array_merge_recursive(
$tag_data, $this->ThisFileInfo[
'tags'][$TagFormat]);
427 $ape_tag_data = array();
428 foreach ($this->tag_data as $tag_key => $valuearray) {
430 case 'ATTACHED_PICTURE':
432 $this->warnings[] =
'$data['.$tag_key.
'] is assumed to be ID3v2 APIC data - NOT written to APE tag';
436 foreach ($valuearray as
$key => $value) {
437 if (is_string($value) || is_numeric($value)) {
440 $this->warnings[] =
'$data['.$tag_key.
']['.
$key.
'] is not a string value - all of $data['.$tag_key.
'] NOT written to APE tag';
441 unset($ape_tag_data[$tag_key]);
449 return $ape_tag_data;
454 $tag_data_id3v1[
'genreid'] = 255;
455 if (!empty($this->tag_data[
'GENRE'])) {
456 foreach ($this->tag_data[
'GENRE'] as
$key => $value) {
463 $tag_data_id3v1[
'title'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'TITLE'] ) ? $this->tag_data[
'TITLE'] : array())));
464 $tag_data_id3v1[
'artist'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'ARTIST'] ) ? $this->tag_data[
'ARTIST'] : array())));
465 $tag_data_id3v1[
'album'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'ALBUM'] ) ? $this->tag_data[
'ALBUM'] : array())));
466 $tag_data_id3v1[
'year'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'YEAR'] ) ? $this->tag_data[
'YEAR'] : array())));
467 $tag_data_id3v1[
'comment'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'COMMENT'] ) ? $this->tag_data[
'COMMENT'] : array())));
468 $tag_data_id3v1[
'track'] = intval(
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'TRACKNUMBER']) ? $this->tag_data[
'TRACKNUMBER'] : array()))));
469 if ($tag_data_id3v1[
'track'] <= 0) {
470 $tag_data_id3v1[
'track'] =
'';
474 return $tag_data_id3v1;
478 $tag_data_id3v2 = array();
480 $ID3v2_text_encoding_lookup[2] = array(
'ISO-8859-1'=>0,
'UTF-16'=>1);
481 $ID3v2_text_encoding_lookup[3] = array(
'ISO-8859-1'=>0,
'UTF-16'=>1);
482 $ID3v2_text_encoding_lookup[4] = array(
'ISO-8859-1'=>0,
'UTF-16'=>1,
'UTF-16BE'=>2,
'UTF-8'=>3);
483 foreach ($this->tag_data as $tag_key => $valuearray) {
485 switch ($ID3v2_framename) {
487 foreach ($valuearray as
$key => $apic_data_array) {
488 if (isset($apic_data_array[
'data']) &&
489 isset($apic_data_array[
'picturetypeid']) &&
490 isset($apic_data_array[
'description']) &&
491 isset($apic_data_array[
'mime'])) {
492 $tag_data_id3v2[
'APIC'][] = $apic_data_array;
494 $this->errors[] =
'ID3v2 APIC data is not properly structured';
501 if (isset($valuearray[
'email']) &&
502 isset($valuearray[
'rating']) &&
503 isset($valuearray[
'data'])) {
504 $tag_data_id3v2[
'POPM'][] = $valuearray;
506 $this->errors[] =
'ID3v2 POPM data is not properly structured';
513 isset($valuearray[
'groupsymbol']) &&
514 isset($valuearray[
'ownerid']) &&
515 isset($valuearray[
'data'])
517 $tag_data_id3v2[
'GRID'][] = $valuearray;
519 $this->errors[] =
'ID3v2 GRID data is not properly structured';
525 if (isset($valuearray[
'ownerid']) &&
526 isset($valuearray[
'data'])) {
527 $tag_data_id3v2[
'UFID'][] = $valuearray;
529 $this->errors[] =
'ID3v2 UFID data is not properly structured';
535 foreach ($valuearray as
$key => $txxx_data_array) {
536 if (isset($txxx_data_array[
'description']) && isset($txxx_data_array[
'data'])) {
537 $tag_data_id3v2[
'TXXX'][] = $txxx_data_array;
539 $this->errors[] =
'ID3v2 TXXX data is not properly structured';
546 $this->errors[] =
'ID3v2: Skipping "'.$tag_key.
'" because cannot match it to a known ID3v2 frame type';
552 foreach ($valuearray as
$key => $value) {
553 if (isset($ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding])) {
555 $tag_data_id3v2[$ID3v2_framename][
$key][
'encodingid'] = $ID3v2_text_encoding_lookup[$id3v2_majorversion][
$this->tag_encoding];
556 $tag_data_id3v2[$ID3v2_framename][
$key][
'data'] = $value;
559 if ($id3v2_majorversion < 4) {
563 $ID3v2_tag_data_converted =
false;
564 if (!$ID3v2_tag_data_converted && ($this->tag_encoding ==
'ISO-8859-1')) {
566 $tag_data_id3v2[$ID3v2_framename][
$key][
'encodingid'] = 0;
567 $tag_data_id3v2[$ID3v2_framename][
$key][
'data'] = $value;
568 $ID3v2_tag_data_converted =
true;
570 if (!$ID3v2_tag_data_converted && ($this->tag_encoding ==
'UTF-8')) {
573 for (
$i = 0;
$i < strlen($value);
$i++) {
574 if (ord($value{
$i}) > 127) {
578 $tag_data_id3v2[$ID3v2_framename][
$key][
'encodingid'] = 0;
579 $tag_data_id3v2[$ID3v2_framename][
$key][
'data'] = $value;
580 $ID3v2_tag_data_converted =
true;
583 if (!$ID3v2_tag_data_converted) {
584 $tag_data_id3v2[$ID3v2_framename][
$key][
'encodingid'] = 1;
586 $tag_data_id3v2[$ID3v2_framename][
$key][
'data'] =
"\xFF\xFE".getid3_lib::iconv_fallback($this->tag_encoding,
'UTF-16LE', $value);
587 $ID3v2_tag_data_converted =
true;
592 $tag_data_id3v2[$ID3v2_framename][
$key][
'encodingid'] = 3;
598 $tag_data_id3v2[$ID3v2_framename][
$key][
'description'] =
'';
605 return $tag_data_id3v2;
613 foreach ($tag_data_vorbiscomment as $tag_key => $valuearray) {
614 foreach ($valuearray as
$key => $value) {
615 str_replace(
"\r",
"\n", $value);
616 if (strstr($value,
"\n")) {
617 unset($tag_data_vorbiscomment[$tag_key][
$key]);
618 $multilineexploded = explode(
"\n", $value);
619 foreach ($multilineexploded as $newcomment) {
620 if (strlen(trim($newcomment)) > 0) {
624 } elseif (is_string($value) || is_numeric($value)) {
627 $this->warnings[] =
'$data['.$tag_key.
']['.
$key.
'] is not a string value - all of $data['.$tag_key.
'] NOT written to VorbisComment tag';
628 unset($tag_data_vorbiscomment[$tag_key]);
634 return $tag_data_vorbiscomment;
644 $tag_data_real[
'title'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'TITLE'] ) ? $this->tag_data[
'TITLE'] : array())));
645 $tag_data_real[
'artist'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'ARTIST'] ) ? $this->tag_data[
'ARTIST'] : array())));
646 $tag_data_real[
'copyright'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'COPYRIGHT']) ? $this->tag_data[
'COPYRIGHT'] : array())));
647 $tag_data_real[
'comment'] =
getid3_lib::iconv_fallback($this->tag_encoding,
'ISO-8859-1', implode(
' ', (isset($this->tag_data[
'COMMENT'] ) ? $this->tag_data[
'COMMENT'] : array())));
650 return $tag_data_real;
static ID3v2ShortFrameNameLookup($majorversion, $long_description)
static LookupGenreID($genre, $allowSCMPXextended=false)
static iconv_fallback($in_charset, $out_charset, $string)
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
getID3() by James Heinrich info@getid3.org //
getID3() by James Heinrich info@getid3.org //