Browse Source

On integre getID3 pour permettre la lecture des metadata des video (largeur, hauteur, duree) (version tres simplifiee de ce que fait le plugin getID3, merci a kent1)

+ bugfix sur l'affichage en taille reduite dans le formulaire d'edition
3.1 v2.9.5
cedric@yterium.com 8 years ago
parent
commit
2dad57b681
  1. 75
      .gitattributes
  2. 6
      formulaires/editer_document.html
  3. 209
      lib/getid3/extension.cache.dbm.php
  4. 190
      lib/getid3/extension.cache.mysql.php
  5. 265
      lib/getid3/extension.cache.sqlite3.php
  6. 1379
      lib/getid3/getid3.lib.php
  7. 1803
      lib/getid3/getid3.php
  8. 281
      lib/getid3/module.archive.gzip.php
  9. 51
      lib/getid3/module.archive.rar.php
  10. 97
      lib/getid3/module.archive.szip.php
  11. 177
      lib/getid3/module.archive.tar.php
  12. 513
      lib/getid3/module.archive.zip.php
  13. 2013
      lib/getid3/module.audio-video.asf.php
  14. 72
      lib/getid3/module.audio-video.bink.php
  15. 745
      lib/getid3/module.audio-video.flv.php
  16. 1751
      lib/getid3/module.audio-video.matroska.php
  17. 606
      lib/getid3/module.audio-video.mpeg.php
  18. 224
      lib/getid3/module.audio-video.nsv.php
  19. 2246
      lib/getid3/module.audio-video.quicktime.php
  20. 528
      lib/getid3/module.audio-video.real.php
  21. 2586
      lib/getid3/module.audio-video.riff.php
  22. 140
      lib/getid3/module.audio-video.swf.php
  23. 79
      lib/getid3/module.audio-video.ts.php
  24. 59
      lib/getid3/module.audio.aa.php
  25. 513
      lib/getid3/module.audio.aac.php
  26. 474
      lib/getid3/module.audio.ac3.php
  27. 97
      lib/getid3/module.audio.amr.php
  28. 163
      lib/getid3/module.audio.au.php
  29. 125
      lib/getid3/module.audio.avr.php
  30. 228
      lib/getid3/module.audio.bonk.php
  31. 93
      lib/getid3/module.audio.dss.php
  32. 291
      lib/getid3/module.audio.dts.php
  33. 443
      lib/getid3/module.audio.flac.php
  34. 226
      lib/getid3/module.audio.la.php
  35. 128
      lib/getid3/module.audio.lpac.php
  36. 530
      lib/getid3/module.audio.midi.php
  37. 99
      lib/getid3/module.audio.mod.php
  38. 204
      lib/getid3/module.audio.monkey.php
  39. 2012
      lib/getid3/module.audio.mp3.php
  40. 507
      lib/getid3/module.audio.mpc.php
  41. 756
      lib/getid3/module.audio.ogg.php
  42. 427
      lib/getid3/module.audio.optimfrog.php
  43. 93
      lib/getid3/module.audio.rkau.php
  44. 182
      lib/getid3/module.audio.shorten.php
  45. 107
      lib/getid3/module.audio.tta.php
  46. 205
      lib/getid3/module.audio.voc.php
  47. 160
      lib/getid3/module.audio.vqf.php
  48. 398
      lib/getid3/module.audio.wavpack.php
  49. 688
      lib/getid3/module.graphic.bmp.php
  50. 51
      lib/getid3/module.graphic.efax.php
  51. 182
      lib/getid3/module.graphic.gif.php
  52. 338
      lib/getid3/module.graphic.jpg.php
  53. 133
      lib/getid3/module.graphic.pcd.php
  54. 518
      lib/getid3/module.graphic.png.php
  55. 102
      lib/getid3/module.graphic.svg.php
  56. 225
      lib/getid3/module.graphic.tiff.php
  57. 312
      lib/getid3/module.misc.cue.php
  58. 59
      lib/getid3/module.misc.exe.php
  59. 388
      lib/getid3/module.misc.iso.php
  60. 38
      lib/getid3/module.misc.msoffice.php
  61. 31
      lib/getid3/module.misc.par2.php
  62. 31
      lib/getid3/module.misc.pdf.php
  63. 371
      lib/getid3/module.tag.apetag.php
  64. 360
      lib/getid3/module.tag.id3v1.php
  65. 3425
      lib/getid3/module.tag.id3v2.php
  66. 294
      lib/getid3/module.tag.lyrics3.php
  67. 768
      lib/getid3/module.tag.xmp.php
  68. 224
      lib/getid3/write.apetag.php
  69. 137
      lib/getid3/write.id3v1.php
  70. 2050
      lib/getid3/write.id3v2.php
  71. 72
      lib/getid3/write.lyrics3.php
  72. 162
      lib/getid3/write.metaflac.php
  73. 608
      lib/getid3/write.php
  74. 274
      lib/getid3/write.real.php
  75. 120
      lib/getid3/write.vorbiscomment.php
  76. 36
      metadata/flv.php
  77. 56
      metadata/video.php
  78. 4
      modeles/video.html
  79. 2
      paquet.xml

75
.gitattributes vendored

