22 if (!defined(
'GETID3_INCLUDEPATH')) {
 
   23         die(
'getid3.php MUST be included before calling getid3_writetags');
 
   25 if (!include_once(GETID3_INCLUDEPATH.
'getid3.lib.php')) {
 
   26         die(
'write.php depends on getid3.lib.php, which is missing.');
 
   73                 if (empty($this->filename)) {
 
   74                         $this->errors[] = 
'filename is undefined in getid3_writetags';
 
   76                 } elseif (!file_exists($this->filename)) {
 
   77                         $this->errors[] = 
'filename set to non-existant file "'.$this->filename.
'" in getid3_writetags';
 
   81                 if (!is_array($this->tagformats)) {
 
   82                         $this->errors[] = 
'tagformats must be an array in getid3_writetags';
 
   86                 $TagFormatsToRemove = array();
 
   87                 if (filesize($this->filename) == 0) {
 
   91                         $this->ThisFileInfo = array(
'fileformat'=>
'');
 
   92                         $AllowedTagFormats = array(
'id3v1', 
'id3v2.2', 
'id3v2.3', 
'id3v2.4', 
'ape', 
'lyrics3');
 
   98                         $this->ThisFileInfo = $getID3->analyze($this->filename);
 
  101                         switch (@$this->ThisFileInfo[
'fileformat']) {
 
  106                                         $AllowedTagFormats = array(
'id3v1', 
'id3v2.2', 
'id3v2.3', 
'id3v2.4', 
'ape', 
'lyrics3');
 
  110                                         $AllowedTagFormats = array(
'ape');
 
  114                                         $AllowedTagFormats = array(
'metaflac');
 
  118                                         $AllowedTagFormats = array(
'real');
 
  122                                         switch (@$this->ThisFileInfo[
'audio'][
'dataformat']) {
 
  125                                                         $this->errors[] = 
'metaflac is not (yet) compatible with OggFLAC files';
 
  129                                                         $AllowedTagFormats = array(
'vorbiscomment');
 
  132                                                         $this->errors[] = 
'metaflac is not (yet) compatible with Ogg files other than OggVorbis';
 
  139                                         $AllowedTagFormats = array();
 
  142                         foreach ($this->tagformats as $requested_tag_format) {
 
  143                                 if (!in_array($requested_tag_format, $AllowedTagFormats)) {
 
  144                                         $errormessage = 
'Tag format "'.$requested_tag_format.
'" is not allowed on "'.@$this->ThisFileInfo[
'fileformat'];
 
  145                                         if (@$this->ThisFileInfo[
'fileformat'] != @$this->ThisFileInfo[
'audio'][
'dataformat']) {
 
  146                                                 $errormessage .= 
'.'.@$this->ThisFileInfo[
'audio'][
'dataformat'];
 
  148                                         $errormessage .= 
'" files';
 
  149                                         $this->errors[] = $errormessage;
 
  155                         if ($this->remove_other_tags) {
 
  156                                 foreach ($AllowedTagFormats as $AllowedTagFormat) {
 
  157                                         switch ($AllowedTagFormat) {
 
  161                                                         if (!in_array(
'id3v2', $TagFormatsToRemove) && !in_array(
'id3v2.2', $this->tagformats) && !in_array(
'id3v2.3', $this->tagformats) && !in_array(
'id3v2.4', $this->tagformats)) {
 
  162                                                                 $TagFormatsToRemove[] = 
'id3v2';
 
  167                                                         if (!in_array($AllowedTagFormat, $this->tagformats)) {
 
  168                                                                 $TagFormatsToRemove[] = $AllowedTagFormat;
 
  176                 $WritingFilesToInclude = array_merge($this->tagformats, $TagFormatsToRemove);
 
  179                 foreach ($WritingFilesToInclude as $tagformat) {
 
  180                         switch ($tagformat) {
 
  190                                 case 'vorbiscomment':
 
  210                                         $this->errors[] = 
'unknown tag format "'.$tagformat.
'" in $tagformats in WriteTags()';
 
  218                 if (!is_array($this->tag_data)) {
 
  219                         $this->errors[] = 
'$tag_data is not an array in WriteTags()';
 
  223                 foreach ($this->tag_data as $tag_key => $tag_array) {
 
  224                         if (strtoupper($tag_key) !== $tag_key) {
 
  225                                 $this->tag_data[strtoupper($tag_key)] = $this->tag_data[$tag_key];
 
  226                                 unset($this->tag_data[$tag_key]);
 
  230                 if (!empty($this->ThisFileInfo[
'tags'])) {
 
  231                         foreach ($this->ThisFileInfo[
'tags'] as $tag_format => $tag_data_array) {
 
  232                                 foreach ($tag_data_array as $tag_key => $tag_array) {
 
  233                                         if (strtoupper($tag_key) !== $tag_key) {
 
  234                                                 $this->ThisFileInfo[
'tags'][$tag_format][strtoupper($tag_key)] = $this->ThisFileInfo[
'tags'][$tag_format][$tag_key];
 
  235                                                 unset($this->ThisFileInfo[
'tags'][$tag_format][$tag_key]);
 
  242                 if (isset($this->tag_data[
'TRACK']) && !isset($this->tag_data[
'TRACKNUMBER'])) {
 
  243                         $this->tag_data[
'TRACKNUMBER'] = $this->tag_data[
'TRACK'];
 
  244                         unset($this->tag_data[
'TRACK']);
 
  248                 if ($this->remove_other_tags) {
 
  253                 foreach ($this->tagformats as $tagformat) {
 
  255                         switch ($tagformat) {
 
  258                                         if (($ape_writer->tag_data = $this->FormatDataForAPE()) !== 
false) {
 
  260                                                 if ((
$success = $ape_writer->WriteAPEtag()) === 
false) {
 
  261                                                         $this->errors[] = 
'WriteAPEtag() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $ape_writer->errors)).
'</LI></UL></PRE>';
 
  264                                                 $this->errors[] = 
'FormatDataForAPE() failed';
 
  270                                         if (($id3v1_writer->tag_data = $this->FormatDataForID3v1()) !== 
false) {
 
  272                                                 if ((
$success = $id3v1_writer->WriteID3v1()) === 
false) {
 
  273                                                         $this->errors[] = 
'WriteID3v1() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $id3v1_writer->errors)).
'</LI></UL></PRE>';
 
  276                                                 $this->errors[] = 
'FormatDataForID3v1() failed';
 
  284                                         $id3v2_writer->majorversion = intval(substr($tagformat, -1));
 
  286                                         if (($id3v2_writer->tag_data = $this->FormatDataForID3v2($id3v2_writer->majorversion)) !== 
false) {
 
  288                                                 if ((
$success = $id3v2_writer->WriteID3v2()) === 
false) {
 
  289                                                         $this->errors[] = 
'WriteID3v2() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $id3v2_writer->errors)).
'</LI></UL></PRE>';
 
  292                                                 $this->errors[] = 
'FormatDataForID3v2() failed';
 
  296                                 case 'vorbiscomment':
 
  298                                         if (($vorbiscomment_writer->tag_data = $this->FormatDataForVorbisComment()) !== 
false) {
 
  300                                                 if ((
$success = $vorbiscomment_writer->WriteVorbisComment()) === 
false) {
 
  301                                                         $this->errors[] = 
'WriteVorbisComment() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $vorbiscomment_writer->errors)).
'</LI></UL></PRE>';
 
  304                                                 $this->errors[] = 
'FormatDataForVorbisComment() failed';
 
  310                                         if (($metaflac_writer->tag_data = $this->FormatDataForMetaFLAC()) !== 
false) {
 
  312                                                 if ((
$success = $metaflac_writer->WriteMetaFLAC()) === 
false) {
 
  313                                                         $this->errors[] = 
'WriteMetaFLAC() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $metaflac_writer->errors)).
'</LI></UL></PRE>';
 
  316                                                 $this->errors[] = 
'FormatDataForMetaFLAC() failed';
 
  322                                         if (($real_writer->tag_data = $this->FormatDataForReal()) !== 
false) {
 
  324                                                 if ((
$success = $real_writer->WriteReal()) === 
false) {
 
  325                                                         $this->errors[] = 
'WriteReal() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $real_writer->errors)).
'</LI></UL></PRE>';
 
  328                                                 $this->errors[] = 
'FormatDataForReal() failed';
 
  333                                         $this->errors[] = 
'Invalid tag format to write: "'.$tagformat.
'"';
 
  347                 foreach ($TagFormatsToDelete as $DeleteTagFormat) {
 
  349                         switch ($DeleteTagFormat) {
 
  353                                         if ((
$success = $id3v1_writer->RemoveID3v1()) === 
false) {
 
  354                                                 $this->errors[] = 
'RemoveID3v1() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $id3v1_writer->errors)).
'</LI></UL></PRE>';
 
  361                                         if ((
$success = $id3v2_writer->RemoveID3v2()) === 
false) {
 
  362                                                 $this->errors[] = 
'RemoveID3v2() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $id3v2_writer->errors)).
'</LI></UL></PRE>';
 
  369                                         if ((
$success = $ape_writer->DeleteAPEtag()) === 
false) {
 
  370                                                 $this->errors[] = 
'DeleteAPEtag() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $ape_writer->errors)).
'</LI></UL></PRE>';
 
  374                                 case 'vorbiscomment':
 
  377                                         if ((
$success = $vorbiscomment_writer->DeleteVorbisComment()) === 
false) {
 
  378                                                 $this->errors[] = 
'DeleteVorbisComment() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $vorbiscomment_writer->errors)).
'</LI></UL></PRE>';
 
  385                                         if ((
$success = $metaflac_writer->DeleteMetaFLAC()) === 
false) {
 
  386                                                 $this->errors[] = 
'DeleteMetaFLAC() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $metaflac_writer->errors)).
'</LI></UL></PRE>';
 
  393                                         if ((
$success = $lyrics3_writer->DeleteLyrics3()) === 
false) {
 
  394                                                 $this->errors[] = 
'DeleteLyrics3() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $lyrics3_writer->errors)).
'</LI></UL></PRE>';
 
  401                                         if ((
$success = $real_writer->RemoveReal()) === 
false) {
 
  402                                                 $this->errors[] = 
'RemoveReal() failed with message(s):<PRE><UL><LI>'.trim(implode(
'</LI><LI>', $real_writer->errors)).
'</LI></UL></PRE>';
 
  407                                         $this->errors[] = 
'Invalid tag format to delete: "'.$tagformat.
'"';
 
  421                 if ($this->overwrite_tags) {
 
  424                         if (!isset($this->ThisFileInfo[
'tags'][$TagFormat])) {
 
  427                         $tag_data = array_merge_recursive(
$tag_data, $this->ThisFileInfo[
'tags'][$TagFormat]);
 
  433                 $ape_tag_data = array();
 
  434                 foreach ($this->tag_data as $tag_key => $valuearray) {
 
  436                                 case 'ATTACHED_PICTURE':
 
  438                                         $this->warnings[] = 
'$data['.$tag_key.
'] is assumed to be ID3v2 APIC data - NOT written to APE tag';
 
  442                                         foreach ($valuearray as $key => $value) {
 
  443                                                 if (is_string($value) || is_numeric($value)) {
 
  446                                                         $this->warnings[] = 
'$data['.$tag_key.
']['.$key.
'] is not a string value - all of $data['.$tag_key.
'] NOT written to APE tag';
 
  447                                                         unset($ape_tag_data[$tag_key]);
 
  455                 return $ape_tag_data;
 
  460                 $tag_data_id3v1[
'genreid'] = 255;
 
  461                 if (!empty($this->tag_data[
'GENRE'])) {
 
  462                         foreach ($this->tag_data[
'GENRE'] as $key => $value) {
 
  470                 $tag_data_id3v1[
'title']   = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'TITLE']));
 
  471                 $tag_data_id3v1[
'artist']  = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'ARTIST']));
 
  472                 $tag_data_id3v1[
'album']   = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'ALBUM']));
 
  473                 $tag_data_id3v1[
'year']    = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'YEAR']));
 
  474                 $tag_data_id3v1[
'comment'] = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'COMMENT']));
 
  476                 $tag_data_id3v1[
'track']   = intval(
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'TRACKNUMBER'])));
 
  477                 if ($tag_data_id3v1[
'track'] <= 0) {
 
  478                         $tag_data_id3v1[
'track'] = 
'';
 
  482                 return $tag_data_id3v1;
 
  486                 $tag_data_id3v2 = array();
 
  488                 $ID3v2_text_encoding_lookup[2] = array(
'ISO-8859-1'=>0, 
'UTF-16'=>1);
 
  489                 $ID3v2_text_encoding_lookup[3] = array(
'ISO-8859-1'=>0, 
'UTF-16'=>1);
 
  490                 $ID3v2_text_encoding_lookup[4] = array(
'ISO-8859-1'=>0, 
'UTF-16'=>1, 
'UTF-16BE'=>2, 
'UTF-8'=>3);
 
  491                 foreach ($this->tag_data as $tag_key => $valuearray) {
 
  493                         switch ($ID3v2_framename) {
 
  495                                         foreach ($valuearray as $key => $apic_data_array) {
 
  496                                                 if (isset($apic_data_array[
'data']) &&
 
  497                                                         isset($apic_data_array[
'picturetypeid']) &&
 
  498                                                         isset($apic_data_array[
'description']) &&
 
  499                                                         isset($apic_data_array[
'mime'])) {
 
  500                                                                 $tag_data_id3v2[
'APIC'][] = $apic_data_array;
 
  502                                                         $this->errors[] = 
'ID3v2 APIC data is not properly structured';
 
  509                                         $this->errors[] = 
'ID3v2: Skipping "'.$tag_key.
'" because cannot match it to a known ID3v2 frame type';
 
  515                                         foreach ($valuearray as $key => $value) {
 
  516                                                 if (isset($ID3v2_text_encoding_lookup[$id3v2_majorversion][$this->tag_encoding])) {
 
  518                                                         $tag_data_id3v2[$ID3v2_framename][$key][
'encodingid'] = $ID3v2_text_encoding_lookup[$id3v2_majorversion][
$this->tag_encoding];
 
  519                                                         $tag_data_id3v2[$ID3v2_framename][$key][
'data']       = $value;
 
  522                                                         if ($id3v2_majorversion < 4) {
 
  524                                                                 $tag_data_id3v2[$ID3v2_framename][$key][
'encodingid'] = 1;
 
  529                                                                 $tag_data_id3v2[$ID3v2_framename][$key][
'encodingid'] = 3;
 
  535                                                 $tag_data_id3v2[$ID3v2_framename][$key][
'description'] = 
'';
 
  542                 return $tag_data_id3v2;
 
  550                 foreach ($tag_data_vorbiscomment as $tag_key => $valuearray) {
 
  551                         foreach ($valuearray as $key => $value) {
 
  552                                 str_replace(
"\r", 
"\n", $value);
 
  553                                 if (strstr($value, 
"\n")) {
 
  554                                         unset($tag_data_vorbiscomment[$tag_key][$key]);
 
  555                                         $multilineexploded = explode(
"\n", $value);
 
  556                                         foreach ($multilineexploded as $newcomment) {
 
  557                                                 if (strlen(trim($newcomment)) > 0) {
 
  561                                 } elseif (is_string($value) || is_numeric($value)) {
 
  564                                         $this->warnings[] = 
'$data['.$tag_key.
']['.$key.
'] is not a string value - all of $data['.$tag_key.
'] NOT written to VorbisComment tag';
 
  565                                         unset($tag_data_vorbiscomment[$tag_key]);
 
  571                 return $tag_data_vorbiscomment;
 
  581                 $tag_data_real[
'title']     = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'TITLE']));
 
  582                 $tag_data_real[
'artist']    = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'ARTIST']));
 
  583                 $tag_data_real[
'copyright'] = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'COPYRIGHT']));
 
  584                 $tag_data_real[
'comment']   = 
getid3_lib::iconv_fallback($this->tag_encoding, 
'ISO-8859-1', @implode(
' ', @$this->tag_data[
'COMMENT']));
 
  587                 return $tag_data_real;