Unverified Commit c6d87002 authored by Joe Hoyle's avatar Joe Hoyle
Browse files

Include updates getID3 lib

This is needed as getID3 lib that's bundled with Core is out of data and doesn't work with s3:// paths. See https://core.trac.wordpress.org/ticket/43836

We'll likely want to remove this one day once core supports a newer version, however this isn't likely to happen soon as the latest released vesion of getid3 still doesn't encorperate the fix needed.
parent 22526114
Loading
Loading
Loading
Loading
+252 −0
Original line number Diff line number Diff line
<?php

/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at http://getid3.sourceforge.net                 //
//            or https://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
{
	/**
	 * @var resource
	 */
	private $dba;

	/**
	 * @var resource|bool
	 */
	private $lock;

	/**
	 * @var string
	 */
	private $cache_type;

	/**
	 * @var string
	 */
	private $dbm_filename;

	/**
	 * constructor - see top of this file for cache type and cache_options
	 *
	 * @param string $cache_type
	 * @param string $dbm_filename
	 * @param string $lock_filename
	 *
	 * @throws Exception
	 * @throws getid3_exception
	 */
	public function __construct($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();
	}



	/**
	 * 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);
	}



	/**
	 * clear cache
	 *
	 * @throws Exception
	 */
	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'));
	}



	/**
	 * clear cache
	 *
	 * @param string $filename
	 * @param int    $filesize
	 * @param string $original_filename
	 *
	 * @return mixed
	 */
	public function analyze($filename, $filesize=null, $original_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 (isset($key) && file_exists($filename)) {
			dba_insert($key, serialize($result), $this->dba);
		}

		return $result;
	}

}
+227 −0
Original line number Diff line number Diff line
<?php

/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at http://getid3.sourceforge.net                 //
//            or https://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
{
	/**
	 * @var resource
	 */
	private $cursor;

	/**
	 * @var resource
	 */
	private $connection;

	/**
	 * @var string
	 */
	private $table;


	/**
	 * constructor - see top of this file for cache type and cache_options
	 *
	 * @param string $host
	 * @param string $database
	 * @param string $username
	 * @param string $password
	 * @param string $table
	 *
	 * @throws Exception
	 * @throws getid3_exception
	 */
	public function __construct($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();
	}



	/**
	 * 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);
	}



	/**
	 * analyze file
	 *
	 * @param string $filename
	 * @param int    $filesize
	 * @param string $original_filename
	 *
	 * @return mixed
	 */
	public function analyze($filename, $filesize=null, $original_filename='') {

        $filetime = 0;
		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, $filesize, $original_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;
	}



	/**
	 * (re)create sql table
	 *
	 * @param bool $drop
	 */
	private function create_table($drop=false) {

		$SQLquery  = 'CREATE TABLE IF NOT EXISTS `'.mysql_real_escape_string($this->table).'` (';
		$SQLquery .=   '`filename` VARCHAR(990) 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` LONGTEXT NOT NULL';
		$SQLquery .= ', PRIMARY KEY (`filename`, `filesize`, `filetime`))';
		$this->cursor = mysql_query($SQLquery, $this->connection);
		echo mysql_error($this->connection);
	}
}
+221 −0
Original line number Diff line number Diff line
<?php