@ -117,6 +117,79 @@ lang/paquet-medias_pt.php -text
lang/paquet-medias_pt_br.php -text
lang/paquet-medias_ru.php -text
lang/paquet-medias_sk.php -text
lib/getid3/extension.cache.dbm.php -text
lib/getid3/extension.cache.mysql.php -text
lib/getid3/extension.cache.sqlite3.php -text
lib/getid3/getid3.lib.php -text
lib/getid3/getid3.php -text
lib/getid3/module.archive.gzip.php -text
lib/getid3/module.archive.rar.php -text
lib/getid3/module.archive.szip.php -text
lib/getid3/module.archive.tar.php -text
lib/getid3/module.archive.zip.php -text
lib/getid3/module.audio-video.asf.php -text
lib/getid3/module.audio-video.bink.php -text
lib/getid3/module.audio-video.flv.php -text
lib/getid3/module.audio-video.matroska.php -text
lib/getid3/module.audio-video.mpeg.php -text
lib/getid3/module.audio-video.nsv.php -text
lib/getid3/module.audio-video.quicktime.php -text
lib/getid3/module.audio-video.real.php -text
lib/getid3/module.audio-video.riff.php -text
lib/getid3/module.audio-video.swf.php -text
lib/getid3/module.audio-video.ts.php -text
lib/getid3/module.audio.aa.php -text
lib/getid3/module.audio.aac.php -text
lib/getid3/module.audio.ac3.php -text
lib/getid3/module.audio.amr.php -text
lib/getid3/module.audio.au.php -text
lib/getid3/module.audio.avr.php -text
lib/getid3/module.audio.bonk.php -text
lib/getid3/module.audio.dss.php -text
lib/getid3/module.audio.dts.php -text
lib/getid3/module.audio.flac.php -text
lib/getid3/module.audio.la.php -text
lib/getid3/module.audio.lpac.php -text
lib/getid3/module.audio.midi.php -text
lib/getid3/module.audio.mod.php -text
lib/getid3/module.audio.monkey.php -text
lib/getid3/module.audio.mp3.php -text
lib/getid3/module.audio.mpc.php -text
lib/getid3/module.audio.ogg.php -text
lib/getid3/module.audio.optimfrog.php -text
lib/getid3/module.audio.rkau.php -text
lib/getid3/module.audio.shorten.php -text
lib/getid3/module.audio.tta.php -text
lib/getid3/module.audio.voc.php -text
lib/getid3/module.audio.vqf.php -text
lib/getid3/module.audio.wavpack.php -text
lib/getid3/module.graphic.bmp.php -text
lib/getid3/module.graphic.efax.php -text
lib/getid3/module.graphic.gif.php -text
lib/getid3/module.graphic.jpg.php -text
lib/getid3/module.graphic.pcd.php -text
lib/getid3/module.graphic.png.php -text
lib/getid3/module.graphic.svg.php -text
lib/getid3/module.graphic.tiff.php -text
lib/getid3/module.misc.cue.php -text
lib/getid3/module.misc.exe.php -text
lib/getid3/module.misc.iso.php -text
lib/getid3/module.misc.msoffice.php -text
lib/getid3/module.misc.par2.php -text
lib/getid3/module.misc.pdf.php -text
lib/getid3/module.tag.apetag.php -text
lib/getid3/module.tag.id3v1.php -text
lib/getid3/module.tag.id3v2.php -text
lib/getid3/module.tag.lyrics3.php -text
lib/getid3/module.tag.xmp.php -text
lib/getid3/write.apetag.php -text
lib/getid3/write.id3v1.php -text
lib/getid3/write.id3v2.php -text
lib/getid3/write.lyrics3.php -text
lib/getid3/write.metaflac.php -text
lib/getid3/write.php -text
lib/getid3/write.real.php -text
lib/getid3/write.vorbiscomment.php -text
lib/mejs/DO[!!-~]NOT[!!-~]CHANGE[!!-~]THESE[!!-~]FILES.[!!-~]USE[!!-~]-src-[!!-~]FOLDER.txt -text
lib/mejs/background.png -text
lib/mejs/bigplay.fw.png -text
@ -146,11 +219,11 @@ lib/mejs/silverlightmediaelement.xap -text
/medias_fonctions.php -text
/medias_ieconfig.php -text
/medias_pipelines.php -text
metadata/flv.php -text
metadata/html.php -text
metadata/image.php -text
metadata/svg.php -text
metadata/swf.php -text
metadata/video.php -text
modeles/application.html -text
modeles/audio.html -text
modeles/doc.html -text

6
formulaires/editer_document.html

