Fix issue 41/50

git-svn-id: http://php-reader.googlecode.com/svn/trunk@217 51a70ab9-7547-0410-9469-37e369ee0574
This commit is contained in:
svollbehr
2011-05-02 19:09:58 +00:00
parent 05d3008ad6
commit 6496cff709
2 changed files with 88 additions and 34 deletions

View File

@@ -164,7 +164,7 @@ final class Zend_Media_Id3v1
*/ */
public function getTitle() public function getTitle()
{ {
return $this->_title; return $this->_title;
} }
/** /**
@@ -175,7 +175,7 @@ final class Zend_Media_Id3v1
*/ */
public function setTitle($title) public function setTitle($title)
{ {
$this->_title = $title; $this->_title = $title;
} }
/** /**
@@ -185,7 +185,7 @@ final class Zend_Media_Id3v1
*/ */
public function getArtist() public function getArtist()
{ {
return $this->_artist; return $this->_artist;
} }
/** /**
@@ -196,7 +196,7 @@ final class Zend_Media_Id3v1
*/ */
public function setArtist($artist) public function setArtist($artist)
{ {
$this->_artist = $artist; $this->_artist = $artist;
} }
/** /**
@@ -206,7 +206,7 @@ final class Zend_Media_Id3v1
*/ */
public function getAlbum() public function getAlbum()
{ {
return $this->_album; return $this->_album;
} }
/** /**
@@ -217,7 +217,7 @@ final class Zend_Media_Id3v1
*/ */
public function setAlbum($album) public function setAlbum($album)
{ {
$this->_album = $album; $this->_album = $album;
} }
/** /**
@@ -227,7 +227,7 @@ final class Zend_Media_Id3v1
*/ */
public function getYear() public function getYear()
{ {
return $this->_year; return $this->_year;
} }
/** /**
@@ -238,7 +238,7 @@ final class Zend_Media_Id3v1
*/ */
public function setYear($year) public function setYear($year)
{ {
$this->_year = $year; $this->_year = $year;
} }
/** /**
@@ -248,7 +248,7 @@ final class Zend_Media_Id3v1
*/ */
public function getComment() public function getComment()
{ {
return $this->_comment; return $this->_comment;
} }
/** /**
@@ -259,7 +259,7 @@ final class Zend_Media_Id3v1
*/ */
public function setComment($comment) public function setComment($comment)
{ {
$this->_comment = $comment; $this->_comment = $comment;
} }
/** /**
@@ -270,7 +270,7 @@ final class Zend_Media_Id3v1
*/ */
public function getTrack() public function getTrack()
{ {
return $this->_track; return $this->_track;
} }
/** /**
@@ -282,7 +282,7 @@ final class Zend_Media_Id3v1
*/ */
public function setTrack($track) public function setTrack($track)
{ {
$this->_track = $track; $this->_track = $track;
} }
/** /**
@@ -368,6 +368,20 @@ final class Zend_Media_Id3v1
$this->_filename = $filename; $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. * Magic function so that $obj->value will work.
* *

View File

@@ -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 * 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 * option is automatically set when a tag is read from a file and
* defaults to version 4.0 for tag write. * 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 * 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, * another source it cannot be written back to. The tag can, however,
* still be written to another file. * still be written to another file.
@@ -150,9 +156,9 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
($this->_decodeUnsynchronisation($data)); ($this->_decodeUnsynchronisation($data));
$tagSize = $this->_reader->getSize(); $tagSize = $this->_reader->getSize();
} }
$this->clearOption('unsyncronisation'); $this->clearOption('unsynchronisation');
if ($this->_header->hasFlag(Zend_Media_Id3_Header::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)) { if ($this->_header->hasFlag(Zend_Media_Id3_Header::EXTENDED_HEADER)) {
require_once 'Zend/Media/Id3/ExtendedHeader.php'; require_once 'Zend/Media/Id3/ExtendedHeader.php';
@@ -433,8 +439,8 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
* here as an argument. Regardless, the write operation will override * here as an argument. Regardless, the write operation will override
* previous tag information, if found. * previous tag information, if found.
* *
* If write is called without setting any frames to the tag, the tag is * If write is called on a tag without any frames to it, current tag is
* removed from the file. * removed from the file altogether.
* *
* @param string|Zend_Io_Writer $filename The optional path to the file, use * @param string|Zend_Io_Writer $filename The optional path to the file, use
* null to save to the same file. * null to save to the same file.
@@ -443,8 +449,7 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
{ {
if ($filename === null && ($filename = $this->_filename) === null) { if ($filename === null && ($filename = $this->_filename) === null) {
require_once 'Zend/Media/Id3/Exception.php'; require_once 'Zend/Media/Id3/Exception.php';
throw new Zend_Media_Id3_Exception throw new Zend_Media_Id3_Exception('No file given to write to');
('No file given to write to');
} else if ($filename !== null && $filename instanceof Zend_Io_Writer) { } else if ($filename !== null && $filename instanceof Zend_Io_Writer) {
require_once 'Zend/Io/Writer.php'; require_once 'Zend/Io/Writer.php';
$this->_writeData($filename); $this->_writeData($filename);
@@ -465,6 +470,18 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
('Unable to open file for writing: ' . $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) { if ($this->_reader !== null) {
$oldTagSize = 10 /* header */ + $this->_header->getSize(); $oldTagSize = 10 /* header */ + $this->_header->getSize();
} else { } else {
@@ -479,9 +496,9 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
require_once 'Zend/Io/StringWriter.php'; require_once 'Zend/Io/StringWriter.php';
$tag = new Zend_Io_StringWriter(); $tag = new Zend_Io_StringWriter();
$this->_writeData($tag); $this->_writeData($tag);
$tagSize = empty($this->_frames) ? 0 : $tag->getSize(); $tagSize = $tag->getSize();
if ($tagSize > $oldTagSize || $tagSize == 0) { if ($tagSize > $oldTagSize) {
fseek($fd, 0, SEEK_END); fseek($fd, 0, SEEK_END);
$oldFileSize = ftell($fd); $oldFileSize = ftell($fd);
ftruncate ftruncate
@@ -501,7 +518,7 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
} }
} }
if (($remaining = $oldFileSize % 1024) != 0) { if (($remaining = $oldFileSize % 1024) != 0) {
// huh?
} }
fseek($fd, 0, SEEK_END); fseek($fd, 0, SEEK_END);
} }
@@ -523,7 +540,7 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
*/ */
private function _writeData($writer) private function _writeData($writer)
{ {
$this->clearOption('unsyncronisation'); $this->clearOption('unsynchronisation');
$buffer = new Zend_Io_StringWriter(); $buffer = new Zend_Io_StringWriter();
foreach ($this->_frames as $frames) { foreach ($this->_frames as $frames) {
@@ -535,17 +552,10 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
$frameDataLength = strlen($frameData); $frameDataLength = strlen($frameData);
$paddingLength = 0; $paddingLength = 0;
// ID3v2.4.0 supports frame level unsynchronisation. The corresponding // ID3v2.4.0 supports frame level unsynchronisation while
// option is set to true when any of the frames use the // ID3v2.3.0 supports only tag level unsynchronisation.
// unsynchronisation scheme. if ($this->getOption('version', 4) < 4 &&
if ($this->getOption('unsyncronisation', false) === true) { $this->getOption('compat', 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) {
$frameData = $this->_encodeUnsynchronisation($frameData); $frameData = $this->_encodeUnsynchronisation($frameData);
if (($len = strlen($frameData)) != $frameDataLength) { if (($len = strlen($frameData)) != $frameDataLength) {
$frameDataLength = $len; $frameDataLength = $len;
@@ -615,6 +625,36 @@ final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object
} }
} }
/**
* 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 * Magic function so that $obj->value will work. The method will attempt to
* return the first frame that matches the identifier. * return the first frame that matches the identifier.