aboutsummaryrefslogtreecommitdiff
path: root/includes/getid3/extension.cache.sqlite3.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/getid3/extension.cache.sqlite3.php')
-rw-r--r--includes/getid3/extension.cache.sqlite3.php297
1 files changed, 297 insertions, 0 deletions
diff --git a/includes/getid3/extension.cache.sqlite3.php b/includes/getid3/extension.cache.sqlite3.php
new file mode 100644
index 0000000..dbcc72a
--- /dev/null
+++ b/includes/getid3/extension.cache.sqlite3.php
@@ -0,0 +1,297 @@
+<?php
+/////////////////////////////////////////////////////////////////
+/// getID3() by James Heinrich <info@getid3.org> //
+// available at https://github.com/JamesHeinrich/getID3 //
+// or https://www.getid3.org //
+// or http://getid3.sourceforge.net //
+// //
+// extension.cache.mysqli.php - part of getID3() //
+// Please see readme.txt for more information //
+// //
+/////////////////////////////////////////////////////////////////
+// //
+// 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
+{
+ /**
+ * hold the sqlite db
+ *
+ * @var SQLite3 Resource
+ */
+ private $db;
+
+ /**
+ * table to use for caching
+ *
+ * @var string $table
+ */
+ private $table;
+
+ /**
+ * @param string $table holds name of sqlite table
+ * @param boolean $hide
+ *
+ * @throws getid3_exception
+ * @throws Exception
+ */
+ public function __construct($table='getid3_cache', $hide=false) {
+ // Check for SQLite3 support
+ if (!function_exists('sqlite_open')) {
+ throw new Exception('PHP not compiled with SQLite3 support.');
+ }
+
+ $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->getQuery('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();
+ }
+ parent::__construct();
+ }
+
+ /**
+ * close the database connection
+ */
+ public function __destruct() {
+ $db=$this->db;
+ $db->close();
+ }
+
+ /**
+ * clear the cache
+ *
+ * @return SQLite3Result
+ */
+ private function clear_cache() {
+ $db = $this->db;
+ $sql = $this->getQuery('delete_cache');
+ $db->exec($sql);
+ $sql = $this->getQuery('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 string $filename
+ * @param integer $filesize
+ * @param string $original_filename
+ * @param resource $fp
+ *
+ * @return mixed|false
+ */
+ public function analyze($filename, $filesize=null, $original_filename='', $fp=null) {
+ if (!file_exists($filename)) {
+ return false;
+ }
+ // items to track for caching
+ $filetime = filemtime($filename);
+ $filesize_real = 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->getQuery('get_id3_data');
+ $stmt = $db->prepare($sql);
+ $stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
+ $stmt->bindValue(':filesize', $filesize_real, 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, $filesize, $original_filename, $fp);
+ // Save result
+ $sql = $this->getQuery('cache_file');
+ $stmt = $db->prepare($sql);
+ $stmt->bindValue(':filename', $filename, SQLITE3_TEXT);
+ $stmt->bindValue(':dirname', $dirname, SQLITE3_TEXT);
+ $stmt->bindValue(':filesize', $filesize_real, 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 bool
+ */
+ private function create_table() {
+ $db = $this->db;
+ $sql = $this->getQuery('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.
+ *
+ * @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->getQuery('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;
+ }
+
+ /**
+ * returns NULL if query is not found
+ *
+ * @param string $name
+ *
+ * @return null|string
+ */
+ public function getQuery($name)
+ {
+ switch ($name) {
+ case 'version_check':
+ return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = '-1' AND filetime = '-1' AND analyzetime = '-1'";
+ case 'delete_cache':
+ return "DELETE FROM $this->table";
+ case 'set_version':
+ return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, -1, -1, -1, :val)";
+ case 'get_id3_data':
+ return "SELECT val FROM $this->table WHERE filename = :filename AND filesize = :filesize AND filetime = :filetime";
+ case 'cache_file':
+ return "INSERT INTO $this->table (filename, dirname, filesize, filetime, analyzetime, val) VALUES (:filename, :dirname, :filesize, :filetime, :atime, :val)";
+ case 'make_table':
+ 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))";
+ case 'get_cached_dir':
+ return "SELECT val FROM $this->table WHERE dirname = :dirname";
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * use the magical __get() for sql queries
+ *
+ * access as easy as $this->{case name}, returns NULL if query is not found
+ *
+ * @param string $name
+ *
+ * @return string
+ * @deprecated use getQuery() instead
+ */
+ public function __get($name) {
+ return $this->getQuery($name);
+ }
+
+}