@ -45,13 +45,13 @@
<input class="image" type="image" name="tournerR90" src="#CHEMIN_IMAGE{tourner-droite-12.png}" alt="<:medias:image_tourner_droite:>" />
<input class="image" type="image" name="tourner180" src="#CHEMIN_IMAGE{tourner-180-12.png}" alt="<:medias:image_tourner_180:>" />
</div>
[<a href='#ENV{apercu}'>(#ENV{apercu}|image_reduire{300,200})</a>]
[<a href='#ENV{apercu}'>(#ENV{apercu}|image_reduire{320,200})</a>]
]
[(#ENV{apercu}|non)
[(#ENV**{_inclus}|=={embed}|?{
[(#MODELE{emb,id_document=#ENV{id_document,''},largeur=300,hauteur=#HAUTEUR|min{200}})]
[(#MODELE{emb,id_document=#ENV{id_document,''},largeur=320,hauteur=#HAUTEUR|?{#HAUTEUR|div{#LARGEUR}|mult{320}|round{0},200}})]
,
[(#MODELE{doc,id_document=#ENV{id_document,''},largeur=300,hauteur=#HAUTEUR|min{200}}|extraire_balise{a})]
[(#MODELE{doc,id_document=#ENV{id_document,''},largeur=320,hauteur=#HAUTEUR|?{#HAUTEUR|div{#LARGEUR}|mult{320}|round{0},200}}|extraire_balise{a})]
})]
]
</li>

209
lib/getid3/extension.cache.dbm.php

@ -0,0 +1,209 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// //
// extension.cache.dbm.php - part of getID3() //
// Please see readme.txt for more information //
// ///
/////////////////////////////////////////////////////////////////
// //
// This extension written by Allan Hansen <ahØartemis*dk> //
// ///
/////////////////////////////////////////////////////////////////
/**
* This is a caching extension for getID3(). It works the exact same
* way as the getID3 class, but return cached information very fast
*
* Example:
*
* Normal getID3 usage (example):
*
* require_once 'getid3/getid3.php';
* $getID3 = new getID3;
* $getID3->encoding = 'UTF-8';
* $info1 = $getID3->analyze('file1.flac');
* $info2 = $getID3->analyze('file2.wv');
*
* getID3_cached usage:
*
* require_once 'getid3/getid3.php';
* require_once 'getid3/getid3/extension.cache.dbm.php';
* $getID3 = new getID3_cached('db3', '/tmp/getid3_cache.dbm',
* '/tmp/getid3_cache.lock');
* $getID3->encoding = 'UTF-8';
* $info1 = $getID3->analyze('file1.flac');
* $info2 = $getID3->analyze('file2.wv');
*
*
* Supported Cache Types
*
* SQL Databases: (use extension.cache.mysql)
*
* cache_type cache_options
* -------------------------------------------------------------------
* mysql host, database, username, password
*
*
* DBM-Style Databases: (this extension)
*
* cache_type cache_options
* -------------------------------------------------------------------
* gdbm dbm_filename, lock_filename
* ndbm dbm_filename, lock_filename
* db2 dbm_filename, lock_filename
* db3 dbm_filename, lock_filename
* db4 dbm_filename, lock_filename (PHP5 required)
*
* PHP must have write access to both dbm_filename and lock_filename.
*
*
* Recommended Cache Types
*
* Infrequent updates, many reads any DBM
* Frequent updates mysql
*/
class getID3_cached_dbm extends getID3
{
// public: constructor - see top of this file for cache type and cache_options
public function getID3_cached_dbm($cache_type, $dbm_filename, $lock_filename) {
// Check for dba extension
if (!extension_loaded('dba')) {
throw new Exception('PHP is not compiled with dba support, required to use DBM style cache.');
}
// Check for specific dba driver
if (!function_exists('dba_handlers') || !in_array($cache_type, dba_handlers())) {
throw new Exception('PHP is not compiled --with '.$cache_type.' support, required to use DBM style cache.');
}
// Create lock file if needed
if (!file_exists($lock_filename)) {
if (!touch($lock_filename)) {
throw new Exception('failed to create lock file: '.$lock_filename);
}
}
// Open lock file for writing
if (!is_writeable($lock_filename)) {
throw new Exception('lock file: '.$lock_filename.' is not writable');
}
$this->lock = fopen($lock_filename, 'w');
// Acquire exclusive write lock to lock file
flock($this->lock, LOCK_EX);
// Create dbm-file if needed
if (!file_exists($dbm_filename)) {
if (!touch($dbm_filename)) {
throw new Exception('failed to create dbm file: '.$dbm_filename);
}
}
// Try to open dbm file for writing
$this->dba = dba_open($dbm_filename, 'w', $cache_type);
if (!$this->dba) {
// Failed - create new dbm file
$this->dba = dba_open($dbm_filename, 'n', $cache_type);
if (!$this->dba) {
throw new Exception('failed to create dbm file: '.$dbm_filename);
}
// Insert getID3 version number
dba_insert(getID3::VERSION, getID3::VERSION, $this->dba);
}
// Init misc values
$this->cache_type = $cache_type;
$this->dbm_filename = $dbm_filename;
// Register destructor
register_shutdown_function(array($this, '__destruct'));
// Check version number and clear cache if changed
if (dba_fetch(getID3::VERSION, $this->dba) != getID3::VERSION) {
$this->clear_cache();
}
parent::__construct();
}
// public: destructor
public function __destruct() {
// Close dbm file
dba_close($this->dba);
// Release exclusive lock
flock($this->lock, LOCK_UN);
// Close lock file
fclose($this->lock);
}
// public: clear cache
public function clear_cache() {
// Close dbm file
dba_close($this->dba);
// Create new dbm file
$this->dba = dba_open($this->dbm_filename, 'n', $this->cache_type);
if (!$this->dba) {
throw new Exception('failed to clear cache/recreate dbm file: '.$this->dbm_filename);
}
// Insert getID3 version number
dba_insert(getID3::VERSION, getID3::VERSION, $this->dba);
// Re-register shutdown function
register_shutdown_function(array($this, '__destruct'));
}
// public: analyze file
public function analyze($filename) {
if (file_exists($filename)) {
// Calc key filename::mod_time::size - should be unique
$key = $filename.'::'.filemtime($filename).'::'.filesize($filename);
// Loopup key
$result = dba_fetch($key, $this->dba);
// Hit
if ($result !== false) {
return unserialize($result);
}
}
// Miss
$result = parent::analyze($filename);
// Save result
if (file_exists($filename)) {
dba_insert($key, serialize($result), $this->dba);
}
return $result;
}
}

190
lib/getid3/extension.cache.mysql.php

@ -0,0 +1,190 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// //
// extension.cache.mysql.php - part of getID3() //
// Please see readme.txt for more information //
// ///
/////////////////////////////////////////////////////////////////
// //
// This extension written by Allan Hansen <ahØartemis*dk> //
// Table name mod by Carlo Capocasa <calroØcarlocapocasa*com> //
// ///
/////////////////////////////////////////////////////////////////
/**
* This is a caching extension for getID3(). It works the exact same
* way as the getID3 class, but return cached information very fast
*
* Example: (see also demo.cache.mysql.php in /demo/)
*
* Normal getID3 usage (example):
*
* require_once 'getid3/getid3.php';
* $getID3 = new getID3;
* $getID3->encoding = 'UTF-8';
* $info1 = $getID3->analyze('file1.flac');
* $info2 = $getID3->analyze('file2.wv');
*
* getID3_cached usage:
*
* require_once 'getid3/getid3.php';
* require_once 'getid3/getid3/extension.cache.mysql.php';
* // 5th parameter (tablename) is optional, default is 'getid3_cache'
* $getID3 = new getID3_cached_mysql('localhost', 'database', 'username', 'password', 'tablename');
* $getID3->encoding = 'UTF-8';
* $info1 = $getID3->analyze('file1.flac');
* $info2 = $getID3->analyze('file2.wv');
*
*
* Supported Cache Types (this extension)
*
* SQL Databases:
*
* cache_type cache_options
* -------------------------------------------------------------------
* mysql host, database, username, password
*
*
* DBM-Style Databases: (use extension.cache.dbm)
*
* cache_type cache_options
* -------------------------------------------------------------------
* gdbm dbm_filename, lock_filename
* ndbm dbm_filename, lock_filename
* db2 dbm_filename, lock_filename
* db3 dbm_filename, lock_filename
* db4 dbm_filename, lock_filename (PHP5 required)
*
* PHP must have write access to both dbm_filename and lock_filename.
*
*
* Recommended Cache Types
*
* Infrequent updates, many reads any DBM
* Frequent updates mysql
*/
class getID3_cached_mysql extends getID3
{
// private vars
private $cursor;
private $connection;
// public: constructor - see top of this file for cache type and cache_options
public function getID3_cached_mysql($host, $database, $username, $password, $table='getid3_cache') {
// Check for mysql support
if (!function_exists('mysql_pconnect')) {
throw new Exception('PHP not compiled with mysql support.');
}
// Connect to database
$this->connection = mysql_pconnect($host, $username, $password);
if (!$this->connection) {
throw new Exception('mysql_pconnect() failed - check permissions and spelling.');
}
// Select database
if (!mysql_select_db($database, $this->connection)) {
throw new Exception('Cannot use database '.$database);
}
// Set table
$this->table = $table;
// Create cache table if not exists
$this->create_table();
// Check version number and clear cache if changed
$version = '';
$SQLquery = 'SELECT `value`';
$SQLquery .= ' FROM `'.mysql_real_escape_string($this->table).'`';
$SQLquery .= ' WHERE (`filename` = \''.mysql_real_escape_string(getID3::VERSION).'\')';
$SQLquery .= ' AND (`filesize` = -1)';
$SQLquery .= ' AND (`filetime` = -1)';
$SQLquery .= ' AND (`analyzetime` = -1)';
if ($this->cursor = mysql_query($SQLquery, $this->connection)) {
list($version) = mysql_fetch_array($this->cursor);
}
if ($version != getID3::VERSION) {
$this->clear_cache();
}
parent::__construct();
}
// public: clear cache
public function clear_cache() {
$this->cursor = mysql_query('DELETE FROM `'.mysql_real_escape_string($this->table).'`', $this->connection);
$this->cursor = mysql_query('INSERT INTO `'.mysql_real_escape_string($this->table).'` VALUES (\''.getID3::VERSION.'\', -1, -1, -1, \''.getID3::VERSION.'\')', $this->connection);
}
// public: analyze file
public function analyze($filename) {
if (file_exists($filename)) {
// Short-hands
$filetime = filemtime($filename);
$filesize = filesize($filename);
// Lookup file
$SQLquery = 'SELECT `value`';
$SQLquery .= ' FROM `'.mysql_real_escape_string($this->table).'`';
$SQLquery .= ' WHERE (`filename` = \''.mysql_real_escape_string($filename).'\')';
$SQLquery .= ' AND (`filesize` = \''.mysql_real_escape_string($filesize).'\')';
$SQLquery .= ' AND (`filetime` = \''.mysql_real_escape_string($filetime).'\')';
$this->cursor = mysql_query($SQLquery, $this->connection);
if (mysql_num_rows($this->cursor) > 0) {
// Hit
list($result) = mysql_fetch_array($this->cursor);
return unserialize(base64_decode($result));
}
}
// Miss
$analysis = parent::analyze($filename);
// Save result
if (file_exists($filename)) {
$SQLquery = 'INSERT INTO `'.mysql_real_escape_string($this->table).'` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (';
$SQLquery .= '\''.mysql_real_escape_string($filename).'\'';
$SQLquery .= ', \''.mysql_real_escape_string($filesize).'\'';
$SQLquery .= ', \''.mysql_real_escape_string($filetime).'\'';
$SQLquery .= ', \''.mysql_real_escape_string(time() ).'\'';
$SQLquery .= ', \''.mysql_real_escape_string(base64_encode(serialize($analysis))).'\')';
$this->cursor = mysql_query($SQLquery, $this->connection);
}
return $analysis;
}
// private: (re)create sql table
private function create_table($drop=false) {
$SQLquery = 'CREATE TABLE IF NOT EXISTS `'.mysql_real_escape_string($this->table).'` (';
$SQLquery .= '`filename` VARCHAR(255) NOT NULL DEFAULT \'\'';
$SQLquery .= ', `filesize` INT(11) NOT NULL DEFAULT \'0\'';
$SQLquery .= ', `filetime` INT(11) NOT NULL DEFAULT \'0\'';
$SQLquery .= ', `analyzetime` INT(11) NOT NULL DEFAULT \'0\'';
$SQLquery .= ', `value` TEXT NOT NULL';
$SQLquery .= ', PRIMARY KEY (`filename`, `filesize`, `filetime`)) ENGINE=MyISAM';
$this->cursor = mysql_query($SQLquery, $this->connection);
echo mysql_error($this->connection);
}
}

265
lib/getid3/extension.cache.sqlite3.php

@ -0,0 +1,265 @@
<?php
/////////////////////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////////////////////
/// //
// extension.cache.sqlite3.php - part of getID3() //
// Please see readme.txt for more information //
// ///
/////////////////////////////////////////////////////////////////////////////////
/// //
// MySQL extension written by Allan Hansen <ahØartemis*dk> //
// Table name mod by Carlo Capocasa <calroØcarlocapocasa*com> //
// MySQL extension was reworked for SQLite3 by Karl G. Holz <newaeonØmac*com> //
// ///
/////////////////////////////////////////////////////////////////////////////////
/**
* This is a caching extension for getID3(). It works the exact same
* way as the getID3 class, but return cached information much faster
*
* Normal getID3 usage (example):
*
* require_once 'getid3/getid3.php';
* $getID3 = new getID3;
* $getID3->encoding = 'UTF-8';
* $info1 = $getID3->analyze('file1.flac');
* $info2 = $getID3->analyze('file2.wv');
*
* getID3_cached usage:
*
* require_once 'getid3/getid3.php';
* require_once 'getid3/extension.cache.sqlite3.php';
* // all parameters are optional, defaults are:
* $getID3 = new getID3_cached_sqlite3($table='getid3_cache', $hide=FALSE);
* $getID3->encoding = 'UTF-8';
* $info1 = $getID3->analyze('file1.flac');
* $info2 = $getID3->analyze('file2.wv');
*
*
* Supported Cache Types (this extension)
*
* SQL Databases:
*
* cache_type cache_options
* -------------------------------------------------------------------
* mysql host, database, username, password
*
* sqlite3 table='getid3_cache', hide=false (PHP5)
*
*** database file will be stored in the same directory as this script,
*** webserver must have write access to that directory!
*** set $hide to TRUE to prefix db file with .ht to pervent access from web client
*** this is a default setting in the Apache configuration:
# The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
<Files ~ "^\.ht">
Order allow,deny
Deny from all
Satisfy all
</Files>
********************************************************************************
*
* -------------------------------------------------------------------
* DBM-Style Databases: (use extension.cache.dbm)
*
* cache_type cache_options
* -------------------------------------------------------------------
* gdbm dbm_filename, lock_filename
* ndbm dbm_filename, lock_filename
* db2 dbm_filename, lock_filename
* db3 dbm_filename, lock_filename
* db4 dbm_filename, lock_filename (PHP5 required)
*
* PHP must have write access to both dbm_filename and lock_filename.
*
* Recommended Cache Types
*
* Infrequent updates, many reads any DBM
* Frequent updates mysql
********************************************************************************
*
* IMHO this is still a bit slow, I'm using this with MP4/MOV/ M4v files
* there is a plan to add directory scanning and analyzing to make things work much faster
*
*
*/
class getID3_cached_sqlite3 extends getID3 {
/**
* __construct()
* @param string $table holds name of sqlite table
* @return type
*/
public function __construct($table='getid3_cache', $hide=false) {
$this->table = $table; // Set table
$file = dirname(__FILE__).'/'.basename(__FILE__, 'php').'sqlite';
if ($hide) {
$file = dirname(__FILE__).'/.ht.'.basename(__FILE__, 'php').'sqlite';
}
$this->db = new SQLite3($file);
$db = $this->db;
$this->create_table(); // Create cache table if not exists
$version = '';
$sql = $this->version_check;
$stmt = $db->prepare($sql);
$stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT);
$result = $stmt->execute();
list($version) = $result->fetchArray();
if ($version != getID3::VERSION) { // Check version number and clear cache if changed
$this->clear_cache();
}
return parent::__construct();
}
/**
* close the database connection
*/
public function __destruct() {
$db=$this->db;
$db->close();
}
/**
* hold the sqlite db
* @var SQLite Resource
*/
private $db;
/**
* table to use for caching
* @var string $table
*/
private $table;
/**
* clear the cache
* @access private
* @return type
*/
private function clear_cache() {
$db = $this->db;
$sql = $this->delete_cache;
$db->exec($sql);
$sql = $this->set_version;
$stmt = $db->prepare($sql);
$stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT);
$stmt->bindValue(':dirname', getID3::VERSION, SQLITE3_TEXT);
$stmt->bindValue(':val', getID3::VERSION, SQLITE3_TEXT);
return $stmt->execute();
}
/**
* analyze file and cache them, if cached pull from the db
* @param type $filename
* @return boolean
*/
public function analyze($filename) {
if (!file_exists($filename)) {
return false;
}
// items to track for caching
$filetime = filemtime($filename);
$filesize = filesize($filename);
// this will be saved for a quick directory lookup of analized files
// ... why do 50 seperate sql quries when you can do 1 for the same result
$dirname = dirname($filename);
// Lookup file
$db = $this->db;
$sql = $this->get_id3_data;
$stmt = $db->prepare($sql);
$stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
$stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER);
$stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
$res = $stmt->execute();
list($result) = $res->fetchArray();
if (count($result) > 0 ) {
return unserialize(base64_decode($result));
}
// if it hasn't been analyzed before, then do it now
$analysis = parent::analyze($filename);
// Save result
$sql = $this->cache_file;
$stmt = $db->prepare($sql);
$stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
$stmt->bindValue(':dirname', $dirname, SQLITE3_TEXT);
$stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER);
$stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER);
$stmt->bindValue(':atime', time(), SQLITE3_INTEGER);
$stmt->bindValue(':val', base64_encode(serialize($analysis)), SQLITE3_TEXT);
$res = $stmt->execute();
return $analysis;
}
/**
* create data base table
* this is almost the same as MySQL, with the exception of the dirname being added
* @return type
*/
private function create_table() {
$db = $this->db;
$sql = $this->make_table;
return $db->exec($sql);
}
/**
* get cached directory
*
* This function is not in the MySQL extention, it's ment to speed up requesting multiple files
* which is ideal for podcasting, playlists, etc.
*
* @access public
* @param string $dir directory to search the cache database for
* @return array return an array of matching id3 data
*/
public function get_cached_dir($dir) {
$db = $this->db;
$rows = array();
$sql = $this->get_cached_dir;
$stmt = $db->prepare($sql);
$stmt->bindValue(':dirname', $dir, SQLITE3_TEXT);
$res = $stmt->execute();
while ($row=$res->fetchArray()) {
$rows[] = unserialize(base64_decode($row));
}
return $rows;
}
/**
* use the magical __get() for sql queries
*
* access as easy as $this->{case name}, returns NULL if query is not found
*/
public function __get($name) {
switch($name) {
case 'version_check':
return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = '-1' AND filetime = '-1' AND analyzetime = '-1'";
break;
case 'delete_cache':
return "DELETE FROM $this->table";
break;
case 'set_version':
return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, -1, -1, -1, :val)";
break;
case 'get_id3_data':
return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = :filesize AND filetime = :filetime";
break;
case 'cache_file':
return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, :filesize, :filetime, :atime, :val)";
break;
case 'make_table':
return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) NOT NULL DEFAULT '', dirname VARCHAR(255) NOT NULL DEFAULT '', filesize INT(11) NOT NULL DEFAULT '0', filetime INT(11) NOT NULL DEFAULT '0', analyzetime INT(11) NOT NULL DEFAULT '0', val text not null, PRIMARY KEY (filename, filesize, filetime))";
break;
case 'get_cached_dir':
return "SELECT val FROM $this->table WHERE dirname = :dirname";
break;
}
return null;
}
}

1379
lib/getid3/getid3.lib.php

File diff suppressed because it is too large Load Diff

1803
lib/getid3/getid3.php

File diff suppressed because it is too large Load Diff

281
lib/getid3/module.archive.gzip.php

@ -0,0 +1,281 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.gzip.php //
// module for analyzing GZIP files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
// //
// Module originally written by //
// Mike Mozolin <teddybearØmail*ru> //
// //
/////////////////////////////////////////////////////////////////
class getid3_gzip extends getid3_handler {
// public: Optional file list - disable for speed.
public $option_gzip_parse_contents = false; // decode gzipped files, if possible, and parse recursively (.tar.gz for example)
public function Analyze() {
$info = &$this->getid3->info;
$info['fileformat'] = 'gzip';
$start_length = 10;
$unpack_header = 'a1id1/a1id2/a1cmethod/a1flags/a4mtime/a1xflags/a1os';
//+---+---+---+---+---+---+---+---+---+---+
//|ID1|ID2|CM |FLG| MTIME |XFL|OS |
//+---+---+---+---+---+---+---+---+---+---+
if ($info['filesize'] > $info['php_memory_limit']) {
$info['error'][] = 'File is too large ('.number_format($info['filesize']).' bytes) to read into memory (limit: '.number_format($info['php_memory_limit'] / 1048576).'MB)';
return false;
}
$this->fseek(0);
$buffer = $this->fread($info['filesize']);
$arr_members = explode("\x1F\x8B\x08", $buffer);
while (true) {
$is_wrong_members = false;
$num_members = intval(count($arr_members));
for ($i = 0; $i < $num_members; $i++) {
if (strlen($arr_members[$i]) == 0) {
continue;
}
$buf = "\x1F\x8B\x08".$arr_members[$i];
$attr = unpack($unpack_header, substr($buf, 0, $start_length));
if (!$this->get_os_type(ord($attr['os']))) {
// Merge member with previous if wrong OS type
$arr_members[$i - 1] .= $buf;
$arr_members[$i] = '';
$is_wrong_members = true;
continue;
}
}
if (!$is_wrong_members) {
break;
}
}
$info['gzip']['files'] = array();
$fpointer = 0;
$idx = 0;
for ($i = 0; $i < $num_members; $i++) {
if (strlen($arr_members[$i]) == 0) {
continue;
}
$thisInfo = &$info['gzip']['member_header'][++$idx];
$buff = "\x1F\x8B\x08".$arr_members[$i];
$attr = unpack($unpack_header, substr($buff, 0, $start_length));
$thisInfo['filemtime'] = getid3_lib::LittleEndian2Int($attr['mtime']);
$thisInfo['raw']['id1'] = ord($attr['cmethod']);
$thisInfo['raw']['id2'] = ord($attr['cmethod']);
$thisInfo['raw']['cmethod'] = ord($attr['cmethod']);
$thisInfo['raw']['os'] = ord($attr['os']);
$thisInfo['raw']['xflags'] = ord($attr['xflags']);
$thisInfo['raw']['flags'] = ord($attr['flags']);
$thisInfo['flags']['crc16'] = (bool) ($thisInfo['raw']['flags'] & 0x02);
$thisInfo['flags']['extra'] = (bool) ($thisInfo['raw']['flags'] & 0x04);
$thisInfo['flags']['filename'] = (bool) ($thisInfo['raw']['flags'] & 0x08);
$thisInfo['flags']['comment'] = (bool) ($thisInfo['raw']['flags'] & 0x10);
$thisInfo['compression'] = $this->get_xflag_type($thisInfo['raw']['xflags']);
$thisInfo['os'] = $this->get_os_type($thisInfo['raw']['os']);
if (!$thisInfo['os']) {
$info['error'][] = 'Read error on gzip file';
return false;
}
$fpointer = 10;
$arr_xsubfield = array();
// bit 2 - FLG.FEXTRA
//+---+---+=================================+
//| XLEN |...XLEN bytes of "extra field"...|
//+---+---+=================================+
if ($thisInfo['flags']['extra']) {
$w_xlen = substr($buff, $fpointer, 2);
$xlen = getid3_lib::LittleEndian2Int($w_xlen);
$fpointer += 2;
$thisInfo['raw']['xfield'] = substr($buff, $fpointer, $xlen);
// Extra SubFields
//+---+---+---+---+==================================+
//|SI1|SI2| LEN |... LEN bytes of subfield data ...|
//+---+---+---+---+==================================+
$idx = 0;
while (true) {
if ($idx >= $xlen) {
break;
}
$si1 = ord(substr($buff, $fpointer + $idx++, 1));
$si2 = ord(substr($buff, $fpointer + $idx++, 1));
if (($si1 == 0x41) && ($si2 == 0x70)) {
$w_xsublen = substr($buff, $fpointer + $idx, 2);
$xsublen = getid3_lib::LittleEndian2Int($w_xsublen);
$idx += 2;
$arr_xsubfield[] = substr($buff, $fpointer + $idx, $xsublen);
$idx += $xsublen;
} else {
break;
}
}
$fpointer += $xlen;
}
// bit 3 - FLG.FNAME
//+=========================================+
//|...original file name, zero-terminated...|
//+=========================================+
// GZIP files may have only one file, with no filename, so assume original filename is current filename without .gz
$thisInfo['filename'] = preg_replace('#\\.gz$#i', '', $info['filename']);
if ($thisInfo['flags']['filename']) {
$thisInfo['filename'] = '';
while (true) {
if (ord($buff[$fpointer]) == 0) {
$fpointer++;
break;
}
$thisInfo['filename'] .= $buff[$fpointer];
$fpointer++;
}
}
// bit 4 - FLG.FCOMMENT
//+===================================+
//|...file comment, zero-terminated...|
//+===================================+
if ($thisInfo['flags']['comment']) {
while (true) {
if (ord($buff[$fpointer]) == 0) {
$fpointer++;
break;
}
$thisInfo['comment'] .= $buff[$fpointer];
$fpointer++;
}
}
// bit 1 - FLG.FHCRC
//+---+---+
//| CRC16 |
//+---+---+
if ($thisInfo['flags']['crc16']) {
$w_crc = substr($buff, $fpointer, 2);
$thisInfo['crc16'] = getid3_lib::LittleEndian2Int($w_crc);
$fpointer += 2;
}
// bit 0 - FLG.FTEXT
//if ($thisInfo['raw']['flags'] & 0x01) {
// Ignored...
//}
// bits 5, 6, 7 - reserved
$thisInfo['crc32'] = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 8, 4));
$thisInfo['filesize'] = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 4));
$info['gzip']['files'] = getid3_lib::array_merge_clobber($info['gzip']['files'], getid3_lib::CreateDeepArray($thisInfo['filename'], '/', $thisInfo['filesize']));
if ($this->option_gzip_parse_contents) {
// Try to inflate GZip
$csize = 0;
$inflated = '';
$chkcrc32 = '';
if (function_exists('gzinflate')) {
$cdata = substr($buff, $fpointer);
$cdata = substr($cdata, 0, strlen($cdata) - 8);
$csize = strlen($cdata);
$inflated = gzinflate($cdata);
// Calculate CRC32 for inflated content
$thisInfo['crc32_valid'] = (bool) (sprintf('%u', crc32($inflated)) == $thisInfo['crc32']);
// determine format
$formattest = substr($inflated, 0, 32774);
$getid3_temp = new getID3();
$determined_format = $getid3_temp->GetFileFormat($formattest);
unset($getid3_temp);
// file format is determined
$determined_format['module'] = (isset($determined_format['module']) ? $determined_format['module'] : '');
switch ($determined_format['module']) {
case 'tar':
// view TAR-file info
if (file_exists(GETID3_INCLUDEPATH.$determined_format['include']) && include_once(GETID3_INCLUDEPATH.$determined_format['include'])) {
if (($temp_tar_filename = tempnam(GETID3_TEMP_DIR, 'getID3')) === false) {
// can't find anywhere to create a temp file, abort
$info['error'][] = 'Unable to create temp file to parse TAR inside GZIP file';
break;
}
if ($fp_temp_tar = fopen($temp_tar_filename, 'w+b')) {
fwrite($fp_temp_tar, $inflated);
fclose($fp_temp_tar);
$getid3_temp = new getID3();
$getid3_temp->openfile($temp_tar_filename);
$getid3_tar = new getid3_tar($getid3_temp);
$getid3_tar->Analyze();
$info['gzip']['member_header'][$idx]['tar'] = $getid3_temp->info['tar'];
unset($getid3_temp, $getid3_tar);
unlink($temp_tar_filename);
} else {
$info['error'][] = 'Unable to fopen() temp file to parse TAR inside GZIP file';
break;
}
}
break;
case '':
default:
// unknown or unhandled format
break;
}
}
}
}
return true;
}
// Converts the OS type
public function get_os_type($key) {
static $os_type = array(
'0' => 'FAT filesystem (MS-DOS, OS/2, NT/Win32)',
'1' => 'Amiga',
'2' => 'VMS (or OpenVMS)',
'3' => 'Unix',
'4' => 'VM/CMS',
'5' => 'Atari TOS',
'6' => 'HPFS filesystem (OS/2, NT)',
'7' => 'Macintosh',
'8' => 'Z-System',
'9' => 'CP/M',
'10' => 'TOPS-20',
'11' => 'NTFS filesystem (NT)',
'12' => 'QDOS',
'13' => 'Acorn RISCOS',
'255' => 'unknown'
);
return (isset($os_type[$key]) ? $os_type[$key] : '');
}
// Converts the eXtra FLags
public function get_xflag_type($key) {
static $xflag_type = array(
'0' => 'unknown',
'2' => 'maximum compression',
'4' => 'fastest algorithm'
);
return (isset($xflag_type[$key]) ? $xflag_type[$key] : '');
}
}