/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org>               //
//  available at http://getid3.sourceforge.net                 //
//            or https://www.getid3.org                        //
//          also https://github.com/JamesHeinrich/getID3       //
/////////////////////////////////////////////////////////////////
//                                                             //
// extension.cache.mysqli.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.mysqli.php';
*       // 5th parameter (tablename) is optional, default is 'getid3_cache'
*       $getID3 = new getID3_cached_mysqli('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
*   -------------------------------------------------------------------
*   mysqli              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                    mysqli
*/

class getID3_cached_mysqli extends getID3
{
	/**
	 * @var mysqli
	 */
	private $mysqli;

	/**
	 * @var mysqli_result
	 */
	private $cursor;

	/**
	 * @var string
	 */
	private $table;


	/**
	 * constructor - see top of this file for cache type and cache_options
	 *
	 * @param string $host
	 * @param string $database
	 * @param string $username
	 * @param string $password
	 * @param string $table
	 *
	 * @throws Exception
	 * @throws getid3_exception
	 */
	public function __construct($host, $database, $username, $password, $table='getid3_cache') {

		// Check for mysqli support
		if (!function_exists('mysqli_connect')) {
			throw new Exception('PHP not compiled with mysqli support.');
		}

		// Connect to database
		$this->mysqli = new mysqli($host, $username, $password);
		if (!$this->mysqli) {
			throw new Exception('mysqli_connect() failed - check permissions and spelling.');
		}

		// Select database
		if (!$this->mysqli->select_db($database)) {
			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 `'.$this->mysqli->real_escape_string($this->table).'`';
		$SQLquery .= ' WHERE (`filename` = \''.$this->mysqli->real_escape_string(getID3::VERSION).'\')';
		$SQLquery .= ' AND (`filesize` = -1)';
		$SQLquery .= ' AND (`filetime` = -1)';
		$SQLquery .= ' AND (`analyzetime` = -1)';
		if ($this->cursor = $this->mysqli->query($SQLquery)) {
			list($version) = $this->cursor->fetch_array();
		}
		if ($version != getID3::VERSION) {
			$this->clear_cache();
		}

		parent::__construct();
	}


	/**
	 * clear cache
	 */
	public function clear_cache() {
		$this->mysqli->query('DELETE FROM `'.$this->mysqli->real_escape_string($this->table).'`');
		$this->mysqli->query('INSERT INTO `'.$this->mysqli->real_escape_string($this->table).'` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (\''.getID3::VERSION.'\', -1, -1, -1, \''.getID3::VERSION.'\')');
	}


	/**
	 * analyze file
	 *
	 * @param string $filename
	 * @param int    $filesize
	 * @param string $original_filename
	 *
	 * @return mixed
	 */
	public function analyze($filename, $filesize=null, $original_filename='') {

        $filetime = 0;
		if (file_exists($filename)) {

			// Short-hands
			$filetime = filemtime($filename);
			$filesize =  filesize($filename);

			// Lookup file
			$SQLquery  = 'SELECT `value`';
			$SQLquery .= ' FROM `'.$this->mysqli->real_escape_string($this->table).'`';
			$SQLquery .= ' WHERE (`filename` = \''.$this->mysqli->real_escape_string($filename).'\')';
			$SQLquery .= '   AND (`filesize` = \''.$this->mysqli->real_escape_string($filesize).'\')';
			$SQLquery .= '   AND (`filetime` = \''.$this->mysqli->real_escape_string($filetime).'\')';
			$this->cursor = $this->mysqli->query($SQLquery);
			if ($this->cursor->num_rows > 0) {
				// Hit
				list($result) = $this->cursor->fetch_array();
				return unserialize(base64_decode($result));
			}
		}

		// Miss
		$analysis = parent::analyze($filename, $filesize, $original_filename);

		// Save result
		if (file_exists($filename)) {
			$SQLquery  = 'INSERT INTO `'.$this->mysqli->real_escape_string($this->table).'` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (';
			$SQLquery .=   '\''.$this->mysqli->real_escape_string($filename).'\'';
			$SQLquery .= ', \''.$this->mysqli->real_escape_string($filesize).'\'';
			$SQLquery .= ', \''.$this->mysqli->real_escape_string($filetime).'\'';
			$SQLquery .= ', \''.$this->mysqli->real_escape_string(time()   ).'\'';
			$SQLquery .= ', \''.$this->mysqli->real_escape_string(base64_encode(serialize($analysis))).'\')';
			$this->cursor = $this->mysqli->query($SQLquery);
		}
		return $analysis;
	}


	/**
	 * (re)create mysqli table
	 *
	 * @param bool $drop
	 */
	private function create_table($drop=false) {
		$SQLquery  = 'CREATE TABLE IF NOT EXISTS `'.$this->mysqli->real_escape_string($this->table).'` (';
		$SQLquery .=   '`filename` VARCHAR(990) 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` LONGTEXT NOT NULL';
		$SQLquery .= ', PRIMARY KEY (`filename`, `filesize`, `filetime`))';
		$this->cursor = $this->mysqli->query($SQLquery);
		echo $this->mysqli->error;
	}
}
+293 −0

File added.

Preview size limit exceeded, changes collapsed.

+1839 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading