File indexing completed on 2025-02-02 05:44:50
0001 <?php 0002 ///////////////////////////////////////////////////////////////////////////////// 0003 /// getID3() by James Heinrich <info@getid3.org> // 0004 // available at http://getid3.sourceforge.net // 0005 // or http://www.getid3.org // 0006 // also https://github.com/JamesHeinrich/getID3 // 0007 ///////////////////////////////////////////////////////////////////////////////// 0008 /// // 0009 // extension.cache.sqlite3.php - part of getID3() // 0010 // Please see readme.txt for more information // 0011 // /// 0012 ///////////////////////////////////////////////////////////////////////////////// 0013 /// // 0014 // MySQL extension written by Allan Hansen <ahØartemis*dk> // 0015 // Table name mod by Carlo Capocasa <calroØcarlocapocasa*com> // 0016 // MySQL extension was reworked for SQLite3 by Karl G. Holz <newaeonØmac*com> // 0017 // /// 0018 ///////////////////////////////////////////////////////////////////////////////// 0019 /** 0020 * This is a caching extension for getID3(). It works the exact same 0021 * way as the getID3 class, but return cached information much faster 0022 * 0023 * Normal getID3 usage (example): 0024 * 0025 * require_once 'getid3/getid3.php'; 0026 * $getID3 = new getID3; 0027 * $getID3->encoding = 'UTF-8'; 0028 * $info1 = $getID3->analyze('file1.flac'); 0029 * $info2 = $getID3->analyze('file2.wv'); 0030 * 0031 * getID3_cached usage: 0032 * 0033 * require_once 'getid3/getid3.php'; 0034 * require_once 'getid3/extension.cache.sqlite3.php'; 0035 * // all parameters are optional, defaults are: 0036 * $getID3 = new getID3_cached_sqlite3($table='getid3_cache', $hide=FALSE); 0037 * $getID3->encoding = 'UTF-8'; 0038 * $info1 = $getID3->analyze('file1.flac'); 0039 * $info2 = $getID3->analyze('file2.wv'); 0040 * 0041 * 0042 * Supported Cache Types (this extension) 0043 * 0044 * SQL Databases: 0045 * 0046 * cache_type cache_options 0047 * ------------------------------------------------------------------- 0048 * mysql host, database, username, password 0049 * 0050 * sqlite3 table='getid3_cache', hide=false (PHP5) 0051 * 0052 0053 *** database file will be stored in the same directory as this script, 0054 *** webserver must have write access to that directory! 0055 *** set $hide to TRUE to prefix db file with .ht to pervent access from web client 0056 *** this is a default setting in the Apache configuration: 0057 0058 # The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients. 0059 0060 <Files ~ "^\.ht"> 0061 Order allow,deny 0062 Deny from all 0063 Satisfy all 0064 </Files> 0065 0066 ******************************************************************************** 0067 * 0068 * ------------------------------------------------------------------- 0069 * DBM-Style Databases: (use extension.cache.dbm) 0070 * 0071 * cache_type cache_options 0072 * ------------------------------------------------------------------- 0073 * gdbm dbm_filename, lock_filename 0074 * ndbm dbm_filename, lock_filename 0075 * db2 dbm_filename, lock_filename 0076 * db3 dbm_filename, lock_filename 0077 * db4 dbm_filename, lock_filename (PHP5 required) 0078 * 0079 * PHP must have write access to both dbm_filename and lock_filename. 0080 * 0081 * Recommended Cache Types 0082 * 0083 * Infrequent updates, many reads any DBM 0084 * Frequent updates mysql 0085 ******************************************************************************** 0086 * 0087 * IMHO this is still a bit slow, I'm using this with MP4/MOV/ M4v files 0088 * there is a plan to add directory scanning and analyzing to make things work much faster 0089 * 0090 * 0091 */ 0092 class getID3_cached_sqlite3 extends getID3 { 0093 0094 /** 0095 * __construct() 0096 * 0097 * @param string $table holds name of sqlite table 0098 * @param bool $hide 0099 */ 0100 public function __construct($table='getid3_cache', $hide=false) { 0101 $this->table = $table; // Set table 0102 $file = dirname(__FILE__).'/'.basename(__FILE__, 'php').'sqlite'; 0103 if ($hide) { 0104 $file = dirname(__FILE__).'/.ht.'.basename(__FILE__, 'php').'sqlite'; 0105 } 0106 $this->db = new SQLite3($file); 0107 $db = $this->db; 0108 $this->create_table(); // Create cache table if not exists 0109 $version = ''; 0110 $sql = $this->version_check; 0111 $stmt = $db->prepare($sql); 0112 $stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT); 0113 $result = $stmt->execute(); 0114 list($version) = $result->fetchArray(); 0115 if ($version != getID3::VERSION) { // Check version number and clear cache if changed 0116 $this->clear_cache(); 0117 } 0118 return parent::__construct(); 0119 } 0120 0121 /** 0122 * close the database connection 0123 */ 0124 public function __destruct() { 0125 $db=$this->db; 0126 $db->close(); 0127 } 0128 0129 /** 0130 * hold the sqlite db 0131 * @var SQLite Resource 0132 */ 0133 private $db; 0134 0135 /** 0136 * table to use for caching 0137 * @var string $table 0138 */ 0139 private $table; 0140 0141 /** 0142 * clear the cache 0143 * @access private 0144 * @return type 0145 */ 0146 private function clear_cache() { 0147 $db = $this->db; 0148 $sql = $this->delete_cache; 0149 $db->exec($sql); 0150 $sql = $this->set_version; 0151 $stmt = $db->prepare($sql); 0152 $stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT); 0153 $stmt->bindValue(':dirname', getID3::VERSION, SQLITE3_TEXT); 0154 $stmt->bindValue(':val', getID3::VERSION, SQLITE3_TEXT); 0155 return $stmt->execute(); 0156 } 0157 0158 /** 0159 * analyze file and cache them, if cached pull from the db 0160 * @param type $filename 0161 * @return boolean 0162 */ 0163 public function analyze($filename) { 0164 if (!file_exists($filename)) { 0165 return false; 0166 } 0167 // items to track for caching 0168 $filetime = filemtime($filename); 0169 $filesize = filesize($filename); 0170 // this will be saved for a quick directory lookup of analized files 0171 // ... why do 50 seperate sql quries when you can do 1 for the same result 0172 $dirname = dirname($filename); 0173 // Lookup file 0174 $db = $this->db; 0175 $sql = $this->get_id3_data; 0176 $stmt = $db->prepare($sql); 0177 $stmt->bindValue(':filename', $filename, SQLITE3_TEXT); 0178 $stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER); 0179 $stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER); 0180 $res = $stmt->execute(); 0181 list($result) = $res->fetchArray(); 0182 if (count($result) > 0 ) { 0183 return unserialize(base64_decode($result)); 0184 } 0185 // if it hasn't been analyzed before, then do it now 0186 $analysis = parent::analyze($filename); 0187 // Save result 0188 $sql = $this->cache_file; 0189 $stmt = $db->prepare($sql); 0190 $stmt->bindValue(':filename', $filename, SQLITE3_TEXT); 0191 $stmt->bindValue(':dirname', $dirname, SQLITE3_TEXT); 0192 $stmt->bindValue(':filesize', $filesize, SQLITE3_INTEGER); 0193 $stmt->bindValue(':filetime', $filetime, SQLITE3_INTEGER); 0194 $stmt->bindValue(':atime', time(), SQLITE3_INTEGER); 0195 $stmt->bindValue(':val', base64_encode(serialize($analysis)), SQLITE3_TEXT); 0196 $res = $stmt->execute(); 0197 return $analysis; 0198 } 0199 0200 /** 0201 * create data base table 0202 * this is almost the same as MySQL, with the exception of the dirname being added 0203 * @return type 0204 */ 0205 private function create_table() { 0206 $db = $this->db; 0207 $sql = $this->make_table; 0208 return $db->exec($sql); 0209 } 0210 0211 /** 0212 * get cached directory 0213 * 0214 * This function is not in the MySQL extention, it's ment to speed up requesting multiple files 0215 * which is ideal for podcasting, playlists, etc. 0216 * 0217 * @access public 0218 * @param string $dir directory to search the cache database for 0219 * @return array return an array of matching id3 data 0220 */ 0221 public function get_cached_dir($dir) { 0222 $db = $this->db; 0223 $rows = array(); 0224 $sql = $this->get_cached_dir; 0225 $stmt = $db->prepare($sql); 0226 $stmt->bindValue(':dirname', $dir, SQLITE3_TEXT); 0227 $res = $stmt->execute(); 0228 while ($row=$res->fetchArray()) { 0229 $rows[] = unserialize(base64_decode($row)); 0230 } 0231 return $rows; 0232 } 0233 0234 /** 0235 * use the magical __get() for sql queries 0236 * 0237 * access as easy as $this->{case name}, returns NULL if query is not found 0238 * @param $name 0239 * @return string|null 0240 */ 0241 public function __get($name) { 0242 switch($name) { 0243 case 'version_check': 0244 return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = '-1' AND filetime = '-1' AND analyzetime = '-1'"; 0245 break; 0246 case 'delete_cache': 0247 return "DELETE FROM $this->table"; 0248 break; 0249 case 'set_version': 0250 return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, -1, -1, -1, :val)"; 0251 break; 0252 case 'get_id3_data': 0253 return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = :filesize AND filetime = :filetime"; 0254 break; 0255 case 'cache_file': 0256 return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, :filesize, :filetime, :atime, :val)"; 0257 break; 0258 case 'make_table': 0259 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))"; 0260 break; 0261 case 'get_cached_dir': 0262 return "SELECT val FROM $this->table WHERE dirname = :dirname"; 0263 break; 0264 } 0265 return null; 0266 } 0267 0268 }