51
lib/getid3/module.archive.rar.php

@ -0,0 +1,51 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.rar.php //
// module for analyzing RAR files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_rar extends getid3_handler
{
public $option_use_rar_extension = false;
public function Analyze() {
$info = &$this->getid3->info;
$info['fileformat'] = 'rar';
if ($this->option_use_rar_extension === true) {
if (function_exists('rar_open')) {
if ($rp = rar_open($info['filenamepath'])) {
$info['rar']['files'] = array();
$entries = rar_list($rp);
foreach ($entries as $entry) {
$info['rar']['files'] = getid3_lib::array_merge_clobber($info['rar']['files'], getid3_lib::CreateDeepArray($entry->getName(), '/', $entry->getUnpackedSize()));
}
rar_close($rp);
return true;
} else {
$info['error'][] = 'failed to rar_open('.$info['filename'].')';
}
} else {
$info['error'][] = 'RAR support does not appear to be available in this PHP installation';
}
} else {
$info['error'][] = 'PHP-RAR processing has been disabled (set $getid3_rar->option_use_rar_extension=true to enable)';
}
return false;
}
}

97
lib/getid3/module.archive.szip.php

@ -0,0 +1,97 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.szip.php //
// module for analyzing SZIP compressed files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_szip extends getid3_handler
{
public function Analyze() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset']);
$SZIPHeader = $this->fread(6);
if (substr($SZIPHeader, 0, 4) != "SZ\x0A\x04") {
$info['error'][] = 'Expecting "53 5A 0A 04" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($SZIPHeader, 0, 4)).'"';
return false;
}
$info['fileformat'] = 'szip';
$info['szip']['major_version'] = getid3_lib::BigEndian2Int(substr($SZIPHeader, 4, 1));
$info['szip']['minor_version'] = getid3_lib::BigEndian2Int(substr($SZIPHeader, 5, 1));
$info['error'][] = 'SZIP parsing not enabled in this version of getID3() ['.$this->getid3->version().']';
return false;
while (!$this->feof()) {
$NextBlockID = $this->fread(2);
switch ($NextBlockID) {
case 'SZ':
// Note that szip files can be concatenated, this has the same effect as
// concatenating the files. this also means that global header blocks
// might be present between directory/data blocks.
$this->fseek(4, SEEK_CUR);
break;
case 'BH':
$BHheaderbytes = getid3_lib::BigEndian2Int($this->fread(3));
$BHheaderdata = $this->fread($BHheaderbytes);
$BHheaderoffset = 0;
while (strpos($BHheaderdata, "\x00", $BHheaderoffset) > 0) {
//filename as \0 terminated string (empty string indicates end)
//owner as \0 terminated string (empty is same as last file)
//group as \0 terminated string (empty is same as last file)
//3 byte filelength in this block
//2 byte access flags
//4 byte creation time (like in unix)
//4 byte modification time (like in unix)
//4 byte access time (like in unix)
$BHdataArray['filename'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, "\x00"));
$BHheaderoffset += (strlen($BHdataArray['filename']) + 1);
$BHdataArray['owner'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, "\x00"));
$BHheaderoffset += (strlen($BHdataArray['owner']) + 1);
$BHdataArray['group'] = substr($BHheaderdata, $BHheaderoffset, strcspn($BHheaderdata, "\x00"));
$BHheaderoffset += (strlen($BHdataArray['group']) + 1);
$BHdataArray['filelength'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 3));
$BHheaderoffset += 3;
$BHdataArray['access_flags'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 2));
$BHheaderoffset += 2;
$BHdataArray['creation_time'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4));
$BHheaderoffset += 4;
$BHdataArray['modification_time'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4));
$BHheaderoffset += 4;
$BHdataArray['access_time'] = getid3_lib::BigEndian2Int(substr($BHheaderdata, $BHheaderoffset, 4));
$BHheaderoffset += 4;
$info['szip']['BH'][] = $BHdataArray;
}
break;
default:
break 2;
}
}
return true;
}
}

