| // | Allan Hansen | // +----------------------------------------------------------------------+ // | write.flac.php | // | writing module for flac tags | // | dependencies: metaflac binary. | // +----------------------------------------------------------------------+ // // $Id: write.flac.php,v 1.9 2006/12/03 20:02:25 ah Exp $ class getid3_write_flac extends getid3_handler_write { public $comments = array (); public function __construct($filename) { if (ini_get('safe_mode')) { throw new getid3_exception('PHP running in Safe Mode (backtick operator not available). Cannot call metaflac binary.'); } static $initialized; if (!$initialized) { // check existance and version of metaflac if (!preg_match('/^metaflac ([0-9]+\.[0-9]+\.[0-9]+)/', `metaflac --version`, $r)) { throw new getid3_exception('Fatal: metaflac binary not available.'); } if (strnatcmp($r[1], '1.1.1') == -1) { throw new getid3_exception('Fatal: metaflac version 1.1.1 or newer is required, available version: ' . $r[1] . '.'); } $initialized = true; } parent::__construct($filename); } public function read() { // read info with metaflac if (!$info = trim(`metaflac --no-utf8-convert --export-tags-to=- "$this->filename"`)) { return; } // process info foreach (explode("\n", $info) as $line) { $pos = strpos($line, '='); $key = strtolower(substr($line, 0, $pos)); $value = substr($line, $pos+1); $this->comments[$key][] = $value; } // convert single element arrays to string foreach ($this->comments as $key => $value) { if (sizeof($value) == 1) { $this->comments[$key] = $value[0]; } } return true; } public function write() { // create temp file with new comments $temp_filename = tempnam('*', 'getID3'); if (!$fp = @fopen($temp_filename, 'wb')) { throw new getid3_exception('Could not write temporary file.'); } fwrite($fp, $this->generate_tag()); fclose($fp); // write comments $this->save_permissions(); if ($error = `metaflac --no-utf8-convert --remove-all-tags --import-tags-from="$temp_filename" "$this->filename" 2>&1`) { throw new getid3_exception('Fatal: metaflac returned error: ' . $error); } $this->restore_permissions(); // success @unlink($temp_filename); return true; } protected function generate_tag() { if (!$this->comments) { throw new getid3_exception('Cannot write empty tag, use remove() instead.'); } $result = ''; foreach ($this->comments as $key => $values) { // A case-insensitive FLAC field name that may consist of ASCII 0x20 through 0x7D, 0x3D ('=') excluded. // ASCII 0x41 through 0x5A inclusive (A-Z) is to be considered equivalent to ASCII 0x61 through 0x7A inclusive (a-z). if (preg_match("/[^\x20-\x7D]|\x3D/", $key)) { throw new getid3_exception('Field name "' . $key . '" contains invalid character(s).'); } $key = strtolower($key); if (!is_array($values)) { $values = array ($values); } foreach ($values as $value) { if (strstr($value, "\n") || strstr($value, "\r")) { throw new getid3_exception('Multi-line comments not supported (value contains \n or \r)'); } $result .= $key . '=' . $value . "\n"; } } return $result; } public function remove() { $this->save_permissions(); if ($error = `metaflac --remove-all-tags "$this->filename" 2>&1`) { throw new getid3_exception('Fatal: metaflac returned error: ' . $error); } $this->restore_permissions(); // success when removing non-existant tag return true; } } ?>