Skip to content

Commit

Permalink
Fix issue 41/50
Browse files Browse the repository at this point in the history
git-svn-id: http://php-reader.googlecode.com/svn/trunk@217 51a70ab9-7547-0410-9469-37e369ee0574
  • Loading branch information
svollbehr committed May 2, 2011
1 parent 05d3008 commit 6496cff
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 34 deletions.
38 changes: 26 additions & 12 deletions src/Zend/Media/Id3v1.php
Expand Up @@ -164,7 +164,7 @@ public function __construct($filename = null)
*/
public function getTitle()
{
return $this->_title;
return $this->_title;
}

/**
Expand All @@ -175,7 +175,7 @@ public function getTitle()
*/
public function setTitle($title)
{
$this->_title = $title;
$this->_title = $title;
}

/**
Expand All @@ -185,7 +185,7 @@ public function setTitle($title)
*/
public function getArtist()
{
return $this->_artist;
return $this->_artist;
}

/**
Expand All @@ -196,7 +196,7 @@ public function getArtist()
*/
public function setArtist($artist)
{
$this->_artist = $artist;
$this->_artist = $artist;
}

/**
Expand All @@ -206,7 +206,7 @@ public function setArtist($artist)
*/
public function getAlbum()
{
return $this->_album;
return $this->_album;
}

/**
Expand All @@ -217,7 +217,7 @@ public function getAlbum()
*/
public function setAlbum($album)
{
$this->_album = $album;
$this->_album = $album;
}

/**
Expand All @@ -227,7 +227,7 @@ public function setAlbum($album)
*/
public function getYear()
{
return $this->_year;
return $this->_year;
}

/**
Expand All @@ -238,7 +238,7 @@ public function getYear()
*/
public function setYear($year)
{
$this->_year = $year;
$this->_year = $year;
}

/**
Expand All @@ -248,7 +248,7 @@ public function setYear($year)
*/
public function getComment()
{
return $this->_comment;
return $this->_comment;
}

/**
Expand All @@ -259,7 +259,7 @@ public function getComment()
*/
public function setComment($comment)
{
$this->_comment = $comment;
$this->_comment = $comment;
}

/**
Expand All @@ -270,7 +270,7 @@ public function setComment($comment)
*/
public function getTrack()
{
return $this->_track;
return $this->_track;
}

/**
Expand All @@ -282,7 +282,7 @@ public function getTrack()
*/
public function setTrack($track)
{
$this->_track = $track;
$this->_track = $track;
}

/**
Expand Down Expand Up @@ -368,6 +368,20 @@ public function write($filename = null)
$this->_filename = $filename;
}

/**
* Removes the ID3v1 tag altogether.
*
* @param string $filename The path to the file.
*/
public static function remove($filename)
{
$reader = new Zend_Io_FileReader($filename, 'r+b');
$reader->setOffset(-128);
if ($reader->read(3) == 'TAG') {
ftruncate($reader->getFileDescriptor(), $reader->getSize() - 128);
}
}