177
lib/getid3/module.archive.tar.php

@ -0,0 +1,177 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.tar.php //
// module for analyzing TAR files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
// //
// Module originally written by //
// Mike Mozolin <teddybearØmail*ru> //
// //
/////////////////////////////////////////////////////////////////
class getid3_tar extends getid3_handler
{
public function Analyze() {
$info = &$this->getid3->info;
$info['fileformat'] = 'tar';
$info['tar']['files'] = array();
$unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155prefix';
$null_512k = str_repeat("\x00", 512); // end-of-file marker
$this->fseek(0);
while (!feof($this->getid3->fp)) {
$buffer = $this->fread(512);
if (strlen($buffer) < 512) {
break;
}
// check the block
$checksum = 0;
for ($i = 0; $i < 148; $i++) {
$checksum += ord($buffer{$i});
}
for ($i = 148; $i < 156; $i++) {
$checksum += ord(' ');
}
for ($i = 156; $i < 512; $i++) {
$checksum += ord($buffer{$i});
}
$attr = unpack($unpack_header, $buffer);
$name = (isset($attr['fname'] ) ? trim($attr['fname'] ) : '');
$mode = octdec(isset($attr['mode'] ) ? trim($attr['mode'] ) : '');
$uid = octdec(isset($attr['uid'] ) ? trim($attr['uid'] ) : '');
$gid = octdec(isset($attr['gid'] ) ? trim($attr['gid'] ) : '');
$size = octdec(isset($attr['size'] ) ? trim($attr['size'] ) : '');
$mtime = octdec(isset($attr['mtime'] ) ? trim($attr['mtime'] ) : '');
$chksum = octdec(isset($attr['chksum'] ) ? trim($attr['chksum'] ) : '');
$typflag = (isset($attr['typflag']) ? trim($attr['typflag']) : '');
$lnkname = (isset($attr['lnkname']) ? trim($attr['lnkname']) : '');
$magic = (isset($attr['magic'] ) ? trim($attr['magic'] ) : '');
$ver = (isset($attr['ver'] ) ? trim($attr['ver'] ) : '');
$uname = (isset($attr['uname'] ) ? trim($attr['uname'] ) : '');
$gname = (isset($attr['gname'] ) ? trim($attr['gname'] ) : '');
$devmaj = octdec(isset($attr['devmaj'] ) ? trim($attr['devmaj'] ) : '');
$devmin = octdec(isset($attr['devmin'] ) ? trim($attr['devmin'] ) : '');
$prefix = (isset($attr['prefix'] ) ? trim($attr['prefix'] ) : '');
if (($checksum == 256) && ($chksum == 0)) {
// EOF Found
break;
}
if ($prefix) {
$name = $prefix.'/'.$name;
}
if ((preg_match('#/$#', $name)) && !$name) {
$typeflag = 5;
}
if ($buffer == $null_512k) {
// it's the end of the tar-file...
break;
}
// Read to the next chunk
$this->fseek($size, SEEK_CUR);
$diff = $size % 512;
if ($diff != 0) {
// Padding, throw away
$this->fseek((512 - $diff), SEEK_CUR);
}
// Protect against tar-files with garbage at the end
if ($name == '') {
break;
}
$info['tar']['file_details'][$name] = array (
'name' => $name,
'mode_raw' => $mode,
'mode' => self::display_perms($mode),
'uid' => $uid,
'gid' => $gid,
'size' => $size,
'mtime' => $mtime,
'chksum' => $chksum,
'typeflag' => self::get_flag_type($typflag),
'linkname' => $lnkname,
'magic' => $magic,
'version' => $ver,
'uname' => $uname,
'gname' => $gname,
'devmajor' => $devmaj,
'devminor' => $devmin
);
$info['tar']['files'] = getid3_lib::array_merge_clobber($info['tar']['files'], getid3_lib::CreateDeepArray($info['tar']['file_details'][$name]['name'], '/', $size));
}
return true;
}
// Parses the file mode to file permissions
public function display_perms($mode) {
// Determine Type
if ($mode & 0x1000) $type='p'; // FIFO pipe
elseif ($mode & 0x2000) $type='c'; // Character special
elseif ($mode & 0x4000) $type='d'; // Directory
elseif ($mode & 0x6000) $type='b'; // Block special
elseif ($mode & 0x8000) $type='-'; // Regular
elseif ($mode & 0xA000) $type='l'; // Symbolic Link
elseif ($mode & 0xC000) $type='s'; // Socket
else $type='u'; // UNKNOWN
// Determine permissions
$owner['read'] = (($mode & 00400) ? 'r' : '-');
$owner['write'] = (($mode & 00200) ? 'w' : '-');
$owner['execute'] = (($mode & 00100) ? 'x' : '-');
$group['read'] = (($mode & 00040) ? 'r' : '-');
$group['write'] = (($mode & 00020) ? 'w' : '-');
$group['execute'] = (($mode & 00010) ? 'x' : '-');
$world['read'] = (($mode & 00004) ? 'r' : '-');
$world['write'] = (($mode & 00002) ? 'w' : '-');
$world['execute'] = (($mode & 00001) ? 'x' : '-');
// Adjust for SUID, SGID and sticky bit
if ($mode & 0x800) $owner['execute'] = ($owner['execute'] == 'x') ? 's' : 'S';
if ($mode & 0x400) $group['execute'] = ($group['execute'] == 'x') ? 's' : 'S';
if ($mode & 0x200) $world['execute'] = ($world['execute'] == 'x') ? 't' : 'T';
$s = sprintf('%1s', $type);
$s .= sprintf('%1s%1s%1s', $owner['read'], $owner['write'], $owner['execute']);
$s .= sprintf('%1s%1s%1s', $group['read'], $group['write'], $group['execute']);
$s .= sprintf('%1s%1s%1s'."\n", $world['read'], $world['write'], $world['execute']);
return $s;
}
// Converts the file type
public function get_flag_type($typflag) {
static $flag_types = array(
'0' => 'LF_NORMAL',
'1' => 'LF_LINK',
'2' => 'LF_SYNLINK',
'3' => 'LF_CHR',
'4' => 'LF_BLK',
'5' => 'LF_DIR',
'6' => 'LF_FIFO',
'7' => 'LF_CONFIG',
'D' => 'LF_DUMPDIR',
'K' => 'LF_LONGLINK',
'L' => 'LF_LONGNAME',
'M' => 'LF_MULTIVOL',
'N' => 'LF_NAMES',
'S' => 'LF_SPARSE',
'V' => 'LF_VOLHDR'
);
return (isset($flag_types[$typflag]) ? $flag_types[$typflag] : '');
}
}

