2010-12-07 20:19:27 +01:00
< ? php
2012-02-24 15:07:04 +01:00
require_once 'formatters/LengthFormatter.php' ;
2012-02-24 18:22:07 +01:00
require_once 'formatters/SamplerateFormatter.php' ;
require_once 'formatters/BitrateFormatter.php' ;
2012-02-24 15:07:04 +01:00
2010-12-07 20:19:27 +01:00
/**
2011-09-22 18:24:17 +02:00
* Application_Model_StoredFile class
2010-12-07 20:19:27 +01:00
*
2011-01-05 18:19:58 +01:00
* @ package Airtime
2010-12-07 20:19:27 +01:00
* @ subpackage StorageServer
* @ copyright 2010 Sourcefabric O . P . S .
* @ license http :// www . gnu . org / licenses / gpl . txt
* @ see MetaData
*/
2012-07-16 03:17:13 +02:00
class Application_Model_StoredFile
{
2010-12-07 20:19:27 +01:00
/**
2011-06-08 10:15:35 +02:00
* @ holds propel database object
2015-07-07 19:54:19 +02:00
* @ var CcFiles
2011-06-08 10:15:35 +02:00
*/
private $_file ;
2010-12-07 20:19:27 +01:00
2013-04-20 02:10:51 +02:00
/**
* @ holds PDO object reference
*/
private $_con ;
2010-12-07 20:19:27 +01:00
/**
2011-06-08 10:15:35 +02:00
* array of db metadata -> propel
2010-12-07 20:19:27 +01:00
*/
2011-06-08 10:15:35 +02:00
private $_dbMD = array (
2012-08-23 16:21:39 +02:00
" track_title " => " DbTrackTitle " ,
" artist_name " => " DbArtistName " ,
" album_title " => " DbAlbumTitle " ,
" genre " => " DbGenre " ,
" mood " => " DbMood " ,
2011-06-08 10:15:35 +02:00
" track_number " => " DbTrackNumber " ,
2012-08-23 16:21:39 +02:00
" bpm " => " DbBpm " ,
" label " => " DbLabel " ,
" composer " => " DbComposer " ,
" encoded_by " => " DbEncodedBy " ,
" conductor " => " DbConductor " ,
" year " => " DbYear " ,
" info_url " => " DbInfoUrl " ,
" isrc_number " => " DbIsrcNumber " ,
" copyright " => " DbCopyright " ,
" length " => " DbLength " ,
" bit_rate " => " DbBitRate " ,
" sample_rate " => " DbSampleRate " ,
" mime " => " DbMime " ,
2012-09-12 17:10:25 +02:00
//"md5" => "DbMd5",
2012-08-23 16:21:39 +02:00
" ftype " => " DbFtype " ,
" language " => " DbLanguage " ,
" replay_gain " => " DbReplayGain " ,
2012-08-23 22:46:35 +02:00
" directory " => " DbDirectory " ,
2013-01-03 20:02:06 +01:00
" owner_id " => " DbOwnerId " ,
" cuein " => " DbCueIn " ,
" cueout " => " DbCueOut " ,
2015-09-14 23:00:54 +02:00
" description " => " DbDescription "
2011-06-08 10:15:35 +02:00
);
2013-04-20 02:10:51 +02:00
function __construct ( $file , $con ) {
$this -> _file = $file ;
$this -> _con = $con ;
}
2011-06-08 11:59:48 +02:00
public function getId ()
{
2011-06-08 10:15:35 +02:00
return $this -> _file -> getDbId ();
}
2010-12-07 20:19:27 +01:00
2011-06-08 11:59:48 +02:00
public function getFormat ()
{
return $this -> _file -> getDbFtype ();
}
2015-06-24 21:46:53 +02:00
/**
* @ return CcFiles
*/
2012-07-16 03:17:13 +02:00
public function getPropelOrm ()
{
2011-06-20 20:10:33 +02:00
return $this -> _file ;
}
2011-06-08 11:59:48 +02:00
public function setFormat ( $p_format )
{
$this -> _file -> setDbFtype ( $p_format );
}
2012-08-29 16:58:03 +02:00
2012-07-20 00:07:39 +02:00
/* This function is only called after liquidsoap
* has notified that a track has started playing .
*/
public function setLastPlayedTime ( $p_now )
{
$this -> _file -> setDbLPtime ( $p_now );
/* Normally we would only call save after all columns have been set
2012-08-29 16:58:03 +02:00
* like in setDbColMetadata () . But since we are only setting one
2012-07-20 00:07:39 +02:00
* column in this case it is OK .
*/
$this -> _file -> save ();
}
2011-06-08 11:59:48 +02:00
2013-04-20 02:10:51 +02:00
public static function createWithFile ( $f , $con ) {
2014-07-24 22:56:15 +02:00
$storedFile = new Application_Model_StoredFile ( $f , $con );
2012-09-12 00:22:46 +02:00
return $storedFile ;
}
2010-12-07 20:19:27 +01:00
/**
2011-06-08 10:15:35 +02:00
* Set multiple metadata values using defined metadata constants .
2010-12-07 20:19:27 +01:00
*
2011-06-08 10:15:35 +02:00
* @ param array $p_md
* example : $p_md [ 'MDATA_KEY_URL' ] = 'http://www.fake.com'
2010-12-07 20:19:27 +01:00
*/
2012-02-28 19:47:57 +01:00
public function setMetadata ( $p_md = null )
2010-12-07 20:19:27 +01:00
{
2011-06-08 10:15:35 +02:00
if ( is_null ( $p_md )) {
$this -> setDbColMetadata ();
2012-07-16 03:17:13 +02:00
} else {
2011-06-08 10:15:35 +02:00
$dbMd = array ();
2012-07-11 00:51:32 +02:00
2012-07-16 03:17:13 +02:00
if ( isset ( $p_md [ " MDATA_KEY_YEAR " ])) {
2012-09-19 23:39:30 +02:00
// We need to make sure to clean this value before
// inserting into database. If value is outside of range
// [-2^31, 2^31-1] then postgresl will throw error when
// trying to retrieve this value. We could make sure
// number is within these bounds, but simplest is to do
// substring to 4 digits (both values are garbage, but
// at least our new garbage value won't cause errors).
// If the value is 2012-01-01, then substring to first 4
// digits is an OK result. CC-3771
2012-07-11 00:51:32 +02:00
2012-06-04 17:43:41 +02:00
$year = $p_md [ " MDATA_KEY_YEAR " ];
2012-07-11 00:51:32 +02:00
2012-07-16 03:17:13 +02:00
if ( strlen ( $year ) > 4 ) {
2012-06-04 17:43:41 +02:00
$year = substr ( $year , 0 , 4 );
}
2012-07-16 03:17:13 +02:00
if ( ! is_numeric ( $year )) {
2012-06-04 17:43:41 +02:00
$year = 0 ;
}
$p_md [ " MDATA_KEY_YEAR " ] = $year ;
}
2012-07-11 00:51:32 +02:00
2012-08-27 20:07:05 +02:00
# Translate metadata attributes from media monitor (MDATA_KEY_*)
# to their counterparts in constants.php (usually the column names)
2013-01-10 17:49:02 +01:00
$track_length = $p_md [ 'MDATA_KEY_DURATION' ];
$track_length_in_sec = Application_Common_DateHelper :: calculateLengthInSeconds ( $track_length );
2011-06-08 10:15:35 +02:00
foreach ( $p_md as $mdConst => $mdValue ) {
2012-07-16 03:17:13 +02:00
if ( defined ( $mdConst )) {
2013-01-15 17:16:50 +01:00
if ( $mdConst == " MDATA_KEY_CUE_OUT " ) {
if ( $mdValue == '0.0' ) {
$mdValue = $track_length_in_sec ;
} else {
$this -> _file -> setDbSilanCheck ( true ) -> save ();
}
2013-01-10 17:49:02 +01:00
}
2012-05-15 21:17:19 +02:00
$dbMd [ constant ( $mdConst )] = $mdValue ;
2013-05-28 20:27:59 +02:00
2012-05-15 21:17:19 +02:00
}
2011-06-08 10:15:35 +02:00
}
$this -> setDbColMetadata ( $dbMd );
2010-12-07 20:19:27 +01:00
}
}
2011-06-08 10:15:35 +02:00
/**
* Set multiple metadata values using database columns as indexes .
*
* @ param array $p_md
* example : $p_md [ 'url' ] = 'http://www.fake.com'
*/
2012-02-28 19:47:57 +01:00
public function setDbColMetadata ( $p_md = null )
2010-12-07 20:19:27 +01:00
{
2011-06-08 10:15:35 +02:00
if ( is_null ( $p_md )) {
foreach ( $this -> _dbMD as $dbColumn => $propelColumn ) {
$method = " set $propelColumn " ;
$this -> _file -> $method ( null );
}
2012-07-16 03:17:13 +02:00
} else {
2012-08-24 18:38:33 +02:00
$owner = $this -> _file -> getFkOwner ();
2012-08-29 16:58:03 +02:00
// if owner_id is already set we don't want to set it again.
if ( ! $owner ) { // no owner detected, we try to assign one.
// if MDATA_OWNER_ID is not set then we default to the
2012-08-23 22:46:35 +02:00
// first admin user we find
2012-08-27 21:09:55 +02:00
if ( ! array_key_exists ( 'owner_id' , $p_md )) {
2012-08-24 18:38:33 +02:00
//$admins = Application_Model_User::getUsers(array('A'));
$admins = Application_Model_User :: getUsersOfType ( 'A' );
2012-08-23 22:46:35 +02:00
if ( count ( $admins ) > 0 ) { // found admin => pick first one
$owner = $admins [ 0 ];
}
}
// get the user by id and set it like that
else {
2012-08-24 16:20:23 +02:00
$user = CcSubjsQuery :: create ()
2012-08-27 21:09:55 +02:00
-> findPk ( $p_md [ 'owner_id' ]);
2012-08-23 22:46:35 +02:00
if ( $user ) {
$owner = $user ;
}
}
2012-08-29 16:58:03 +02:00
if ( $owner ) {
2012-08-24 18:38:33 +02:00
$this -> _file -> setDbOwnerId ( $owner -> getDbId () );
2012-08-29 16:58:03 +02:00
} else {
2012-08-24 18:38:33 +02:00
Logging :: info ( " Could not find suitable owner for file
2012-11-07 18:05:20 +01:00
'".$p_md[' filepath ']."' " );
2012-08-23 22:46:35 +02:00
}
}
2012-08-27 21:09:55 +02:00
# We don't want to process owner_id in bulk because we already
# processed it in the code above. This is done because owner_id
# needs special handling
if ( array_key_exists ( 'owner_id' , $p_md )) {
unset ( $p_md [ 'owner_id' ]);
}
2011-06-08 10:15:35 +02:00
foreach ( $p_md as $dbColumn => $mdValue ) {
2012-08-24 18:38:33 +02:00
// don't blank out name, defaults to original filename on first
// insertion to database.
2012-07-16 03:17:13 +02:00
if ( $dbColumn == " track_title " && ( is_null ( $mdValue ) || $mdValue == " " )) {
2011-06-15 09:19:41 +02:00
continue ;
}
2014-11-18 16:32:03 +01:00
// Bpm gets POSTed as a string type. With Propel 1.6 this value
// was casted to an integer type before saving it to the db. But
// Propel 1.7 does not do this
if ( $dbColumn == " bpm " ) {
$mdValue = ( int ) $mdValue ;
}
2012-10-03 18:01:24 +02:00
# TODO : refactor string evals
2011-06-21 10:24:02 +02:00
if ( isset ( $this -> _dbMD [ $dbColumn ])) {
$propelColumn = $this -> _dbMD [ $dbColumn ];
2012-08-23 22:46:35 +02:00
$method = " set $propelColumn " ;
2013-05-28 20:27:59 +02:00
2012-10-16 21:56:03 +02:00
/* We need to set track_number to null if it is an empty string
* because propel defaults empty strings to zeros */
if ( $dbColumn == " track_number " && empty ( $mdValue )) $mdValue = null ;
2011-06-21 10:24:02 +02:00
$this -> _file -> $method ( $mdValue );
}
2011-06-08 10:15:35 +02:00
}
2010-12-07 20:19:27 +01:00
}
2012-07-20 00:11:31 +02:00
2012-07-20 00:07:39 +02:00
$this -> _file -> setDbMtime ( new DateTime ( " now " , new DateTimeZone ( " UTC " )));
2013-04-20 02:10:51 +02:00
$this -> _file -> save ( $this -> _con );
2010-12-07 20:19:27 +01:00
}
/**
* Set metadata element value
*
* @ param string $category
2012-07-11 00:51:32 +02:00
* Metadata element by metadata constant
2010-12-07 20:19:27 +01:00
* @ param string $value
2012-07-11 00:51:32 +02:00
* value to store , if NULL then delete record
2010-12-07 20:19:27 +01:00
*/
public function setMetadataValue ( $p_category , $p_value )
{
2011-07-15 23:35:16 +02:00
// constant() was used because it gets quoted constant name value from
// api_client.py. This is the wrapper funtion
2011-06-08 10:15:35 +02:00
$this -> setDbColMetadataValue ( constant ( $p_category ), $p_value );
2010-12-07 20:19:27 +01:00
}
/**
2011-06-08 10:15:35 +02:00
* Set metadata element value
2010-12-07 20:19:27 +01:00
*
2011-06-08 10:15:35 +02:00
* @ param string $category
2012-07-11 00:51:32 +02:00
* Metadata element by db column
2011-06-08 10:15:35 +02:00
* @ param string $value
2012-07-11 00:51:32 +02:00
* value to store , if NULL then delete record
2010-12-07 20:19:27 +01:00
*/
2011-06-08 10:15:35 +02:00
public function setDbColMetadataValue ( $p_category , $p_value )
2010-12-07 20:19:27 +01:00
{
2011-06-15 09:19:41 +02:00
//don't blank out name, defaults to original filename on first insertion to database.
2012-07-16 03:17:13 +02:00
if ( $p_category == " track_title " && ( is_null ( $p_value ) || $p_value == " " )) {
2011-06-15 09:19:41 +02:00
return ;
}
2011-07-15 23:35:16 +02:00
if ( isset ( $this -> _dbMD [ $p_category ])) {
2012-09-11 22:25:45 +02:00
// TODO : fix this crust -- RG
2011-06-21 10:24:02 +02:00
$propelColumn = $this -> _dbMD [ $p_category ];
$method = " set $propelColumn " ;
$this -> _file -> $method ( $p_value );
$this -> _file -> save ();
}
2010-12-07 20:19:27 +01:00
}
2011-06-08 10:15:35 +02:00
/**
* Get metadata as array , indexed by the column names in the database .
*
* @ return array
*/
public function getDbColMetadata ()
2010-12-07 20:19:27 +01:00
{
2011-06-08 10:15:35 +02:00
$md = array ();
foreach ( $this -> _dbMD as $dbColumn => $propelColumn ) {
$method = " get $propelColumn " ;
$md [ $dbColumn ] = $this -> _file -> $method ();
2010-12-07 23:29:28 +01:00
}
2011-06-08 10:15:35 +02:00
return $md ;
2010-12-07 20:19:27 +01:00
}
2011-06-15 14:20:14 +02:00
/**
* Get metadata as array , indexed by the constant names .
*
* @ return array
*/
public function getMetadata ()
{
$c = get_defined_constants ( true );
$md = array ();
2012-07-11 00:51:32 +02:00
/* Create a copy of dbMD here and create a " filepath " key inside of
2012-05-04 18:02:42 +02:00
* it . The reason we do this here , instead of creating this key inside
2012-07-11 00:51:32 +02:00
* dbMD is because " filepath " isn 't really metadata, and we don' t want
2012-05-04 18:02:42 +02:00
* filepath updated everytime the metadata changes . Also it needs extra
2012-07-11 00:51:32 +02:00
* processing before we can write it to the database ( needs to be split
2012-05-04 18:02:42 +02:00
* into base and relative path )
* */
$dbmd_copy = $this -> _dbMD ;
$dbmd_copy [ " filepath " ] = " DbFilepath " ;
2011-06-15 14:20:14 +02:00
foreach ( $c [ 'user' ] as $constant => $value ) {
if ( preg_match ( '/^MDATA_KEY/' , $constant )) {
2012-05-04 18:02:42 +02:00
if ( isset ( $dbmd_copy [ $value ])) {
2012-08-23 16:21:39 +02:00
$propelColumn = $dbmd_copy [ $value ];
$method = " get $propelColumn " ;
2012-05-04 18:47:29 +02:00
$md [ $constant ] = $this -> _file -> $method ();
2011-06-15 14:20:14 +02:00
}
}
}
return $md ;
}
2010-12-07 20:19:27 +01:00
/**
* Returns an array of playlist objects that this file is a part of .
* @ return array
*/
2012-07-16 03:17:13 +02:00
public function getPlaylists ()
{
2012-04-01 21:51:03 +02:00
$con = Propel :: getConnection ();
2012-09-04 23:21:59 +02:00
2012-09-11 22:20:59 +02:00
$sql = <<< SQL
SELECT playlist_id
FROM cc_playlist
WHERE file_id = : file_id
SQL ;
2012-09-04 23:21:59 +02:00
$stmt = $con -> prepare ( $sql );
$stmt -> bindParam ( ':file_id' , $this -> id , PDO :: PARAM_INT );
2013-05-28 20:27:59 +02:00
2012-09-04 23:21:59 +02:00
if ( $stmt -> execute ()) {
$ids = $stmt -> fetchAll ();
} else {
$msg = implode ( ',' , $stmt -> errorInfo ());
throw new Exception ( " Error: $msg " );
}
2010-12-07 20:19:27 +01:00
if ( is_array ( $ids ) && count ( $ids ) > 0 ) {
2012-09-11 22:20:59 +02:00
return array_map ( function ( $id ) {
2013-04-20 02:24:05 +02:00
return Application_Model_Playlist :: RecallById ( $id );
2012-09-11 22:20:59 +02:00
}, $ids );
} else {
return array ();
2010-12-07 20:19:27 +01:00
}
}
2014-03-24 22:14:04 +01:00
/**
* Check if the file ( on disk ) corresponding to this class exists or not .
* @ return boolean true if the file exists , false otherwise .
*/
public function existsOnDisk ()
{
$exists = false ;
try {
2015-03-30 17:31:07 +02:00
$filePaths = $this -> getFilePaths ();
$filePath = $filePaths [ 0 ];
$exists = ( file_exists ( $filePath ) && ! is_dir ( $filePath ));
2014-03-24 22:14:04 +01:00
} catch ( Exception $e ) {
return false ;
}
return $exists ;
}
2010-12-07 20:19:27 +01:00
/**
2014-07-15 23:20:04 +02:00
* Deletes the physical file from the local file system or from the cloud
2011-06-08 11:59:48 +02:00
*
2010-12-07 20:19:27 +01:00
*/
2015-05-13 23:58:11 +02:00
public function delete ( $quiet = false )
2010-12-07 20:19:27 +01:00
{
2011-06-08 11:59:48 +02:00
// Check if the file is scheduled to be played in the future
2015-01-13 21:49:57 +01:00
if ( Application_Model_Schedule :: IsFileScheduledInTheFuture ( $this -> _file -> getCcFileId ())) {
2012-02-05 18:19:22 +01:00
throw new DeleteScheduledFileException ();
2011-06-08 11:59:48 +02:00
}
2015-01-12 22:26:27 +01:00
2012-10-31 21:51:29 +01:00
$userInfo = Zend_Auth :: getInstance () -> getStorage () -> read ();
$user = new Application_Model_User ( $userInfo -> id );
2014-06-20 23:43:20 +02:00
$isAdminOrPM = $user -> isUserType ( array ( UTYPE_SUPERADMIN , UTYPE_ADMIN , UTYPE_PROGRAM_MANAGER ));
2012-10-31 21:51:29 +01:00
if ( ! $isAdminOrPM && $this -> getFileOwnerId () != $user -> getId ()) {
throw new FileNoPermissionException ();
}
2014-07-15 23:20:04 +02:00
$file_id = $this -> _file -> getDbId ();
2015-01-12 21:29:41 +01:00
Logging :: info ( $file_id );
2014-07-15 23:20:04 +02:00
Logging :: info ( " User " . $user -> getLogin () . " is deleting file: " . $this -> _file -> getDbTrackTitle () . " - file id: " . $file_id );
2015-01-12 22:26:27 +01:00
2014-10-21 22:05:50 +02:00
$filesize = $this -> _file -> getFileSize ();
2015-02-25 21:09:02 +01:00
if ( $filesize < 0 ) {
2014-10-27 17:39:02 +01:00
throw new Exception ( " Cannot delete file with filesize " . $filesize );
}
2014-10-21 22:05:50 +02:00
//Delete the physical file from either the local stor directory
//or from the cloud
2015-03-03 19:44:42 +01:00
if ( $this -> _file -> getDbImportStatus () == CcFiles :: IMPORT_STATUS_SUCCESS ) {
2015-04-01 22:16:46 +02:00
try {
$this -> _file -> deletePhysicalFile ();
}
catch ( Exception $e )
{
2015-05-13 23:58:11 +02:00
if ( $quiet ) {
Logging :: info ( $e );
} else {
//Just log the exception and continue.
Logging :: error ( $e );
}
2015-04-01 22:16:46 +02:00
}
2015-03-03 19:44:42 +01:00
}
2014-10-21 22:05:50 +02:00
//Update the user's disk usage
Application_Model_Preference :: updateDiskUsage ( - 1 * $filesize );
//Explicitly update any playlist's and block's length that contain
//the file getting deleted
self :: updateBlockAndPlaylistLength ( $this -> _file -> getDbId ());
//delete the file record from cc_files (and cloud_file, if applicable)
$this -> _file -> delete ();
2014-07-15 23:20:04 +02:00
}
2014-07-15 13:26:39 +02:00
2014-07-15 23:20:04 +02:00
/*
* This function is meant to be called when a file is getting
* deleted from the library . It re - calculates the length of
* all blocks and playlists that contained the deleted file .
*/
2014-07-24 22:56:15 +02:00
private static function updateBlockAndPlaylistLength ( $fileId )
2014-07-15 23:20:04 +02:00
{
$plRows = CcPlaylistcontentsQuery :: create () -> filterByDbFileId ( $fileId ) -> find ();
2012-11-06 16:58:25 +01:00
foreach ( $plRows as $row ) {
$pl = CcPlaylistQuery :: create () -> filterByDbId ( $row -> getDbPlaylistId ( $fileId )) -> findOne ();
$pl -> setDbLength ( $pl -> computeDbLength ( Propel :: getConnection ( CcPlaylistPeer :: DATABASE_NAME )));
$pl -> save ();
}
2013-05-28 20:27:59 +02:00
2012-11-06 16:58:25 +01:00
$blRows = CcBlockcontentsQuery :: create () -> filterByDbFileId ( $fileId ) -> find ();
foreach ( $blRows as $row ) {
$bl = CcBlockQuery :: create () -> filterByDbId ( $row -> getDbBlockId ()) -> findOne ();
$bl -> setDbLength ( $bl -> computeDbLength ( Propel :: getConnection ( CcBlockPeer :: DATABASE_NAME )));
$bl -> save ();
}
2012-04-12 22:17:19 +02:00
}
2012-07-11 00:51:32 +02:00
2012-04-12 22:17:19 +02:00
/**
* This function is for when media monitor detects deletion of file
* and trying to update airtime side
*
* @ param boolean $p_deleteFile
*
*/
public function deleteByMediaMonitor ( $deleteFromPlaylist = false )
{
2012-07-16 03:17:13 +02:00
if ( $deleteFromPlaylist ) {
2012-04-12 22:17:19 +02:00
Application_Model_Playlist :: DeleteFileFromAllPlaylists ( $this -> getId ());
}
2012-08-27 22:49:45 +02:00
// set file_exists flag to false
2012-02-05 18:19:22 +01:00
$this -> _file -> setDbFileExists ( false );
$this -> _file -> save ();
2010-12-07 20:19:27 +01:00
}
/**
2014-07-24 22:56:15 +02:00
* Get the absolute filepath
2010-12-07 20:19:27 +01:00
*
2015-03-30 17:31:07 +02:00
* @ return array of strings
2010-12-07 20:19:27 +01:00
*/
2015-03-30 17:31:07 +02:00
public function getFilePaths ()
2012-01-17 11:18:17 +01:00
{
2014-03-24 22:14:04 +01:00
assert ( $this -> _file );
2015-03-30 17:31:07 +02:00
return $this -> _file -> getURLsForTrackPreviewOrDownload ();
2011-06-21 10:24:02 +02:00
}
2012-07-11 00:51:32 +02:00
2011-06-21 10:24:02 +02:00
/**
* Set real filename of raw media data
*
* @ return string
*/
public function setFilePath ( $p_filepath )
{
2011-09-22 18:24:17 +02:00
$path_info = Application_Model_MusicDir :: splitFilePath ( $p_filepath );
2012-01-17 11:18:17 +01:00
2011-06-21 10:24:02 +02:00
if ( is_null ( $path_info )) {
return - 1 ;
}
2011-09-22 18:24:17 +02:00
$musicDir = Application_Model_MusicDir :: getDirByPath ( $path_info [ 0 ]);
2011-06-21 10:24:02 +02:00
$this -> _file -> setDbDirectory ( $musicDir -> getId ());
$this -> _file -> setDbFilepath ( $path_info [ 1 ]);
2013-04-20 02:10:51 +02:00
$this -> _file -> save ( $this -> _con );
2010-12-07 20:19:27 +01:00
}
/**
2013-05-22 21:33:49 +02:00
* Get the URL to access this file
2010-12-07 20:19:27 +01:00
*/
public function getFileUrl ()
2011-09-22 21:31:21 +02:00
{
2013-05-22 21:33:49 +02:00
$CC_CONFIG = Config :: getConfig ();
2013-05-28 20:27:59 +02:00
2013-05-22 21:33:49 +02:00
$protocol = empty ( $_SERVER [ 'HTTPS' ]) ? " http " : " https " ;
2013-05-28 20:27:59 +02:00
2013-05-22 21:35:59 +02:00
$serverName = $_SERVER [ 'SERVER_NAME' ];
2013-05-22 21:33:49 +02:00
$serverPort = $_SERVER [ 'SERVER_PORT' ];
$subDir = $CC_CONFIG [ 'baseDir' ];
2013-05-28 20:27:59 +02:00
2013-05-22 21:35:59 +02:00
if ( $subDir [ 0 ] === " / " ) {
$subDir = substr ( $subDir , 1 , strlen ( $subDir ) - 1 );
2013-05-22 21:33:49 +02:00
}
2013-05-28 20:27:59 +02:00
2013-05-22 21:33:49 +02:00
$baseUrl = " { $protocol } :// { $serverName } : { $serverPort } / { $subDir } " ;
2013-05-28 20:27:59 +02:00
2013-05-22 21:33:49 +02:00
return $this -> getRelativeFileUrl ( $baseUrl );
2011-06-09 11:50:03 +02:00
}
2011-06-22 22:50:58 +02:00
/**
* Sometimes we want a relative URL and not a full URL . See bug
* http :// dev . sourcefabric . org / browse / CC - 2403
*/
2011-06-24 22:04:57 +02:00
public function getRelativeFileUrl ( $baseUrl )
2011-06-22 22:50:58 +02:00
{
2015-07-07 21:09:06 +02:00
return $baseUrl . " api/get-media/file/ " . $this -> getId ();
2011-06-22 22:50:58 +02:00
}
2014-07-10 23:56:41 +02:00
public function getResourceId ()
{
2014-07-29 21:07:51 +02:00
return $this -> _file -> getResourceId ();
2014-07-10 23:56:41 +02:00
}
2011-06-22 22:50:58 +02:00
2014-07-10 23:56:41 +02:00
public function getFileSize ()
{
2014-07-29 21:07:51 +02:00
$filesize = $this -> _file -> getFileSize ();
2015-02-24 17:00:41 +01:00
// It's OK for the file size to be zero. Pypo will make a request to Airtime and update
// the file size and md5 hash if they are not set.
if ( $filesize < 0 ) {
2014-07-29 21:07:51 +02:00
throw new Exception ( " Could not determine filesize for file id: " . $this -> _file -> getDbId () . " . Filesize: " . $filesize );
}
return $filesize ;
2014-07-10 23:56:41 +02:00
}
2013-04-20 02:10:51 +02:00
public static function Insert ( $md , $con )
2011-06-09 11:50:03 +02:00
{
2012-08-08 21:55:58 +02:00
// save some work by checking if filepath is given right away
2012-08-29 16:58:03 +02:00
if ( ! isset ( $md [ 'MDATA_KEY_FILEPATH' ]) ) {
return null ;
}
2012-08-08 21:55:58 +02:00
2011-06-09 11:50:03 +02:00
$file = new CcFiles ();
2012-08-24 17:09:38 +02:00
$now = new DateTime ( " now " , new DateTimeZone ( " UTC " ));
$file -> setDbUtime ( $now );
$file -> setDbMtime ( $now );
2011-06-09 11:50:03 +02:00
2013-04-20 02:10:51 +02:00
$storedFile = new Application_Model_StoredFile ( $file , $con );
2011-06-09 12:57:30 +02:00
2012-08-08 21:55:58 +02:00
// removed "//" in the path. Always use '/' for path separator
2012-08-23 19:49:49 +02:00
// TODO : it might be better to just call OsPath::normpath on the file
// path. Also note that mediamonitor normalizes the paths anyway
// before passing them to php so it's not necessary to do this at all
2012-08-24 17:09:38 +02:00
2012-08-08 21:55:58 +02:00
$filepath = str_replace ( " // " , " / " , $md [ 'MDATA_KEY_FILEPATH' ]);
$res = $storedFile -> setFilePath ( $filepath );
if ( $res === - 1 ) {
2011-06-21 10:24:02 +02:00
return null ;
}
2012-08-08 21:55:58 +02:00
$storedFile -> setMetadata ( $md );
2012-08-29 16:58:03 +02:00
2012-08-08 21:55:58 +02:00
return $storedFile ;
2010-12-07 20:19:27 +01:00
}
2013-04-20 02:40:31 +02:00
/* TODO : Callers of this function should use a Propel transaction . Start
* by creating $con outside the function with beingTransaction () */
2015-06-03 22:57:17 +02:00
/**
* @ param int $p_id
* @ param \Doctrine\DBAL\Driver\PDOConnection $con
*
* @ return Application_Model_StoredFile
* @ throws Exception
*/
2013-04-20 02:24:05 +02:00
public static function RecallById ( $p_id = null , $con = null ) {
2013-04-20 02:10:51 +02:00
//TODO
if ( is_null ( $con )) {
$con = Propel :: getConnection ( CcFilesPeer :: DATABASE_NAME );
}
if ( isset ( $p_id )) {
2014-08-12 17:39:29 +02:00
$p_id = intval ( $p_id );
2014-08-12 17:33:10 +02:00
$storedFile = CcFilesQuery :: create () -> findPK ( $p_id , $con );
2014-07-24 22:56:15 +02:00
if ( is_null ( $storedFile )) {
throw new Exception ( " Could not recall file with id: " . $p_id );
}
2014-08-12 17:33:10 +02:00
2014-07-24 22:56:15 +02:00
//Attempt to get the cloud file object and return it. If no cloud
//file object is found then we are dealing with a regular stored
//object so return that
2014-08-01 05:11:49 +02:00
$cloudFile = CloudFileQuery :: create () -> findOneByCcFileId ( $p_id );
2014-07-24 22:56:15 +02:00
if ( is_null ( $cloudFile )) {
return self :: createWithFile ( $storedFile , $con );
} else {
return self :: createWithFile ( $cloudFile , $con );
}
2012-07-16 03:17:13 +02:00
} else {
2013-04-20 02:24:05 +02:00
throw new Exception ( " No arguments passed to RecallById " );
2011-06-09 12:57:30 +02:00
}
2011-06-08 10:15:35 +02:00
}
2011-06-28 15:04:03 +02:00
2012-07-16 03:17:13 +02:00
public function getName ()
{
2014-07-24 22:56:15 +02:00
return $this -> _file -> getFilename ();
2011-06-27 17:23:48 +02:00
}
2011-06-08 10:15:35 +02:00
/**
2011-09-22 18:24:17 +02:00
* Fetch the Application_Model_StoredFile by looking up its filepath .
2011-06-08 10:15:35 +02:00
*
2012-09-18 18:09:28 +02:00
* @ param string $p_filepath path of file stored in Airtime .
2011-09-22 18:24:17 +02:00
* @ return Application_Model_StoredFile | NULL
2011-06-08 10:15:35 +02:00
*/
2013-04-20 02:10:51 +02:00
public static function RecallByFilepath ( $p_filepath , $con )
2011-06-08 10:15:35 +02:00
{
2012-09-12 00:22:46 +02:00
$path_info = Application_Model_MusicDir :: splitFilePath ( $p_filepath );
if ( is_null ( $path_info )) {
return null ;
}
$music_dir = Application_Model_MusicDir :: getDirByPath ( $path_info [ 0 ]);
$file = CcFilesQuery :: create ()
-> filterByDbDirectory ( $music_dir -> getId ())
-> filterByDbFilepath ( $path_info [ 1 ])
2013-04-20 02:10:51 +02:00
-> findOne ( $con );
return is_null ( $file ) ? null : self :: createWithFile ( $file , $con );
2011-06-08 10:15:35 +02:00
}
2011-12-01 11:16:29 +01:00
2013-04-20 02:10:51 +02:00
public static function RecallByPartialFilepath ( $partial_path , $con )
2012-07-16 03:17:13 +02:00
{
2011-09-27 20:49:03 +02:00
$path_info = Application_Model_MusicDir :: splitFilePath ( $partial_path );
if ( is_null ( $path_info )) {
return null ;
}
$music_dir = Application_Model_MusicDir :: getDirByPath ( $path_info [ 0 ]);
$files = CcFilesQuery :: create ()
-> filterByDbDirectory ( $music_dir -> getId ())
-> filterByDbFilepath ( " $path_info[1] % " )
2013-04-20 02:10:51 +02:00
-> find ( $con );
2011-09-27 20:49:03 +02:00
$res = array ();
2012-07-16 03:17:13 +02:00
foreach ( $files as $file ) {
2013-04-20 02:10:51 +02:00
$storedFile = new Application_Model_StoredFile ( $file , $con );
2012-08-23 23:52:28 +02:00
$res [] = $storedFile ;
2011-09-27 20:49:03 +02:00
}
2012-07-16 03:17:13 +02:00
2011-09-27 20:49:03 +02:00
return $res ;
}
2011-12-01 11:16:29 +01:00
2012-10-19 17:09:34 +02:00
2012-09-14 18:09:40 +02:00
public static function getLibraryColumns ()
{
return array ( " id " , " track_title " , " artist_name " , " album_title " ,
" genre " , " length " , " year " , " utime " , " mtime " , " ftype " ,
" track_number " , " mood " , " bpm " , " composer " , " info_url " ,
" bit_rate " , " sample_rate " , " isrc_number " , " encoded_by " , " label " ,
" copyright " , " mime " , " language " , " filepath " , " owner_id " ,
2013-02-19 19:38:35 +01:00
" conductor " , " replay_gain " , " lptime " , " is_playlist " , " is_scheduled " ,
2015-09-14 23:00:54 +02:00
" cuein " , " cueout " , " description " );
2012-09-14 18:09:40 +02:00
}
2012-07-16 03:17:13 +02:00
public static function searchLibraryFiles ( $datatables )
{
2012-10-19 20:42:01 +02:00
$baseUrl = Application_Common_OsPath :: getBaseDir ();
2013-05-28 20:27:59 +02:00
2012-07-11 00:51:32 +02:00
$con = Propel :: getConnection ( CcFilesPeer :: DATABASE_NAME );
2010-12-07 23:29:28 +01:00
2012-09-14 18:09:40 +02:00
$displayColumns = self :: getLibraryColumns ();
2012-08-31 19:34:21 +02:00
2012-08-23 16:21:39 +02:00
$plSelect = array ();
$blSelect = array ();
$fileSelect = array ();
2012-07-19 00:27:39 +02:00
$streamSelect = array ();
2012-02-22 18:38:33 +01:00
foreach ( $displayColumns as $key ) {
if ( $key === " id " ) {
2012-08-23 16:21:39 +02:00
$plSelect [] = " PL.id AS " . $key ;
$blSelect [] = " BL.id AS " . $key ;
2012-08-31 19:34:21 +02:00
$fileSelect [] = " FILES.id AS $key " ;
2012-08-04 00:06:47 +02:00
$streamSelect [] = " ws.id AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " track_title " ) {
2012-08-23 16:21:39 +02:00
$plSelect [] = " name AS " . $key ;
$blSelect [] = " name AS " . $key ;
$fileSelect [] = $key ;
2012-07-19 00:27:39 +02:00
$streamSelect [] = " name AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " ftype " ) {
2012-08-23 16:21:39 +02:00
$plSelect [] = " 'playlist'::varchar AS " . $key ;
$blSelect [] = " 'block'::varchar AS " . $key ;
$fileSelect [] = $key ;
2012-07-19 00:27:39 +02:00
$streamSelect [] = " 'stream'::varchar AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " artist_name " ) {
2012-08-23 16:21:39 +02:00
$plSelect [] = " login AS " . $key ;
$blSelect [] = " login AS " . $key ;
$fileSelect [] = $key ;
2012-08-04 00:06:47 +02:00
$streamSelect [] = " login AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " owner_id " ) {
2012-08-31 19:34:21 +02:00
$plSelect [] = " login AS " . $key ;
$blSelect [] = " login AS " . $key ;
$fileSelect [] = " sub.login AS $key " ;
$streamSelect [] = " login AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " replay_gain " ) {
2012-09-10 20:37:38 +02:00
$plSelect [] = " NULL::NUMERIC AS " . $key ;
$blSelect [] = " NULL::NUMERIC AS " . $key ;
2012-09-11 00:01:36 +02:00
$fileSelect [] = $key ;
2012-09-10 20:37:38 +02:00
$streamSelect [] = " NULL::NUMERIC AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " lptime " ) {
2012-09-18 18:26:07 +02:00
$plSelect [] = " NULL::TIMESTAMP AS " . $key ;
$blSelect [] = " NULL::TIMESTAMP AS " . $key ;
$fileSelect [] = $key ;
2012-09-11 00:01:36 +02:00
$streamSelect [] = $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " is_scheduled " || $key === " is_playlist " ) {
2013-02-01 23:47:07 +01:00
$plSelect [] = " NULL::boolean AS " . $key ;
$blSelect [] = " NULL::boolean AS " . $key ;
$fileSelect [] = $key ;
$streamSelect [] = " NULL::boolean AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " cuein " || $key === " cueout " ) {
2013-02-19 19:38:35 +01:00
$plSelect [] = " NULL::INTERVAL AS " . $key ;
$blSelect [] = " NULL::INTERVAL AS " . $key ;
$fileSelect [] = $key ;
$streamSelect [] = " NULL::INTERVAL AS " . $key ;
2012-02-24 00:55:20 +01:00
}
2013-10-16 22:01:30 +02:00
//file length is displayed based on cueout - cuein.
else if ( $key === " length " ) {
$plSelect [] = $key ;
$blSelect [] = $key ;
$fileSelect [] = " (cueout - cuein)::INTERVAL AS length " ;
$streamSelect [] = $key ;
2013-10-16 21:56:32 +02:00
}
2012-02-24 16:05:01 +01:00
//same columns in each table.
2013-10-16 21:56:32 +02:00
else if ( in_array ( $key , array ( " utime " , " mtime " ))) {
2012-09-18 18:26:07 +02:00
$plSelect [] = $key ;
$blSelect [] = $key ;
$fileSelect [] = $key ;
2012-07-19 00:27:39 +02:00
$streamSelect [] = $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " year " ) {
2012-09-18 18:26:07 +02:00
$plSelect [] = " EXTRACT(YEAR FROM utime)::varchar AS " . $key ;
$blSelect [] = " EXTRACT(YEAR FROM utime)::varchar AS " . $key ;
$fileSelect [] = " year AS " . $key ;
2012-07-19 00:27:39 +02:00
$streamSelect [] = " EXTRACT(YEAR FROM utime)::varchar AS " . $key ;
2012-02-24 00:55:20 +01:00
}
//need to cast certain data as ints for the union to search on.
2012-08-15 22:40:04 +02:00
else if ( in_array ( $key , array ( " track_number " , " bit_rate " , " sample_rate " , " bpm " ))) {
2012-08-23 16:21:39 +02:00
$plSelect [] = " NULL::int AS " . $key ;
$blSelect [] = " NULL::int AS " . $key ;
$fileSelect [] = $key ;
2012-07-19 00:27:39 +02:00
$streamSelect [] = " NULL::int AS " . $key ;
2013-10-16 21:56:32 +02:00
}
elseif ( $key === " filepath " ) {
2012-08-23 16:21:39 +02:00
$plSelect [] = " NULL::VARCHAR AS " . $key ;
$blSelect [] = " NULL::VARCHAR AS " . $key ;
$fileSelect [] = $key ;
2012-08-09 20:39:31 +02:00
$streamSelect [] = " url AS " . $key ;
2013-10-16 21:56:32 +02:00
}
else if ( $key == " mime " ) {
2013-01-02 22:09:32 +01:00
$plSelect [] = " NULL::VARCHAR AS " . $key ;
$blSelect [] = " NULL::VARCHAR AS " . $key ;
$fileSelect [] = $key ;
$streamSelect [] = $key ;
2015-09-14 23:00:54 +02:00
}
2013-10-16 21:56:32 +02:00
else {
2012-08-23 16:21:39 +02:00
$plSelect [] = " NULL::text AS " . $key ;
$blSelect [] = " NULL::text AS " . $key ;
$fileSelect [] = $key ;
2012-07-19 00:27:39 +02:00
$streamSelect [] = " NULL::text AS " . $key ;
2010-12-30 00:43:17 +01:00
}
}
2012-08-23 16:21:39 +02:00
$plSelect = " SELECT " . join ( " , " , $plSelect );
$blSelect = " SELECT " . join ( " , " , $blSelect );
$fileSelect = " SELECT " . join ( " , " , $fileSelect );
2012-07-19 00:27:39 +02:00
$streamSelect = " SELECT " . join ( " , " , $streamSelect );
2012-02-22 18:38:33 +01:00
2012-02-24 00:55:20 +01:00
$type = intval ( $datatables [ " type " ]);
$plTable = " ( { $plSelect } FROM cc_playlist AS PL LEFT JOIN cc_subjs AS sub ON (sub.id = PL.creator_id)) " ;
2012-07-25 23:08:22 +02:00
$blTable = " ( { $blSelect } FROM cc_block AS BL LEFT JOIN cc_subjs AS sub ON (sub.id = BL.creator_id)) " ;
2012-11-20 21:18:18 +01:00
$fileTable = " ( { $fileSelect } FROM cc_files AS FILES LEFT JOIN cc_subjs AS sub ON (sub.id = FILES.owner_id) WHERE file_exists = 'TRUE' AND hidden='FALSE') " ;
2012-08-31 19:34:21 +02:00
//$fileTable = "({$fileSelect} FROM cc_files AS FILES WHERE file_exists = 'TRUE')";
2012-08-04 00:06:47 +02:00
$streamTable = " ( { $streamSelect } FROM cc_webstream AS ws LEFT JOIN cc_subjs AS sub ON (sub.id = ws.creator_id)) " ;
2012-07-19 00:27:39 +02:00
$unionTable = " ( { $plTable } UNION { $blTable } UNION { $fileTable } UNION { $streamTable } ) AS RESULTS " ;
2012-01-17 11:18:17 +01:00
2012-02-24 00:55:20 +01:00
//choose which table we need to select data from.
2012-09-18 18:48:45 +02:00
// TODO : use constants instead of numbers -- RG
2012-02-24 00:55:20 +01:00
switch ( $type ) {
case 0 :
$fromTable = $unionTable ;
break ;
case 1 :
$fromTable = $fileTable . " AS File " ; //need an alias for the table if it's standalone.
break ;
case 2 :
$fromTable = $plTable . " AS Playlist " ; //need an alias for the table if it's standalone.
break ;
2012-07-25 23:08:22 +02:00
case 3 :
$fromTable = $blTable . " AS Block " ; //need an alias for the table if it's standalone.
break ;
2012-08-03 22:33:58 +02:00
case 4 :
$fromTable = $streamTable . " AS StreamTable " ; //need an alias for the table if it's standalone.
break ;
2012-02-24 00:55:20 +01:00
default :
$fromTable = $unionTable ;
}
2012-04-01 21:51:03 +02:00
2013-02-05 22:52:25 +01:00
// update is_scheduled to false for tracks that
// have already played out
self :: updatePastFilesIsScheduled ();
2012-03-12 15:32:24 +01:00
$results = Application_Model_Datatables :: findEntries ( $con , $displayColumns , $fromTable , $datatables );
2013-01-30 22:53:59 +01:00
2013-12-04 21:16:07 +01:00
$displayTimezone = new DateTimeZone ( Application_Model_Preference :: GetUserTimezone ());
$utcTimezone = new DateTimeZone ( " UTC " );
2012-02-20 11:41:44 +01:00
foreach ( $results [ 'aaData' ] as & $row ) {
2012-02-01 18:47:08 +01:00
$row [ 'id' ] = intval ( $row [ 'id' ]);
2013-07-18 07:31:20 +02:00
//taken from Datatables.php, needs to be cleaned up there.
2013-07-18 07:37:39 +02:00
if ( isset ( $r [ 'ftype' ])) {
if ( $r [ 'ftype' ] == 'playlist' ) {
$pl = new Application_Model_Playlist ( $r [ 'id' ]);
$r [ 'length' ] = $pl -> getLength ();
} elseif ( $r [ 'ftype' ] == " block " ) {
$bl = new Application_Model_Block ( $r [ 'id' ]);
$r [ 'bl_type' ] = $bl -> isStatic () ? 'static' : 'dynamic' ;
$r [ 'length' ] = $bl -> getLength ();
}
2013-07-18 07:31:20 +02:00
}
2013-06-24 17:09:03 +02:00
if ( $row [ 'ftype' ] === " audioclip " ) {
2013-02-19 19:38:35 +01:00
2013-06-24 17:15:09 +02:00
$cuein_formatter = new LengthFormatter ( $row [ " cuein " ]);
$row [ " cuein " ] = $cuein_formatter -> format ();
$cueout_formatter = new LengthFormatter ( $row [ " cueout " ]);
2013-06-24 17:09:03 +02:00
$row [ " cueout " ] = $cueout_formatter -> format ();
2013-02-19 19:38:35 +01:00
2013-06-24 17:09:03 +02:00
$cuein = Application_Common_DateHelper :: playlistTimeToSeconds ( $row [ " cuein " ]);
$cueout = Application_Common_DateHelper :: playlistTimeToSeconds ( $row [ " cueout " ]);
$row_length = Application_Common_DateHelper :: secondsToPlaylistTime ( $cueout - $cuein );
2012-02-01 23:33:20 +01:00
2012-02-24 18:22:07 +01:00
$formatter = new SamplerateFormatter ( $row [ 'sample_rate' ]);
$row [ 'sample_rate' ] = $formatter -> format ();
$formatter = new BitrateFormatter ( $row [ 'bit_rate' ]);
$row [ 'bit_rate' ] = $formatter -> format ();
2013-01-30 21:38:25 +01:00
// for audio preview
$row [ 'audioFile' ] = $row [ 'id' ] . " . " . pathinfo ( $row [ 'filepath' ], PATHINFO_EXTENSION );
2013-06-24 17:09:03 +02:00
}
else {
2013-01-30 21:38:25 +01:00
$row [ 'audioFile' ] = $row [ 'id' ];
2013-06-24 17:09:03 +02:00
$row_length = $row [ 'length' ];
2012-02-24 18:22:07 +01:00
}
2012-08-29 16:58:03 +02:00
2013-06-24 17:15:09 +02:00
$len_formatter = new LengthFormatter ( $row_length );
2013-06-24 17:09:03 +02:00
$row [ 'length' ] = $len_formatter -> format ();
2013-12-04 21:16:07 +01:00
2012-07-20 01:11:42 +02:00
//convert mtime and utime to localtime
2013-12-04 21:16:07 +01:00
$row [ 'mtime' ] = new DateTime ( $row [ 'mtime' ], $utcTimezone );
$row [ 'mtime' ] -> setTimeZone ( $displayTimezone );
2015-06-26 20:42:52 +02:00
$row [ 'mtime' ] = $row [ 'mtime' ] -> format ( DEFAULT_TIMESTAMP_FORMAT );
2013-12-04 21:16:07 +01:00
$row [ 'utime' ] = new DateTime ( $row [ 'utime' ], $utcTimezone );
$row [ 'utime' ] -> setTimeZone ( $displayTimezone );
2015-06-26 20:42:52 +02:00
$row [ 'utime' ] = $row [ 'utime' ] -> format ( DEFAULT_TIMESTAMP_FORMAT );
2013-12-04 21:24:27 +01:00
//need to convert last played to localtime if it exists.
if ( isset ( $row [ 'lptime' ])) {
$row [ 'lptime' ] = new DateTime ( $row [ 'lptime' ], $utcTimezone );
$row [ 'lptime' ] -> setTimeZone ( $displayTimezone );
2015-06-26 20:42:52 +02:00
$row [ 'lptime' ] = $row [ 'lptime' ] -> format ( DEFAULT_TIMESTAMP_FORMAT );
2015-07-16 00:53:19 +02:00
}
// we need to initalize the checkbox and image row because we do not retrieve
// any data from the db for these and datatables will complain
$row [ 'checkbox' ] = " " ;
$row [ 'image' ] = " " ;
2015-08-25 23:09:05 +02:00
$row [ 'options' ] = " " ;
2015-07-16 00:53:19 +02:00
$type = substr ( $row [ 'ftype' ], 0 , 2 );
$row [ 'tr_id' ] = " { $type } _ { $row [ 'id' ] } " ;
}
return $results ;
}
2015-07-27 21:37:55 +02:00
/**
2014-03-17 15:19:39 +01:00
* Copy a newly uploaded audio file from its temporary upload directory
* on the local disk ( like / tmp ) over to Airtime ' s " stor " directory ,
* which is where all ingested music / media live .
*
* This is done in PHP here on the web server rather than in airtime_analyzer because
* the airtime_analyzer might be running on a different physical computer than the web server ,
* and it probably won 't have access to the web server' s / tmp folder . The stor / organize directory
* is , however , both accessible to the machines running airtime_analyzer and the web server
* on Airtime Pro .
*
* The file is actually copied to " stor/organize " , which is a staging directory where files go
* before they ' re processed by airtime_analyzer , which then moves them to " stor/imported " in the final
* step .
*
* @ param string $tempFilePath
* @ param string $originalFilename
2015-02-20 22:36:36 +01:00
* @ param bool $copyFile Copy the file instead of moving it .
2014-03-17 15:19:39 +01:00
* @ throws Exception
* @ return Ambigous < unknown , string >
*/
2015-02-20 22:36:36 +01:00
public static function moveFileToStor ( $tempFilePath , $originalFilename , $copyFile = false )
2012-07-16 03:17:13 +02:00
{
2014-03-17 15:19:39 +01:00
$audio_file = $tempFilePath ;
2015-02-20 22:36:36 +01:00
2012-08-22 22:08:46 +02:00
$storDir = Application_Model_MusicDir :: getStorDir ();
$stor = $storDir -> getDirectory ();
// check if "organize" dir exists and if not create one
if ( ! file_exists ( $stor . " /organize " )) {
if ( ! mkdir ( $stor . " /organize " , 0777 )) {
2014-03-17 15:19:39 +01:00
throw new Exception ( " Failed to create organize directory. " );
2012-07-06 04:37:40 +02:00
}
2012-08-22 22:08:46 +02:00
}
2014-03-17 15:19:39 +01:00
2012-08-22 22:08:46 +02:00
if ( chmod ( $audio_file , 0644 ) === false ) {
Logging :: info ( " Warning: couldn't change permissions of $audio_file to 0644 " );
}
2014-03-17 15:19:39 +01:00
2012-09-19 23:45:03 +02:00
// Did all the checks for real, now trying to copy
2012-08-27 23:58:09 +02:00
$audio_stor = Application_Common_OsPath :: join ( $stor , " organize " ,
2014-03-17 15:19:39 +01:00
$originalFilename );
2013-04-30 21:00:31 +02:00
//if the uploaded file is not UTF-8 encoded, let's encode it. Assuming source
//encoding is ISO-8859-1
$audio_stor = mb_detect_encoding ( $audio_stor , " UTF-8 " ) == " UTF-8 " ? $audio_stor : utf8_encode ( $audio_stor );
2015-02-20 22:36:36 +01:00
if ( $copyFile ) {
Logging :: info ( " Copying file $audio_file to $audio_stor " );
if ( @ copy ( $audio_file , $audio_stor ) === false ) {
throw new Exception ( " Failed to copy $audio_file to $audio_stor " );
}
} else {
Logging :: info ( " Moving file $audio_file to $audio_stor " );
2015-03-25 22:34:38 +01:00
//Ensure we have permissions to overwrite the file in stor, in case it already exists.
if ( file_exists ( $audio_stor )) {
chmod ( $audio_stor , 0644 );
}
2015-02-20 22:36:36 +01:00
// Martin K.: changed to rename: Much less load + quicker since this is
// an atomic operation
2015-03-24 19:56:03 +01:00
if ( rename ( $audio_file , $audio_stor ) === false ) {
2015-02-20 22:36:36 +01:00
//something went wrong likely there wasn't enough space in .
//the audio_stor to move the file too warn the user that .
//the file wasn't uploaded and they should check if there .
//is enough disk space .
unlink ( $audio_file ); //remove the file after failed rename
throw new Exception ( " The file was not uploaded, this error can occur if the computer "
. " hard drive does not have enough disk space or the stor "
. " directory does not have correct write permissions. " );
}
2012-08-22 22:08:46 +02:00
}
2014-03-17 15:19:39 +01:00
return $audio_stor ;
2011-03-25 04:07:13 +01:00
}
2014-03-17 15:19:39 +01:00
2012-07-06 04:37:40 +02:00
/*
* Pass the file through Liquidsoap and test if it is readable . Return True if readable , and False otherwise .
*/
2012-07-16 03:17:13 +02:00
public static function liquidsoapFilePlayabilityTest ( $audio_file )
{
2012-07-06 04:37:40 +02:00
$LIQUIDSOAP_ERRORS = array ( 'TagLib: MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.' );
2012-07-11 00:51:32 +02:00
2012-07-06 04:37:40 +02:00
// Ask Liquidsoap if file is playable
2015-01-28 19:19:50 +01:00
/* CC-5990/5991 - Changed to point directly to liquidsoap, removed PATH export */
$command = sprintf ( 'liquidsoap -v -c "output.dummy(audio_to_stereo(single(%s)))" 2>&1' ,
2013-02-07 21:42:06 +01:00
escapeshellarg ( $audio_file ));
2012-07-11 00:51:32 +02:00
2012-07-06 04:37:40 +02:00
exec ( $command , $output , $rv );
2012-07-11 00:51:32 +02:00
2012-07-06 04:37:40 +02:00
$isError = count ( $output ) > 0 && in_array ( $output [ 0 ], $LIQUIDSOAP_ERRORS );
2012-07-16 03:17:13 +02:00
2015-01-28 19:19:50 +01:00
Logging :: info ( " Is error?! : " . $isError );
Logging :: info ( " ls playability response: " . $rv );
2012-07-11 00:51:32 +02:00
return ( $rv == 0 && ! $isError );
2012-07-06 04:37:40 +02:00
}
2012-07-11 00:51:32 +02:00
2011-07-22 12:54:42 +02:00
public static function getFileCount ()
{
2012-09-04 23:21:59 +02:00
$sql = " SELECT count(*) as cnt FROM cc_files WHERE file_exists " ;
2013-05-09 21:53:12 +02:00
return Application_Common_Database :: prepareAndExecute ( $sql , array (),
Application_Common_Database :: COLUMN );
2011-07-22 12:54:42 +02:00
}
2012-01-13 20:17:39 +01:00
/**
2012-01-17 11:18:17 +01:00
*
2012-01-13 20:17:39 +01:00
* Enter description here ...
2012-09-19 17:17:32 +02:00
* @ param $dir_id - if this is not provided , it returns all files with full
* path constructed .
2012-01-13 20:17:39 +01:00
*/
2013-05-10 19:19:56 +02:00
public static function listAllFiles ( $dir_id = null , $all = true )
2012-04-01 21:51:03 +02:00
{
2012-07-16 03:17:13 +02:00
$con = Propel :: getConnection ();
2012-01-17 11:18:17 +01:00
2012-09-19 17:17:32 +02:00
$sql = <<< SQL
SELECT filepath AS fp
FROM CC_FILES AS f
2013-01-03 20:02:06 +01:00
WHERE f . directory = : dir_id
2012-09-19 17:17:32 +02:00
SQL ;
2012-11-05 17:11:05 +01:00
2012-09-04 23:21:59 +02:00
if ( ! $all ) {
$sql .= " AND f.file_exists = 'TRUE' " ;
}
2012-08-28 18:35:19 +02:00
2012-09-04 23:21:59 +02:00
$stmt = $con -> prepare ( $sql );
$stmt -> bindParam ( ':dir_id' , $dir_id );
2013-05-28 20:27:59 +02:00
2012-09-04 23:21:59 +02:00
if ( $stmt -> execute ()) {
$rows = $stmt -> fetchAll ();
2012-04-01 21:51:03 +02:00
} else {
2012-09-04 23:21:59 +02:00
$msg = implode ( ',' , $stmt -> errorInfo ());
throw new Exception ( " Error: $msg " );
2012-01-13 20:17:39 +01:00
}
2013-05-28 20:27:59 +02:00
2011-07-04 20:29:09 +02:00
$results = array ();
2012-04-01 21:51:03 +02:00
foreach ( $rows as $row ) {
2012-09-04 23:21:59 +02:00
$results [] = $row [ " fp " ];
2011-07-04 20:29:09 +02:00
}
return $results ;
}
2012-07-16 03:17:13 +02:00
2012-07-12 23:58:29 +02:00
//TODO: MERGE THIS FUNCTION AND "listAllFiles" -MK
2012-09-04 23:21:59 +02:00
public static function listAllFiles2 ( $dir_id = null , $limit = " ALL " )
2012-07-12 23:58:29 +02:00
{
$con = Propel :: getConnection ();
2012-09-18 21:04:22 +02:00
$sql = <<< SQL
SELECT id ,
filepath AS fp
FROM cc_files
WHERE directory = : dir_id
AND file_exists = 'TRUE'
AND replay_gain IS NULL LIMIT : lim
SQL ;
2012-08-29 16:58:03 +02:00
2012-09-04 23:21:59 +02:00
$stmt = $con -> prepare ( $sql );
$stmt -> bindParam ( ':dir_id' , $dir_id );
$stmt -> bindParam ( ':lim' , $limit );
if ( $stmt -> execute ()) {
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
} else {
$msg = implode ( ',' , $stmt -> errorInfo ());
throw new Exception ( " Error: $msg " );
}
2012-08-29 16:58:03 +02:00
2012-07-12 23:58:29 +02:00
return $rows ;
}
2013-05-28 20:27:59 +02:00
2013-01-18 17:53:26 +01:00
public static function getAllFilesWithoutSilan () {
$con = Propel :: getConnection ();
2013-05-28 20:27:59 +02:00
2013-01-18 17:53:26 +01:00
$sql = <<< SQL
SELECT f . id ,
m . directory || f . filepath AS fp
FROM cc_files as f
JOIN cc_music_dirs as m ON f . directory = m . id
WHERE file_exists = 'TRUE'
AND silan_check IS FALSE Limit 100
SQL ;
$stmt = $con -> prepare ( $sql );
2013-05-28 20:27:59 +02:00
2013-01-18 17:53:26 +01:00
if ( $stmt -> execute ()) {
$rows = $stmt -> fetchAll ( PDO :: FETCH_ASSOC );
} else {
$msg = implode ( ',' , $stmt -> errorInfo ());
throw new Exception ( " Error: $msg " );
}
2013-05-28 20:27:59 +02:00
2013-01-18 17:53:26 +01:00
return $rows ;
}
2012-07-11 00:51:32 +02:00
2012-07-16 03:17:13 +02:00
public function getDirectory ()
{
2012-07-11 00:51:32 +02:00
return $this -> _file -> getDbDirectory ();
}
2012-01-17 11:18:17 +01:00
2012-07-16 03:17:13 +02:00
public function setFileExistsFlag ( $flag )
{
2012-01-13 20:17:39 +01:00
$this -> _file -> setDbFileExists ( $flag )
-> save ();
}
2013-01-08 21:42:35 +01:00
public function setFileHiddenFlag ( $flag )
{
$this -> _file -> setDbHidden ( $flag )
-> save ();
}
2013-05-28 20:27:59 +02:00
2012-11-05 15:49:49 +01:00
// This method seems to be unsued everywhere so I've commented it out
2013-01-03 20:02:06 +01:00
// If it's absence does not have any effect then it will be completely
2012-11-05 15:49:49 +01:00
// removed soon
//public function getFileExistsFlag()
//{
//return $this->_file->getDbFileExists();
//}
2011-09-22 21:31:21 +02:00
2012-10-31 21:01:17 +01:00
public function getFileOwnerId ()
{
return $this -> _file -> getDbOwnerId ();
}
2012-09-18 21:04:22 +02:00
2013-05-28 20:27:59 +02:00
2013-02-01 23:47:07 +01:00
public static function setIsPlaylist ( $p_playlistItems , $p_type , $p_status ) {
foreach ( $p_playlistItems as $item ) {
2013-04-20 02:24:05 +02:00
$file = self :: RecallById ( $item -> getDbFileId ());
2013-02-01 23:47:07 +01:00
$fileId = $file -> _file -> getDbId ();
if ( $p_type == 'playlist' ) {
// we have to check if the file is in another playlist before
// we can update
if ( ! is_null ( $fileId ) && ! in_array ( $fileId , Application_Model_Playlist :: getAllPlaylistFiles ())) {
$file -> _file -> setDbIsPlaylist ( $p_status ) -> save ();
}
} elseif ( $p_type == 'block' ) {
if ( ! is_null ( $fileId ) && ! in_array ( $fileId , Application_Model_Block :: getAllBlockFiles ())) {
$file -> _file -> setDbIsPlaylist ( $p_status ) -> save ();
}
}
}
}
2013-05-28 20:27:59 +02:00
2013-10-02 17:24:48 +02:00
public static function setIsScheduled ( $fileId , $status ) {
2013-05-14 16:58:06 +02:00
2013-04-20 02:24:05 +02:00
$file = self :: RecallById ( $fileId );
2013-02-01 23:47:07 +01:00
$updateIsScheduled = false ;
2013-05-14 16:58:06 +02:00
if ( ! is_null ( $fileId ) && ! in_array ( $fileId ,
2013-05-16 19:42:06 +02:00
Application_Model_Schedule :: getAllFutureScheduledFiles ())) {
2013-10-02 17:24:48 +02:00
$file -> _file -> setDbIsScheduled ( $status ) -> save ();
2013-02-01 23:47:07 +01:00
$updateIsScheduled = true ;
}
return $updateIsScheduled ;
}
2013-02-03 03:07:34 +01:00
2014-10-28 15:25:40 +01:00
/**
*
* Updates the is_scheduled flag to false for tracks that are no longer
* scheduled in the future . We do this by checking the difference between
* all files scheduled in the future and all files with is_scheduled = true .
* The difference of the two result sets is what we need to update .
*/
2013-02-05 22:52:25 +01:00
public static function updatePastFilesIsScheduled ()
{
2014-10-28 15:25:40 +01:00
$futureScheduledFilesSelectCriteria = new Criteria ();
$futureScheduledFilesSelectCriteria -> addSelectColumn ( CcSchedulePeer :: FILE_ID );
$futureScheduledFilesSelectCriteria -> setDistinct ();
2015-06-26 20:42:52 +02:00
$futureScheduledFilesSelectCriteria -> add ( CcSchedulePeer :: ENDS , gmdate ( DEFAULT_TIMESTAMP_FORMAT ), Criteria :: GREATER_THAN );
2014-10-28 15:25:40 +01:00
$stmt = CcSchedulePeer :: doSelectStmt ( $futureScheduledFilesSelectCriteria );
$filesScheduledInFuture = $stmt -> fetchAll ( PDO :: FETCH_COLUMN , 0 );
$filesCurrentlySetWithIsScheduledSelectCriteria = new Criteria ();
$filesCurrentlySetWithIsScheduledSelectCriteria -> addSelectColumn ( CcFilesPeer :: ID );
$filesCurrentlySetWithIsScheduledSelectCriteria -> add ( CcFilesPeer :: IS_SCHEDULED , true );
$stmt = CcFilesPeer :: doSelectStmt ( $filesCurrentlySetWithIsScheduledSelectCriteria );
$filesCurrentlySetWithIsScheduled = $stmt -> fetchAll ( PDO :: FETCH_COLUMN , 0 );
$diff = array_diff ( $filesCurrentlySetWithIsScheduled , $filesScheduledInFuture );
$con = Propel :: getConnection ( CcFilesPeer :: DATABASE_NAME );
$selectCriteria = new Criteria ();
$selectCriteria -> add ( CcFilesPeer :: ID , $diff , Criteria :: IN );
$updateCriteria = new Criteria ();
$updateCriteria -> add ( CcFilesPeer :: IS_SCHEDULED , false );
BasePeer :: doUpdate ( $selectCriteria , $updateCriteria , $con );
2013-02-05 22:52:25 +01:00
}
2010-12-07 23:29:28 +01:00
}
2011-02-22 18:22:31 +01:00
2012-02-05 18:19:22 +01:00
class DeleteScheduledFileException extends Exception {}
2012-02-16 19:46:14 +01:00
class FileDoesNotExistException extends Exception {}
2012-10-31 21:51:29 +01:00
class FileNoPermissionException extends Exception {}