/**
* Magic function so that $obj->value will work.
*
Expand Down
84 changes: 62 additions & 22 deletions src/Zend/Media/Id3v2.php
Expand Up @@ -81,6 +81,12 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
* o version -- The ID3v2 tag version to use in write operation. This
* option is automatically set when a tag is read from a file and
* defaults to version 4.0 for tag write.
* o compat -- Normally unsynchronization is handled automatically behind
* the scenes. However, current versions of Windows operating system and
* Windows Media Player, just to name a few, do not support ID3v2.4 tags
* nor ID3v2.3 tags with unsynchronization. Hence, for compatibility
* reasons, this option is made available to disable automatic tag level
* unsynchronization scheme that version 3.0 supports.
* o readonly -- Indicates that the tag is read from a temporary file or
* another source it cannot be written back to. The tag can, however,
* still be written to another file.
Expand Down Expand Up @@ -150,9 +156,9 @@ public function __construct($filename = null, $options = array())
($this->_decodeUnsynchronisation($data));
$tagSize = $this->_reader->getSize();
}
$this->clearOption('unsyncronisation');
$this->clearOption('unsynchronisation');
if ($this->_header->hasFlag(Zend_Media_Id3_Header::UNSYNCHRONISATION)) {
$this->setOption('unsyncronisation', true);
$this->setOption('unsynchronisation', true);
}
if ($this->_header->hasFlag(Zend_Media_Id3_Header::EXTENDED_HEADER)) {
require_once 'Zend/Media/Id3/ExtendedHeader.php';
Expand Down Expand Up @@ -433,8 +439,8 @@ public function setFooter($useFooter)
* here as an argument. Regardless, the write operation will override
* previous tag information, if found.
*
* If write is called without setting any frames to the tag, the tag is
* removed from the file.
* If write is called on a tag without any frames to it, current tag is
* removed from the file altogether.
*
* @param string|Zend_Io_Writer $filename The optional path to the file, use
* null to save to the same file.
Expand All @@ -443,8 +449,7 @@ public function write($filename)
{
if ($filename === null && ($filename = $this->_filename) === null) {
require_once 'Zend/Media/Id3/Exception.php';
throw new Zend_Media_Id3_Exception
('No file given to write to');
throw new Zend_Media_Id3_Exception('No file given to write to');
} else if ($filename !== null && $filename instanceof Zend_Io_Writer) {
require_once 'Zend/Io/Writer.php';
$this->_writeData($filename);
Expand All @@ -465,6 +470,18 @@ public function write($filename)
('Unable to open file for writing: ' . $filename);
}

$hasNoFrames = true;
foreach ($this->_frames as $identifier => $instances) {
if (count($instances) > 0) {
$hasNoFrames = false;
break;
}
}
if ($hasNoFrames === true) {
$this->remove(new Zend_Io_Reader($fd));
return;
}

if ($this->_reader !== null) {
$oldTagSize = 10 /* header */ + $this->_header->getSize();
} else {
Expand All @@ -479,9 +496,9 @@ public function write($filename)
require_once 'Zend/Io/StringWriter.php';
$tag = new Zend_Io_StringWriter();
$this->_writeData($tag);
$tagSize = empty($this->_frames) ? 0 : $tag->getSize();
if ($tagSize > $oldTagSize || $tagSize == 0) {
$tagSize = $tag->getSize();

if ($tagSize > $oldTagSize) {
fseek($fd, 0, SEEK_END);
$oldFileSize = ftell($fd);
ftruncate
Expand All @@ -501,7 +518,7 @@ public function write($filename)
}
}
if (($remaining = $oldFileSize % 1024) != 0) {

// huh?
}
fseek($fd, 0, SEEK_END);
}
Expand All @@ -523,7 +540,7 @@ public function write($filename)
*/
private function _writeData($writer)
{
$this->clearOption('unsyncronisation');
$this->clearOption('unsynchronisation');

$buffer = new Zend_Io_StringWriter();
foreach ($this->_frames as $frames) {
Expand All @@ -535,17 +552,10 @@ private function _writeData($writer)
$frameDataLength = strlen($frameData);
$paddingLength = 0;

// ID3v2.4.0 supports frame level unsynchronisation. The corresponding
// option is set to true when any of the frames use the
// unsynchronisation scheme.
if ($this->getOption('unsyncronisation', false) === true) {
$this->_header->setFlags
($this->_header->getFlags() |
Zend_Media_Id3_Header::UNSYNCHRONISATION);
}

// ID3v2.3.0 supports only tag level unsynchronisation
if ($this->getOption('version', 4) < 4) {
// ID3v2.4.0 supports frame level unsynchronisation while
// ID3v2.3.0 supports only tag level unsynchronisation.
if ($this->getOption('version', 4) < 4 &&
$this->getOption('compat', false) !== true) {
$frameData = $this->_encodeUnsynchronisation($frameData);
if (($len = strlen($frameData)) != $frameDataLength) {
$frameDataLength = $len;
Expand Down Expand Up @@ -615,6 +625,36 @@ private function _writeData($writer)
}
}

/**
* Removes the ID3v2 tag altogether.
*
* @param string $filename The path to the file.
*/
public static function remove($filename)
{
if ($filename instanceof Zend_Io_Reader) {
$reader = &$filename;
} else {
require_once 'Zend/Io/FileReader.php';
$reader = new Zend_Io_FileReader($filename, 'r+b');
}

$fileSize = $reader->getSize();
if ($reader->read(3) == 'ID3') {
$header = new Zend_Media_Id3_Header($reader);
$tagSize = 10 /* header */ + $header->getSize();
} else return;

$fd = $reader->getFileDescriptor();
for ($i = 0; $tagSize + ($i * 1024) < $fileSize; $i++) {
fseek($fd, $tagSize + ($i * 1024));
$buffer = fread($fd, 1024);
fseek($fd, ($i * 1024));
$bytes = fwrite($fd, $buffer, 1024);
}
ftruncate($fd, $fileSize - $tagSize);
}

/**
* Magic function so that $obj->value will work. The method will attempt to
* return the first frame that matches the identifier.
Expand Down

0 comments on commit 6496cff

Please sign in to comment.