513
lib/getid3/module.archive.zip.php

@ -0,0 +1,513 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at http://getid3.sourceforge.net //
// or http://www.getid3.org //
// also https://github.com/JamesHeinrich/getID3 //
/////////////////////////////////////////////////////////////////
// See readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.zip.php //
// module for analyzing pkZip files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_zip extends getid3_handler
{
public function Analyze() {
$info = &$this->getid3->info;
$info['fileformat'] = 'zip';
$info['zip']['encoding'] = 'ISO-8859-1';
$info['zip']['files'] = array();
$info['zip']['compressed_size'] = 0;
$info['zip']['uncompressed_size'] = 0;
$info['zip']['entries_count'] = 0;
if (!getid3_lib::intValueSupported($info['filesize'])) {
$info['error'][] = 'File is larger than '.round(PHP_INT_MAX / 1073741824).'GB, not supported by PHP';
return false;
} else {
$EOCDsearchData = '';
$EOCDsearchCounter = 0;
while ($EOCDsearchCounter++ < 512) {
$this->fseek(-128 * $EOCDsearchCounter, SEEK_END);
$EOCDsearchData = $this->fread(128).$EOCDsearchData;
if (strstr($EOCDsearchData, 'PK'."\x05\x06")) {
$EOCDposition = strpos($EOCDsearchData, 'PK'."\x05\x06");
$this->fseek((-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END);
$info['zip']['end_central_directory'] = $this->ZIPparseEndOfCentralDirectory();
$this->fseek($info['zip']['end_central_directory']['directory_offset']);
$info['zip']['entries_count'] = 0;
while ($centraldirectoryentry = $this->ZIPparseCentralDirectory($this->getid3->fp)) {
$info['zip']['central_directory'][] = $centraldirectoryentry;
$info['zip']['entries_count']++;
$info['zip']['compressed_size'] += $centraldirectoryentry['compressed_size'];
$info['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size'];
//if ($centraldirectoryentry['uncompressed_size'] > 0) { zero-byte files are valid
if (!empty($centraldirectoryentry['filename'])) {
$info['zip']['files'] = getid3_lib::array_merge_clobber($info['zip']['files'], getid3_lib::CreateDeepArray($centraldirectoryentry['filename'], '/', $centraldirectoryentry['uncompressed_size']));
}
}
if ($info['zip']['entries_count'] == 0) {
$info['error'][] = 'No Central Directory entries found (truncated file?)';
return false;
}
if (!empty($info['zip']['end_central_directory']['comment'])) {
$info['zip']['comments']['comment'][] = $info['zip']['end_central_directory']['comment'];
}
if (isset($info['zip']['central_directory'][0]['compression_method'])) {
$info['zip']['compression_method'] = $info['zip']['central_directory'][0]['compression_method'];
}
if (isset($info['zip']['central_directory'][0]['flags']['compression_speed'])) {
$info['zip']['compression_speed'] = $info['zip']['central_directory'][0]['flags']['compression_speed'];
}
if (isset($info['zip']['compression_method']) && ($info['zip']['compression_method'] == 'store') && !isset($info['zip']['compression_speed'])) {
$info['zip']['compression_speed'] = 'store';
}
// secondary check - we (should) already have all the info we NEED from the Central Directory above, but scanning each
// Local File Header entry will
foreach ($info['zip']['central_directory'] as $central_directory_entry) {
$this->fseek($central_directory_entry['entry_offset']);
if ($fileentry = $this->ZIPparseLocalFileHeader()) {
$info['zip']['entries'][] = $fileentry;
} else {
$info['warning'][] = 'Error parsing Local File Header at offset '.$central_directory_entry['entry_offset'];
}
}
if (!empty($info['zip']['files']['[Content_Types].xml']) &&
!empty($info['zip']['files']['_rels']['.rels']) &&
!empty($info['zip']['files']['docProps']['app.xml']) &&
!empty($info['zip']['files']['docProps']['core.xml'])) {
// http://technet.microsoft.com/en-us/library/cc179224.aspx
$info['fileformat'] = 'zip.msoffice';
if (!empty($ThisFileInfo['zip']['files']['ppt'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
} elseif (!empty($ThisFileInfo['zip']['files']['xl'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
} elseif (!empty($ThisFileInfo['zip']['files']['word'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
}
}
return true;
}
}
}
if (!$this->getZIPentriesFilepointer()) {
unset($info['zip']);
$info['fileformat'] = '';
$info['error'][] = 'Cannot find End Of Central Directory (truncated file?)';
return false;
}
// central directory couldn't be found and/or parsed
// scan through actual file data entries, recover as much as possible from probable trucated file
if ($info['zip']['compressed_size'] > ($info['filesize'] - 46 - 22)) {
$info['error'][] = 'Warning: Truncated file! - Total compressed file sizes ('.$info['zip']['compressed_size'].' bytes) is greater than filesize minus Central Directory and End Of Central Directory structures ('.($info['filesize'] - 46 - 22).' bytes)';
}
$info['error'][] = 'Cannot find End Of Central Directory - returned list of files in [zip][entries] array may not be complete';
foreach ($info['zip']['entries'] as $key => $valuearray) {
$info['zip']['files'][$valuearray['filename']] = $valuearray['uncompressed_size'];
}
return true;
}
public function getZIPHeaderFilepointerTopDown() {
$info = &$this->getid3->info;
$info['fileformat'] = 'zip';
$info['zip']['compressed_size'] = 0;
$info['zip']['uncompressed_size'] = 0;
$info['zip']['entries_count'] = 0;
rewind($this->getid3->fp);
while ($fileentry = $this->ZIPparseLocalFileHeader()) {
$info['zip']['entries'][] = $fileentry;
$info['zip']['entries_count']++;
}
if ($info['zip']['entries_count'] == 0) {
$info['error'][] = 'No Local File Header entries found';
return false;
}
$info['zip']['entries_count'] = 0;
while ($centraldirectoryentry = $this->ZIPparseCentralDirectory($this->getid3->fp)) {
$info['zip']['central_directory'][] = $centraldirectoryentry;
$info['zip']['entries_count']++;
$info['zip']['compressed_size'] += $centraldirectoryentry['compressed_size'];
$info['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size'];
}
if ($info['zip']['entries_count'] == 0) {
$info['error'][] = 'No Central Directory entries found (truncated file?)';
return false;
}
if ($EOCD = $this->ZIPparseEndOfCentralDirectory()) {
$info['zip']['end_central_directory'] = $EOCD;
} else {
$info['error'][] = 'No End Of Central Directory entry found (truncated file?)';
return false;
}
if (!empty($info['zip']['end_central_directory']['comment'])) {
$info['zip']['comments']['comment'][] = $info['zip']['end_central_directory']['comment'];
}
return true;
}
public function getZIPentriesFilepointer() {
$info = &$this->getid3->info;
$info['zip']['compressed_size'] = 0;
$info['zip']['uncompressed_size'] = 0;
$info['zip']['entries_count'] = 0;
rewind($this->getid3->fp);
while ($fileentry = $this->ZIPparseLocalFileHeader()) {
$info['zip']['entries'][] = $fileentry;
$info['zip']['entries_count']++;
$info['zip']['compressed_size'] += $fileentry['compressed_size'];
$info['zip']['uncompressed_size'] += $fileentry['uncompressed_size'];
}
if ($info['zip']['entries_count'] == 0) {
$info['error'][] = 'No Local File Header entries found';
return false;
}
return true;