source: spip-zone/_core_/branches/spip-3.2/plugins/medias/lib/getid3/extension.cache.sqlite3.php @ 113162

Last change on this file since 113162 was 113162, checked in by spip.franck@…, 5 months ago

Mise à jour de la lib getid en version 1.9.16, nous étions en 1.9.14
https://github.com/JamesHeinrich/getID3/blob/master/changelog.txt

File size: 10.1 KB
Line 
1<?php
2/////////////////////////////////////////////////////////////////
3/// getID3() by James Heinrich <info@getid3.org>               //
4//  available at https://github.com/JamesHeinrich/getID3       //
5//            or https://www.getid3.org                        //
6//            or http://getid3.sourceforge.net                 //
7//                                                             //
8// extension.cache.mysqli.php - part of getID3()               //
9// Please see readme.txt for more information                  //
10//                                                             //
11/////////////////////////////////////////////////////////////////
12//                                                             //
13// extension.cache.sqlite3.php - part of getID3()              //
14// Please see readme.txt for more information                  //
15//                                                             //
16/////////////////////////////////////////////////////////////////
17///                                                            //
18// MySQL extension written by Allan Hansen <ahØartemis*dk>     //
19// Table name mod by Carlo Capocasa <calroØcarlocapocasa*com>  //
20// MySQL extension was reworked for SQLite3 by                 //
21//   Karl G. Holz <newaeonØmac*com>                            //
22//                                                            ///
23/////////////////////////////////////////////////////////////////
24
25/**
26* This is a caching extension for getID3(). It works the exact same
27* way as the getID3 class, but return cached information much faster
28*
29*    Normal getID3 usage (example):
30*
31*       require_once 'getid3/getid3.php';
32*       $getID3 = new getID3;
33*       $getID3->encoding = 'UTF-8';
34*       $info1 = $getID3->analyze('file1.flac');
35*       $info2 = $getID3->analyze('file2.wv');
36*
37*    getID3_cached usage:
38*
39*       require_once 'getid3/getid3.php';
40*       require_once 'getid3/extension.cache.sqlite3.php';
41*       // all parameters are optional, defaults are:
42*       $getID3 = new getID3_cached_sqlite3($table='getid3_cache', $hide=FALSE);
43*       $getID3->encoding = 'UTF-8';
44*       $info1 = $getID3->analyze('file1.flac');
45*       $info2 = $getID3->analyze('file2.wv');
46*
47*
48* Supported Cache Types    (this extension)
49*
50*   SQL Databases:
51*
52*   cache_type          cache_options
53*   -------------------------------------------------------------------
54*   mysql               host, database, username, password
55*
56*   sqlite3             table='getid3_cache', hide=false        (PHP5)
57*
58*
59* ***  database file will be stored in the same directory as this script,
60* ***  webserver must have write access to that directory!
61* ***  set $hide to TRUE to prefix db file with .ht to pervent access from web client
62* ***  this is a default setting in the Apache configuration:
63*
64* The following lines prevent .htaccess and .htpasswd files from being viewed by Web clients.
65*
66* <Files ~ "^\.ht">
67*     Order allow,deny
68*     Deny from all
69*     Satisfy all
70* </Files>
71*
72********************************************************************************
73*
74*   -------------------------------------------------------------------
75*   DBM-Style Databases:    (use extension.cache.dbm)
76*
77*   cache_type          cache_options
78*   -------------------------------------------------------------------
79*   gdbm                dbm_filename, lock_filename
80*   ndbm                dbm_filename, lock_filename
81*   db2                 dbm_filename, lock_filename
82*   db3                 dbm_filename, lock_filename
83*   db4                 dbm_filename, lock_filename  (PHP5 required)
84*
85*   PHP must have write access to both dbm_filename and lock_filename.
86*
87* Recommended Cache Types
88*
89*   Infrequent updates, many reads      any DBM
90*   Frequent updates                    mysql
91********************************************************************************
92*
93* IMHO this is still a bit slow, I'm using this with MP4/MOV/ M4v files
94* there is a plan to add directory scanning and analyzing to make things work much faster
95*
96*
97*/
98class getID3_cached_sqlite3 extends getID3
99{
100        /**
101         * hold the sqlite db
102         *
103         * @var SQLite3 Resource
104         */
105        private $db;
106
107        /**
108         * table to use for caching
109         *
110         * @var string $table
111         */
112        private $table;
113
114        /**
115         * @param string  $table holds name of sqlite table
116         * @param boolean $hide
117         *
118         * @throws getid3_exception
119         * @throws Exception
120         */
121        public function __construct($table='getid3_cache', $hide=false) {
122                // Check for SQLite3 support
123                if (!function_exists('sqlite_open')) {
124                        throw new Exception('PHP not compiled with SQLite3 support.');
125                }
126
127                $this->table = $table; // Set table
128                $file = dirname(__FILE__).'/'.basename(__FILE__, 'php').'sqlite';
129                if ($hide) {
130                        $file = dirname(__FILE__).'/.ht.'.basename(__FILE__, 'php').'sqlite';
131                }
132                $this->db = new SQLite3($file);
133                $db = $this->db;
134                $this->create_table();   // Create cache table if not exists
135                $version = '';
136                $sql = $this->getQuery('version_check');
137                $stmt = $db->prepare($sql);
138                $stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT);
139                $result = $stmt->execute();
140                list($version) = $result->fetchArray();
141                if ($version != getID3::VERSION) { // Check version number and clear cache if changed
142                        $this->clear_cache();
143                }
144                parent::__construct();
145        }
146
147        /**
148         * close the database connection
149         */
150        public function __destruct() {
151                $db=$this->db;
152                $db->close();
153        }
154
155        /**
156         * clear the cache
157         *
158         * @return SQLite3Result
159         */
160        private function clear_cache() {
161                $db = $this->db;
162                $sql = $this->getQuery('delete_cache');
163                $db->exec($sql);
164                $sql = $this->getQuery('set_version');
165                $stmt = $db->prepare($sql);
166                $stmt->bindValue(':filename', getID3::VERSION, SQLITE3_TEXT);
167                $stmt->bindValue(':dirname', getID3::VERSION, SQLITE3_TEXT);
168                $stmt->bindValue(':val', getID3::VERSION, SQLITE3_TEXT);
169                return $stmt->execute();
170        }
171
172        /**
173         * analyze file and cache them, if cached pull from the db
174         *
175         * @param string  $filename
176         * @param integer $filesize
177         * @param string  $original_filename
178         *
179         * @return mixed|false
180         */
181        public function analyze($filename, $filesize=null, $original_filename='') {
182                if (!file_exists($filename)) {
183                        return false;
184                }
185                // items to track for caching
186                $filetime = filemtime($filename);
187                $filesize_real = filesize($filename);
188                // this will be saved for a quick directory lookup of analized files
189                // ... why do 50 seperate sql quries when you can do 1 for the same result
190                $dirname  = dirname($filename);
191                // Lookup file
192                $db = $this->db;
193                $sql = $this->getQuery('get_id3_data');
194                $stmt = $db->prepare($sql);
195                $stmt->bindValue(':filename', $filename,      SQLITE3_TEXT);
196                $stmt->bindValue(':filesize', $filesize_real, SQLITE3_INTEGER);
197                $stmt->bindValue(':filetime', $filetime,      SQLITE3_INTEGER);
198                $res = $stmt->execute();
199                list($result) = $res->fetchArray();
200                if (count($result) > 0 ) {
201                        return unserialize(base64_decode($result));
202                }
203                // if it hasn't been analyzed before, then do it now
204                $analysis = parent::analyze($filename, $filesize, $original_filename);
205                // Save result
206                $sql = $this->getQuery('cache_file');
207                $stmt = $db->prepare($sql);
208                $stmt->bindValue(':filename', $filename,                           SQLITE3_TEXT);
209                $stmt->bindValue(':dirname',  $dirname,                            SQLITE3_TEXT);
210                $stmt->bindValue(':filesize', $filesize_real,                      SQLITE3_INTEGER);
211                $stmt->bindValue(':filetime', $filetime,                           SQLITE3_INTEGER);
212                $stmt->bindValue(':atime',    time(),                              SQLITE3_INTEGER);
213                $stmt->bindValue(':val',      base64_encode(serialize($analysis)), SQLITE3_TEXT);
214                $res = $stmt->execute();
215                return $analysis;
216        }
217
218        /**
219         * create data base table
220         * this is almost the same as MySQL, with the exception of the dirname being added
221         *
222         * @return bool
223         */
224        private function create_table() {
225                $db = $this->db;
226                $sql = $this->getQuery('make_table');
227                return $db->exec($sql);
228        }
229
230        /**
231         * get cached directory
232         *
233         * This function is not in the MySQL extention, it's ment to speed up requesting multiple files
234         * which is ideal for podcasting, playlists, etc.
235         *
236         * @param string $dir directory to search the cache database for
237         *
238         * @return array return an array of matching id3 data
239         */
240        public function get_cached_dir($dir) {
241                $db = $this->db;
242                $rows = array();
243                $sql = $this->getQuery('get_cached_dir');
244                $stmt = $db->prepare($sql);
245                $stmt->bindValue(':dirname', $dir, SQLITE3_TEXT);
246                $res = $stmt->execute();
247                while ($row=$res->fetchArray()) {
248                        $rows[] = unserialize(base64_decode($row));
249                }
250                return $rows;
251        }
252
253        /**
254         * returns NULL if query is not found
255         *
256         * @param string $name
257         *
258         * @return null|string
259         */
260        public function getQuery($name)
261        {
262                switch ($name) {
263                        case 'version_check':
264                                return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = '-1' AND filetime = '-1' AND analyzetime = '-1'";
265                                break;
266                        case 'delete_cache':
267                                return "DELETE FROM $this->table";
268                                break;
269                        case 'set_version':
270                                return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, -1, -1, -1, :val)";
271                                break;
272                        case 'get_id3_data':
273                                return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = :filesize AND filetime = :filetime";
274                                break;
275                        case 'cache_file':
276                                return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, :filesize, :filetime, :atime, :val)";
277                                break;
278                        case 'make_table':
279                                return "CREATE TABLE IF NOT EXISTS $this->table (filename VARCHAR(255) DEFAULT '', dirname VARCHAR(255) DEFAULT '', filesize INT(11) DEFAULT '0', filetime INT(11) DEFAULT '0', analyzetime INT(11) DEFAULT '0', val text, PRIMARY KEY (filename, filesize, filetime))";
280                                break;
281                        case 'get_cached_dir':
282                                return "SELECT val FROM $this->table WHERE dirname = :dirname";
283                                break;
284                        default:
285                                return null;
286                }
287        }
288
289        /**
290        * use the magical __get() for sql queries
291        *
292        * access as easy as $this->{case name}, returns NULL if query is not found
293        *
294        * @param string $name
295        *
296        * @return string
297        * @deprecated use getQuery() instead
298        */
299        public function __get($name) {
300                return $this->getQuery($name);
301        }
302
303}
Note: See TracBrowser for help on using the repository browser.