diff --git a/src/ID3/ExtendedHeader.php b/src/ID3/ExtendedHeader.php
index 9b6dd78..dc54a42 100644
--- a/src/ID3/ExtendedHeader.php
+++ b/src/ID3/ExtendedHeader.php
@@ -117,7 +117,7 @@ final class ID3_ExtendedHeader extends ID3_Object
$this->_size = $this->decodeSynchsafe32($this->_reader->readUInt32BE());
/* ID3v2.3.0 ExtendedHeader */
- if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
+ if ($this->getOption("version", 4) < 4) {
if ($this->_reader->readUInt16BE() == 0x8000)
$this->_flags = self::CRC32;
$this->_padding = $this->_reader->readUInt32BE();
@@ -299,7 +299,7 @@ final class ID3_ExtendedHeader extends ID3_Object
public function __toString()
{
/* ID3v2.3.0 ExtendedHeader */
- if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
+ if ($this->getOption("version", 4) < 4) {
return Transform::toUInt32BE($this->_size) .
Transform::toUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0) .
Transform::toUInt32BE($this->_padding) .
diff --git a/src/ID3/Frame.php b/src/ID3/Frame.php
index 739bf58..065fb36 100644
--- a/src/ID3/Frame.php
+++ b/src/ID3/Frame.php
@@ -152,7 +152,7 @@ class ID3_Frame extends ID3_Object
$this->_size = $this->decodeSynchsafe32($this->_reader->readUInt32BE());
/* ID3v2.3.0 Flags; convert to 2.4.0 format */
- if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
+ if ($this->getOption("version", 4) < 4) {
$flags = $this->_reader->readUInt16BE();
if (($flags & 0x8000) == 0x8000)
$this->_flags |= self::DISCARD_ON_TAGCHANGE;
@@ -243,7 +243,7 @@ class ID3_Frame extends ID3_Object
public function __toString()
{
/* ID3v2.3.0 Flags; convert from 2.4.0 format */
- if (isset($this->_options["version"]) && $this->_options["version"] < 4) {
+ if ($this->getOption("version", 4) < 4) {
$flags = 0;
if ($this->hasFlag(self::DISCARD_ON_TAGCHANGE))
$flags = $flags | 0x8000;
diff --git a/src/ID3/Header.php b/src/ID3/Header.php
index a703c24..589404c 100644
--- a/src/ID3/Header.php
+++ b/src/ID3/Header.php
@@ -119,7 +119,7 @@ final class ID3_Header extends ID3_Object
*/
public function setVersion($version)
{
- $this->_version = $this->_options["version"] = $version;
+ $this->setOption("version", $this->_version = $version);
}
/**
diff --git a/src/ID3/Object.php b/src/ID3/Object.php
index d96825e..3c3e894 100644
--- a/src/ID3/Object.php
+++ b/src/ID3/Object.php
@@ -59,7 +59,7 @@ abstract class ID3_Object
*
* @var Array
*/
- protected $_options;
+ private $_options;
/**
* Constructs the class with given parameters and reads object related data
@@ -81,6 +81,20 @@ abstract class ID3_Object
*/
public function getOptions() { return $this->_options; }
+ /**
+ * Returns the given option value, or the default value if the option is not
+ * defined.
+ *
+ * @param string $option The name of the option.
+ * @param mixed $defaultValue The default value to be returned.
+ */
+ public function getOption($option, $defaultValue = false)
+ {
+ if (isset($this->_options[$option]))
+ return $this->_options[$option];
+ return $defaultValue;
+ }
+
/**
* Sets the options array. See {@link ID3v2} class for available options.
*
@@ -88,6 +102,17 @@ abstract class ID3_Object
*/
public function setOptions(&$options) { $this->_options = $options; }
+ /**
+ * Sets the given option the given value.
+ *
+ * @param string $option The name of the option.
+ * @param mixed $value The value to set for the option.
+ */
+ public function setOption($option, $value)
+ {
+ $this->_options[$option] = $value;
+ }
+
/**
* Magic function so that $obj->value will work.
*
diff --git a/src/ID3v2.php b/src/ID3v2.php
index 1483007..1af6e54 100644
--- a/src/ID3v2.php
+++ b/src/ID3v2.php
@@ -132,6 +132,8 @@ final class ID3v2
throw new ID3_Exception
("File does not contain ID3v2 tag: " . $filename);
+ $startOffset = $this->_reader->getOffset();
+
$this->_header = new ID3_Header($this->_reader, $options);
if ($this->_header->getVersion() < 3 || $this->_header->getVersion() > 4)
throw new ID3_Exception
@@ -146,7 +148,7 @@ final class ID3v2
$offset = $this->_reader->getOffset();
// Jump off the loop if we reached the end of the tag
- if ($offset - 10 >= $this->_header->getSize() -
+ if ($offset - $startOffset - 10 >= $this->_header->getSize() -
($this->hasFooter() ? 10 : 0))
break;
@@ -337,9 +339,6 @@ final class ID3v2
*/
public function write($filename = false)
{
- if (empty($this->_frames))
- throw new ID3_Exception("Tag must contain at least one frame");
-
if ($filename === false && ($filename = $this->_filename) === false)
throw new ID3_Exception("No file given to write the tag to");
@@ -349,9 +348,10 @@ final class ID3v2
$oldTagSize = $this->_header->getSize();
$tag = "" . $this;
- $tagSize = strlen($tag);
+ $tagSize = empty($this->_frames) ? 0 : strlen($tag);
- if ($this->_reader === null || $tagSize - 10 > $oldTagSize) {
+ if ($this->_reader === null ||
+ $tagSize - 10 > $oldTagSize || $tagSize == 0) {
fseek($fd, 0, SEEK_END);
$oldFileSize = ftell($fd);
ftruncate($fd, $newFileSize = $tagSize - $oldTagSize + $oldFileSize);
@@ -363,7 +363,8 @@ final class ID3v2
}
}
fseek($fd, 0);
- fwrite($fd, $tag);
+ fwrite($fd, $tag, $tagLength);
+ fclose($fd);
$this->_filename = $filename;
}
@@ -393,6 +394,23 @@ final class ID3v2
throw new ID3_Exception("Unknown frame/field: " . $name);
}
+ /**
+ * Magic function so that isset($obj->value) will work. This method checks
+ * whether the frame matching the identifier exists.
+ *
+ * @param string $name The frame identifier.
+ * @return boolean
+ */
+ public function __isset($name) { return isset($this->_boxes[$name]); }
+
+ /**
+ * Magic function so that unset($obj->value) will work. This method removes
+ * all the frames matching the identifier.
+ *
+ * @param string $name The frame identifier.
+ */
+ public function __unset($name) { unset($this->_boxes[$name]); }
+
/**
* Returns the tag raw data.
*
diff --git a/src/ISO14496/Box.php b/src/ISO14496/Box.php
index a1afffe..a78992c 100644
--- a/src/ISO14496/Box.php
+++ b/src/ISO14496/Box.php
@@ -263,7 +263,7 @@ class ISO14496_Box
if ($size == 0)
$size = $this->_reader->getSize() - $offset;
- if (preg_match("/^\xa9?[a-z]{3,4}$/i", $type) &&
+ if (preg_match("/^\xa9?[a-z0-9]{3,4}$/i", $type) &&
substr($base, 0, min(strlen($base), strlen
($tmp = $path . ($path ? "." : "") . $type))) ==
substr($tmp, 0, min(strlen($base), strlen($tmp))))
@@ -287,14 +287,6 @@ class ISO14496_Box
array_pop(self::$_path);
}
- protected function getPath()
- {
- $path = "";
- echo "box: " .$this->getType() . ", parent: " . $this->getParent()."\n";
- for ($child = $this; ($parent = $child->getParent()) !== null; $child = $parent){echo "parent found";$path = $parent->getType() . "." . $path;};
- return $path;
- }
-
/**
* Checks whether the box given as an argument is present in the file. Returns
* true if one or more boxes are present, false
diff --git a/src/ISO14496/Box/ID32.php b/src/ISO14496/Box/ID32.php
index 7f1c44f..7c17394 100644
--- a/src/ISO14496/Box/ID32.php
+++ b/src/ISO14496/Box/ID32.php
@@ -124,8 +124,8 @@ final class ISO14496_Box_ID32 extends ISO14496_Box_Full
{
return parent::__toString
(Transform::toUInt16BE
- (((ord($language[0]) - 0x60) << 10) |
- ((ord($language[1]) - 0x60) << 5) |
- ord($language[2]) - 0x60) . $this->_tag);
+ (((ord($this->_language[0]) - 0x60) << 10) |
+ ((ord($this->_language[1]) - 0x60) << 5) |
+ ord($this->_language[2]) - 0x60) . $this->_tag);
}
}